1a34a8711Sopenharmony_ci/* 2a34a8711Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3a34a8711Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4a34a8711Sopenharmony_ci * you may not use this file except in compliance with the License. 5a34a8711Sopenharmony_ci * You may obtain a copy of the License at 6a34a8711Sopenharmony_ci * 7a34a8711Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8a34a8711Sopenharmony_ci * 9a34a8711Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10a34a8711Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11a34a8711Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12a34a8711Sopenharmony_ci * See the License for the specific language governing permissions and 13a34a8711Sopenharmony_ci * limitations under the License. 14a34a8711Sopenharmony_ci */ 15a34a8711Sopenharmony_ci 16a34a8711Sopenharmony_ci#include "rpc_session_handle.h" 17a34a8711Sopenharmony_ci 18a34a8711Sopenharmony_ci#include <stdlib.h> 19a34a8711Sopenharmony_ci#include <errno.h> 20a34a8711Sopenharmony_ci#include <sys/time.h> 21a34a8711Sopenharmony_ci 22a34a8711Sopenharmony_ci#include "rpc_log.h" 23a34a8711Sopenharmony_ci#include "rpc_errno.h" 24a34a8711Sopenharmony_ci 25a34a8711Sopenharmony_cistatic int32_t GetWaitTime(struct timespec *waitTime) 26a34a8711Sopenharmony_ci{ 27a34a8711Sopenharmony_ci#define USECTONSEC 1000 28a34a8711Sopenharmony_ci struct timeval now; 29a34a8711Sopenharmony_ci if (gettimeofday(&now, NULL) != 0) { 30a34a8711Sopenharmony_ci RPC_LOG_ERROR("gettimeofday failed"); 31a34a8711Sopenharmony_ci return ERR_FAILED; 32a34a8711Sopenharmony_ci } 33a34a8711Sopenharmony_ci waitTime->tv_sec = now.tv_sec + CONNECT_WAIT_TIME_SECONDS; 34a34a8711Sopenharmony_ci waitTime->tv_nsec = now.tv_usec * USECTONSEC; 35a34a8711Sopenharmony_ci 36a34a8711Sopenharmony_ci return ERR_NONE; 37a34a8711Sopenharmony_ci} 38a34a8711Sopenharmony_ci 39a34a8711Sopenharmony_cistatic SessionIdList *FindOrNewSessionIdObject(SessionIdList *sessionIdList, int32_t sessionId) 40a34a8711Sopenharmony_ci{ 41a34a8711Sopenharmony_ci RPC_LOG_INFO("FindOrNewSessionIdObject sessionId=%d", sessionId); 42a34a8711Sopenharmony_ci if (sessionIdList == NULL) { 43a34a8711Sopenharmony_ci RPC_LOG_ERROR("FindOrNewSessionIdObject sessionIdList is null"); 44a34a8711Sopenharmony_ci return NULL; 45a34a8711Sopenharmony_ci } 46a34a8711Sopenharmony_ci pthread_mutex_lock(&sessionIdList->mutex); 47a34a8711Sopenharmony_ci SessionIdList *node = NULL; 48a34a8711Sopenharmony_ci UTILS_DL_LIST_FOR_EACH_ENTRY(node, &sessionIdList->idList, SessionIdList, idList) 49a34a8711Sopenharmony_ci { 50a34a8711Sopenharmony_ci if (node->sessionId == sessionId) { 51a34a8711Sopenharmony_ci RPC_LOG_INFO("find sessionId in sessionIdList"); 52a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdList->mutex); 53a34a8711Sopenharmony_ci return node; 54a34a8711Sopenharmony_ci } 55a34a8711Sopenharmony_ci } 56a34a8711Sopenharmony_ci 57a34a8711Sopenharmony_ci node = (SessionIdList *)malloc(sizeof(SessionIdList)); 58a34a8711Sopenharmony_ci if (node == NULL) { 59a34a8711Sopenharmony_ci RPC_LOG_ERROR("FindOrNewSessionIdObject malloc failed"); 60a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdList->mutex); 61a34a8711Sopenharmony_ci return NULL; 62a34a8711Sopenharmony_ci } 63a34a8711Sopenharmony_ci memset_s(node, sizeof(SessionIdList), 0, sizeof(SessionIdList)); 64a34a8711Sopenharmony_ci (void)pthread_mutex_init(&node->mutex, NULL); 65a34a8711Sopenharmony_ci (void)pthread_cond_init(&node->condition, NULL); 66a34a8711Sopenharmony_ci node->sessionId = sessionId; 67a34a8711Sopenharmony_ci node->isReady = false; 68a34a8711Sopenharmony_ci 69a34a8711Sopenharmony_ci UtilsListAdd(&sessionIdList->idList, &node->idList); 70a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdList->mutex); 71a34a8711Sopenharmony_ci return node; 72a34a8711Sopenharmony_ci} 73a34a8711Sopenharmony_ci 74a34a8711Sopenharmony_ciint32_t WaitForSessionIdReady(SessionIdList *sessionIdList, int32_t sessionId) 75a34a8711Sopenharmony_ci{ 76a34a8711Sopenharmony_ci if (sessionIdList == NULL) { 77a34a8711Sopenharmony_ci RPC_LOG_ERROR("WaitForSessionIdReady sessionIdList is null"); 78a34a8711Sopenharmony_ci return ERR_FAILED; 79a34a8711Sopenharmony_ci } 80a34a8711Sopenharmony_ci if (sessionId <= 0) { 81a34a8711Sopenharmony_ci RPC_LOG_ERROR("invalid sessionid %d", sessionId); 82a34a8711Sopenharmony_ci return ERR_FAILED; 83a34a8711Sopenharmony_ci } 84a34a8711Sopenharmony_ci SessionIdList *sessionIdObject = FindOrNewSessionIdObject(sessionIdList, sessionId); 85a34a8711Sopenharmony_ci if (sessionIdObject == NULL) { 86a34a8711Sopenharmony_ci RPC_LOG_ERROR("FindOrNewSessionIdObject return null"); 87a34a8711Sopenharmony_ci return ERR_FAILED; 88a34a8711Sopenharmony_ci } 89a34a8711Sopenharmony_ci pthread_mutex_lock(&sessionIdObject->mutex); 90a34a8711Sopenharmony_ci if (sessionIdObject->isReady) { 91a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdObject->mutex); 92a34a8711Sopenharmony_ci return ERR_NONE; 93a34a8711Sopenharmony_ci } 94a34a8711Sopenharmony_ci 95a34a8711Sopenharmony_ci struct timespec waitTime; 96a34a8711Sopenharmony_ci if (GetWaitTime(&waitTime) != ERR_NONE) { 97a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdObject->mutex); 98a34a8711Sopenharmony_ci return ERR_FAILED; 99a34a8711Sopenharmony_ci } 100a34a8711Sopenharmony_ci 101a34a8711Sopenharmony_ci if (pthread_cond_timedwait(&sessionIdObject->condition, 102a34a8711Sopenharmony_ci &sessionIdObject->mutex, &waitTime) == ETIMEDOUT) { 103a34a8711Sopenharmony_ci RPC_LOG_ERROR("WaitForSessionIdReady timeout"); 104a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdObject->mutex); 105a34a8711Sopenharmony_ci return ERR_FAILED; 106a34a8711Sopenharmony_ci } 107a34a8711Sopenharmony_ci 108a34a8711Sopenharmony_ci RPC_LOG_INFO("WaitForSessionIdReady wakeup!"); 109a34a8711Sopenharmony_ci int32_t ret = sessionIdObject->isReady ? ERR_NONE : ERR_FAILED; 110a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdObject->mutex); 111a34a8711Sopenharmony_ci return ret; 112a34a8711Sopenharmony_ci} 113a34a8711Sopenharmony_ci 114a34a8711Sopenharmony_ciint32_t HandleNewConnection(SessionIdList *sessionIdList, int32_t sessionId) 115a34a8711Sopenharmony_ci{ 116a34a8711Sopenharmony_ci if (sessionIdList == NULL) { 117a34a8711Sopenharmony_ci RPC_LOG_ERROR("HandleNewConnection sessionIdList is null"); 118a34a8711Sopenharmony_ci return ERR_FAILED; 119a34a8711Sopenharmony_ci } 120a34a8711Sopenharmony_ci if (sessionId <= 0) { 121a34a8711Sopenharmony_ci return ERR_FAILED; 122a34a8711Sopenharmony_ci } 123a34a8711Sopenharmony_ci 124a34a8711Sopenharmony_ci SessionIdList *sessionIdObject = FindOrNewSessionIdObject(sessionIdList, sessionId); 125a34a8711Sopenharmony_ci if (sessionIdObject == NULL) { 126a34a8711Sopenharmony_ci RPC_LOG_ERROR("HandleNewConnection get sessionIdObject null"); 127a34a8711Sopenharmony_ci return ERR_FAILED; 128a34a8711Sopenharmony_ci } 129a34a8711Sopenharmony_ci 130a34a8711Sopenharmony_ci pthread_mutex_lock(&sessionIdObject->mutex); 131a34a8711Sopenharmony_ci if (!sessionIdObject->isReady) { 132a34a8711Sopenharmony_ci sessionIdObject->isReady = true; 133a34a8711Sopenharmony_ci pthread_cond_broadcast(&sessionIdObject->condition); 134a34a8711Sopenharmony_ci RPC_LOG_INFO("HandleNewConnection broadcast thread, sessionId=%d", sessionId); 135a34a8711Sopenharmony_ci } 136a34a8711Sopenharmony_ci pthread_mutex_unlock(&sessionIdObject->mutex); 137a34a8711Sopenharmony_ci return ERR_NONE; 138a34a8711Sopenharmony_ci}