From 197b2fc0053b4e933fd0a80359837e8768446ad8 Mon Sep 17 00:00:00 2001 From: Dale Phurrough Date: Sun, 8 May 2022 19:08:43 +0200 Subject: [PATCH] xlink init unlocks mutex on errors + allows retry --- src/shared/XLinkDevice.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/src/shared/XLinkDevice.c b/src/shared/XLinkDevice.c index ba41d8b..7c4508a 100644 --- a/src/shared/XLinkDevice.c +++ b/src/shared/XLinkDevice.c @@ -75,20 +75,18 @@ static XLinkError_t parsePlatformError(xLinkPlatformErrorCode_t rc); XLinkError_t XLinkInitialize(XLinkGlobalHandler_t* globalHandler) { + XLINK_RET_IF(globalHandler == NULL); XLINK_RET_ERR_IF(pthread_mutex_lock(&init_mutex), X_LINK_ERROR); if(init_once){ - // BUGBUG missing pthread_mutex_unlock()? + pthread_mutex_unlock(&init_mutex); return X_LINK_SUCCESS; } - // BUGBUG only allow init once? Even if there was an error on previous try? - init_once = 1; #ifdef __DEVICE__ mvLogLevelSet(MVLOG_FATAL); mvLogDefaultLevelSet(MVLOG_FATAL); #endif - XLINK_RET_IF(globalHandler == NULL); ASSERT_XLINK(XLINK_MAX_STREAMS <= MAX_POOLS_ALLOC); glHandler = globalHandler; if (sem_init(&pingSem,0,0)) { @@ -120,7 +118,11 @@ XLinkError_t XLinkInitialize(XLinkGlobalHandler_t* globalHandler) controlFunctionTbl.closeLink = &dispatcherCloseLink; controlFunctionTbl.closeDeviceFd = &dispatcherCloseDeviceFd; - XLINK_RET_IF(DispatcherInitialize(&controlFunctionTbl)); + if (DispatcherInitialize(&controlFunctionTbl)) { + mvLog(MVLOG_ERROR, "Condition failed: DispatcherInitialize(&controlFunctionTbl)"); + pthread_mutex_unlock(&init_mutex); + return X_LINK_ERROR; + } //initialize availableStreams memset(availableXLinks, 0, sizeof(availableXLinks)); @@ -139,24 +141,34 @@ XLinkError_t XLinkInitialize(XLinkGlobalHandler_t* globalHandler) #ifdef __DEVICE__ link = getNextAvailableLink(); - if (link == NULL) - // BUGBUG missing pthread_mutex_unlock()? + if (link == NULL) { + pthread_mutex_unlock(&init_mutex); return X_LINK_COMMUNICATION_NOT_OPEN; + } link->peerState = XLINK_UP; link->deviceHandle.xLinkFD = NULL; link->deviceHandle.protocol = globalHandler->protocol; xLinkDeviceHandle_t temp = {0}; temp.protocol = globalHandler->protocol; - XLINK_RET_IF_FAIL(DispatcherStart(&temp)); //myriad has one + { + int rc; + if (rc = DispatcherStart(&temp)) { //myriad has one + mvLog(MVLOG_ERROR, " DispatcherStart(&temp) method call failed with an error: %d", rc); + pthread_mutex_unlock(&init_mutex); + return rc; + } + } while(((sem_wait(&pingSem) == -1) && errno == EINTR) continue; #endif + init_once = 1; int status = pthread_mutex_unlock(&init_mutex); if(status){ + // rare and unstable scenario; xlink is technically initialized yet mutex unlock failed return X_LINK_ERROR; }