/* precond: fileCache locked or single thread use */ iFuseDesc_t *newIFuseDesc (char *objPath, char *localPath, fileCache_t *fileCache, int *status) { iFuseDesc_t *desc; LOCK_STRUCT(*IFuseDescFreeList); /* printf("******************************************************\n"); printf("num of desc slots free = %d\n", _listSize(IFuseDescFreeList)); printf("******************************************************\n"); */ if(_listSize(IFuseDescFreeList)!=0) { ListNode *node = IFuseDescFreeList->list->head; desc = (iFuseDesc_t *) node->value; listRemoveNoRegion(IFuseDescFreeList->list, node); UNLOCK_STRUCT(*IFuseDescFreeList); REF_NO_LOCK(desc->fileCache, fileCache); desc->objPath = strdup (objPath); desc->localPath = strdup (localPath); INIT_STRUCT_LOCK(*desc); *status = 0; return desc; } else { UNLOCK_STRUCT(*IFuseDescFreeList); rodsLog (LOG_ERROR, "allocIFuseDesc: Out of iFuseDesc"); *status = SYS_OUT_OF_FILE_DESC; return NULL; } }
fileCache_t *addFileCache( int iFd, char *objPath, char *localPath, char *cachePath, int mode, rodsLong_t fileSize, cacheState_t state ) { uint cachedTime = time( 0 ); fileCache_t *fileCache, *swapCache; if ( state == NO_FILE_CACHE ) { return newFileCache( iFd, objPath, localPath, cachePath, cachedTime, mode, fileSize, state ); } else { fileCache = newFileCache( iFd, objPath, localPath, cachePath, cachedTime, mode, fileSize, state ); LOCK_STRUCT( *FileCacheList ); if ( _listSize( FileCacheList ) >= NUM_NEWLY_CREATED_SLOT ) { ListNode *node = FileCacheList->list->head; swapCache = ( fileCache_t * ) node->value; listRemoveNoRegion( FileCacheList->list, node ); UNLOCK_STRUCT( *FileCacheList ); ifuseFileCacheSwapOut( swapCache ); LOCK_STRUCT( *FileCacheList ); listAppendNoRegion( FileCacheList->list, fileCache ); } UNLOCK_STRUCT( *FileCacheList ); return fileCache; } }
void connManager() { time_t curTime; iFuseConn_t *tmpIFuseConn; ListNode *node; List *TimeOutList = newListNoRegion(); while ( 1 ) { curTime = time( NULL ); /* exceed high water mark for number of connection ? */ if ( listSize( ConnectedConn ) > HIGH_NUM_CONN ) { LOCK_STRUCT( *ConnectedConn ); int disconnTarget = _listSize( ConnectedConn ) - HIGH_NUM_CONN; node = ConnectedConn->list->head; while ( node != NULL ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { listAppendNoRegion( TimeOutList, tmpIFuseConn ); } node = node->next; } UNLOCK_STRUCT( *ConnectedConn ); node = TimeOutList->head; int disconned = 0; while ( node != NULL && disconned < disconnTarget ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; LOCK_STRUCT( *tmpIFuseConn ); if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { removeFromConcurrentList2( FreeConn, tmpIFuseConn ); removeFromConcurrentList2( ConnectedConn, tmpIFuseConn ); if ( tmpIFuseConn->status == 0 ) { /* no struct is referring to it, we can unlock it and free it */ UNLOCK_STRUCT( *tmpIFuseConn ); /* rodsLog(LOG_ERROR, "[FREE IFUSE CONN] %s:%d %p", __FILE__, __LINE__, tmpIFuseConn); */ _freeIFuseConn( tmpIFuseConn ); } else { /* set to timed out */ _ifuseDisconnect( tmpIFuseConn ); UNLOCK_STRUCT( *tmpIFuseConn ); } disconned ++; } else { UNLOCK_STRUCT( *tmpIFuseConn ); } node = node->next; } clearListNoRegion( TimeOutList ); } notifyWait( &connReqWait.mutex, &connReqWait.cond ); timeoutWait( &ConnManagerLock, &ConnManagerCond, CONN_MANAGER_SLEEP_TIME ); } deleteListNoRegion( TimeOutList ); }
int listSize(concurrentList_t *l) { LOCK_STRUCT(*l); int s = _listSize(l); UNLOCK_STRUCT(*l); return s; }
void connManager() { time_t curTime; iFuseConn_t *tmpIFuseConn; ListNode *node; List *TimeOutList = newListNoRegion(); while ( 1 ) { curTime = time( NULL ); /* exceed high water mark for number of connection ? */ if ( listSize( ConnectedConn ) > HIGH_NUM_CONN ) { LOCK_STRUCT( *ConnectedConn ); int disconnTarget = _listSize( ConnectedConn ) - HIGH_NUM_CONN; node = ConnectedConn->list->head; while ( node != NULL ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { listAppendNoRegion( TimeOutList, tmpIFuseConn ); } node = node->next; } UNLOCK_STRUCT( *ConnectedConn ); node = TimeOutList->head; int disconned = 0; while ( node != NULL && disconned < disconnTarget ) { tmpIFuseConn = ( iFuseConn_t * ) node->value; LOCK_STRUCT( *tmpIFuseConn ); if ( tmpIFuseConn->inuseCnt == 0 && tmpIFuseConn->pendingCnt == 0 && curTime - tmpIFuseConn->actTime > IFUSE_CONN_TIMEOUT ) { removeFromConcurrentList2( FreeConn, tmpIFuseConn ); removeFromConcurrentList2( ConnectedConn, tmpIFuseConn ); if ( tmpIFuseConn->status == 0 ) { /* no struct is referring to it, we can unlock it and free it */ UNLOCK_STRUCT( *tmpIFuseConn ); /* rodsLog(LOG_ERROR, "[FREE IFUSE CONN] %s:%d %p", __FILE__, __LINE__, tmpIFuseConn); */ _freeIFuseConn( tmpIFuseConn ); } else { /* set to timed out */ _ifuseDisconnect( tmpIFuseConn ); UNLOCK_STRUCT( *tmpIFuseConn ); } disconned ++; } else { UNLOCK_STRUCT( *tmpIFuseConn ); } node = node->next; } clearListNoRegion( TimeOutList ); } while ( listSize( ConnectedConn ) <= MAX_NUM_CONN || listSize( FreeConn ) != 0 ) { /* signal one in the wait queue */ connReqWait_t *myConnReqWait = ( connReqWait_t * ) removeFirstElementOfConcurrentList( ConnReqWaitQue ); /* if there is no conn req left, exit loop */ if ( myConnReqWait == NULL ) { break; } myConnReqWait->state = 1; notifyTimeoutWait( &myConnReqWait->mutex, &myConnReqWait->cond ); } #if 0 rodsSleep( CONN_MANAGER_SLEEP_TIME, 0 ); #else timeoutWait( &ConnManagerLock, &ConnManagerCond, CONN_MANAGER_SLEEP_TIME ); #endif } deleteListNoRegion( TimeOutList ); }