/* precond: lock desc */ int _freeIFuseDesc (iFuseDesc_t *desc) { int i; if (desc->index < 3) { rodsLog (LOG_ERROR, "freeIFuseDesc: descInx %d out of range", desc->index); return (SYS_FILE_DESC_OUT_OF_RANGE); } for (i = 0; i < MAX_BUF_CACHE; i++) { if (desc->bufCache[i].buf != NULL) { free (desc->bufCache[i].buf); } } free (desc->objPath); free (desc->localPath); UNREF(desc->fileCache, FileCache); addToConcurrentList(IFuseDescFreeList, desc); /* printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"); printf("num of desc slots free = %d\n", listSize(IFuseDescFreeList)); printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");*/ return 0; }
void _waitForConn() { connReqWait_t myConnReqWait; bzero( &myConnReqWait, sizeof( myConnReqWait ) ); initConnReqWaitMutex( &myConnReqWait ); addToConcurrentList( ConnReqWaitQue, &myConnReqWait ); while ( myConnReqWait.state == 0 ) { timeoutWait( &myConnReqWait.mutex, &myConnReqWait.cond, CONN_REQ_SLEEP_TIME ); } deleteConnReqWaitMutex( &myConnReqWait ); }
int _getAndUseIFuseConn( iFuseConn_t **iFuseConn ) { int status; iFuseConn_t *tmpIFuseConn; *iFuseConn = NULL; LOCK( WaitForConnLock ); while ( listSize( ConnectedConn ) >= MAX_NUM_CONN && listSize( FreeConn ) == 0 ) { untimedWait( &connReqWait.mutex, &connReqWait.cond ); } tmpIFuseConn = ( iFuseConn_t * ) removeFirstElementOfConcurrentList( FreeConn ); if ( tmpIFuseConn == NULL ) { if ( listSize( ConnectedConn ) < MAX_NUM_CONN ) { tmpIFuseConn = newIFuseConn( &status ); if ( status < 0 ) { _freeIFuseConn( tmpIFuseConn ); return status; } _useFreeIFuseConn( tmpIFuseConn ); addToConcurrentList( ConnectedConn, tmpIFuseConn ); *iFuseConn = tmpIFuseConn; } else { rodsLog( LOG_ERROR, "failure to acquire fuse connection; maximum fuse connections exceeded." ); return SYS_MAX_CONNECT_COUNT_EXCEEDED; } } else { useIFuseConn( tmpIFuseConn ); *iFuseConn = tmpIFuseConn; } UNLOCK( WaitForConnLock ); if ( ++ConnManagerStarted == HIGH_NUM_CONN ) { /* don't do it the first time */ #ifdef USE_BOOST ConnManagerThr = new boost::thread( connManager ); #else status = pthread_create( &ConnManagerThr, pthread_attr_default, ( void * ( * )( void * ) ) connManager, ( void * ) NULL ); #endif if ( status < 0 ) { ConnManagerStarted--; rodsLog( LOG_ERROR, "pthread_create failure, status = %d", status ); } } return 0; }
int unuseIFuseConn( iFuseConn_t *iFuseConn ) { if ( iFuseConn == NULL || iFuseConn->conn == NULL ) { return USER__NULL_INPUT_ERR; } LOCK_STRUCT( *iFuseConn ); iFuseConn->actTime = time( NULL ); iFuseConn->inuseCnt--; if ( iFuseConn->pendingCnt == 0 ) { addToConcurrentList( FreeConn, iFuseConn ); } UNLOCK_STRUCT( *iFuseConn ); signalConnManager(); return 0; }
int initIFuseDesc () { #ifndef USE_BOOST pthread_mutex_init (&PathCacheLock, NULL); pthread_mutex_init (&ConnManagerLock, NULL); pthread_cond_init (&ConnManagerCond, NULL); IFuseDescFreeList = newConcurrentList(); int i; for(i=0;i<MAX_IFUSE_DESC;i++) { INIT_STRUCT_LOCK(IFuseDesc[i]); IFuseDesc[i].index = i; if(i>=3) { addToConcurrentList(IFuseDescFreeList, &IFuseDesc[i]); } } #endif // JMC - overwrites objects construction? - memset (IFuseDesc, 0, sizeof (iFuseDesc_t) * MAX_IFUSE_DESC); return (0); }
int _getAndUseIFuseConn( iFuseConn_t **iFuseConn ) { int status; iFuseConn_t *tmpIFuseConn; *iFuseConn = NULL; while ( *iFuseConn == NULL ) { /* get a free IFuseConn */ if ( listSize( ConnectedConn ) >= MAX_NUM_CONN && listSize( FreeConn ) == 0 ) { /* have to wait */ _waitForConn(); /* start from begining */ continue; } else { tmpIFuseConn = ( iFuseConn_t * ) removeFirstElementOfConcurrentList( FreeConn ); if ( tmpIFuseConn == NULL ) { if ( listSize( ConnectedConn ) < MAX_NUM_CONN ) { /* may cause num of conn > max num of conn */ /* get here when nothing free. make one */ tmpIFuseConn = newIFuseConn( &status ); if ( status < 0 ) { _freeIFuseConn( tmpIFuseConn ); return status; } _useFreeIFuseConn( tmpIFuseConn ); addToConcurrentList( ConnectedConn, tmpIFuseConn ); *iFuseConn = tmpIFuseConn; break; } _waitForConn(); continue; } else { useIFuseConn( tmpIFuseConn ); *iFuseConn = tmpIFuseConn; break; } } } /* while *iFuseConn */ if ( ++ConnManagerStarted == HIGH_NUM_CONN ) { /* don't do it the first time */ #ifdef USE_BOOST ConnManagerThr = new boost::thread( connManager ); #else status = pthread_create( &ConnManagerThr, pthread_attr_default, ( void * ( * )( void * ) ) connManager, ( void * ) NULL ); #endif if ( status < 0 ) { ConnManagerStarted--; rodsLog( LOG_ERROR, "pthread_create failure, status = %d", status ); } } return 0; }
int preloadFile (const char *path, struct stat *stbuf) { int status; preloadThreadInfo_t *existingThreadInfo = NULL; preloadThreadInfo_t *threadInfo = NULL; preloadThreadData_t *threadData = NULL; char iRODSPath[MAX_NAME_LEN]; off_t cacheSize; off_t freeSize; // convert input path to iRODSPath status = _getiRODSPath(path, iRODSPath); if(status < 0) { rodsLog (LOG_DEBUG, "preloadFile: failed to get iRODS path - %s", path); return status; } LOCK(PreloadLock); // check the given file is preloading existingThreadInfo = (preloadThreadInfo_t *)lookupFromHashTable(PreloadThreadTable, iRODSPath); if(existingThreadInfo != NULL) { rodsLog (LOG_DEBUG, "preloadFile: preloading is already running - %s", iRODSPath); UNLOCK(PreloadLock); return 0; } if(_hasValidCache(iRODSPath, stbuf) != 0) { // invalidate cache - this may fail if cache file does not exists // if old cache exists in local, invalidate it _invalidateCache(iRODSPath); if(stbuf->st_size < PreloadConfig.preloadMinSize) { rodsLog (LOG_DEBUG, "preloadFile: given file is smaller than preloadMinSize, canceling preloading - %s", iRODSPath); UNLOCK(PreloadLock); return (0); } // check whether preload cache exceeds limit if(PreloadConfig.cacheMaxSize > 0) { // cache max size is set if(stbuf->st_size > (off_t)PreloadConfig.cacheMaxSize) { rodsLog (LOG_DEBUG, "preloadFile: given file is bigger than cacheMaxSize, canceling preloading - %s", iRODSPath); UNLOCK(PreloadLock); return (0); } cacheSize = getFileSizeRecursive(PreloadConfig.cachePath); if((cacheSize + stbuf->st_size) > (off_t)PreloadConfig.cacheMaxSize) { // evict? status = _evictOldCache((cacheSize + stbuf->st_size) - (off_t)PreloadConfig.cacheMaxSize); if(status < 0) { rodsLog (LOG_DEBUG, "preloadFile: failed to evict old cache"); UNLOCK(PreloadLock); return status; } } } freeSize = getEmptypSpace(PreloadConfig.cachePath); if(freeSize < stbuf->st_size) { // evict? status = _evictOldCache(stbuf->st_size - freeSize); if(status < 0) { rodsLog (LOG_DEBUG, "preloadFile: failed to evict old cache"); UNLOCK(PreloadLock); return status; } } // does not have valid cache. now, start a new preloading // create a new thread to preload threadInfo = (preloadThreadInfo_t *)malloc(sizeof(preloadThreadInfo_t)); threadInfo->path = strdup(iRODSPath); threadInfo->running = PRELOAD_THREAD_RUNNING; INIT_STRUCT_LOCK((*threadInfo)); addToConcurrentList(PreloadThreadList, threadInfo); insertIntoHashTable(PreloadThreadTable, iRODSPath, threadInfo); // prepare thread argument threadData = (preloadThreadData_t *)malloc(sizeof(preloadThreadData_t)); threadData->path = strdup(iRODSPath); memcpy(&threadData->stbuf, stbuf, sizeof(struct stat)); threadData->threadInfo = threadInfo; rodsLog (LOG_DEBUG, "preloadFile: start preloading - %s", iRODSPath); #ifdef USE_BOOST status = threadInfo->thread = new boost::thread(_preloadThread, (void *)threadData); #else status = pthread_create(&threadInfo->thread, NULL, _preloadThread, (void *)threadData); #endif } else { rodsLog (LOG_DEBUG, "preloadFile: given file is already preloaded - %s", iRODSPath); status = 0; } UNLOCK(PreloadLock); return status; }