cpl_multiproc.cpp
来自「用于读取TAB、MIF、SHP文件的类」· C++ 代码 · 共 1,036 行 · 第 1/3 页
CPP
1,036 行
/************************************************************************/static void **CPLGetTLSList(){ void **papTLSList; if( !bTLSKeySetup ) { nTLSKey = TlsAlloc(); if( nTLSKey == TLS_OUT_OF_INDEXES ) { CPLError( CE_Fatal, CPLE_AppDefined, "TlsAlloc() failed!" ); } bTLSKeySetup = TRUE; } papTLSList = (void **) TlsGetValue( nTLSKey ); if( papTLSList == NULL ) { papTLSList = (void **) CPLCalloc(sizeof(void*),CTLS_MAX*2); if( TlsSetValue( nTLSKey, papTLSList ) == 0 ) { CPLError( CE_Fatal, CPLE_AppDefined, "TlsSetValue() failed!" ); } } return papTLSList;}/************************************************************************//* CPLCleanupTLS() *//************************************************************************/void CPLCleanupTLS(){ void **papTLSList; if( !bTLSKeySetup ) return; papTLSList = (void **) TlsGetValue( nTLSKey ); if( papTLSList == NULL ) return; TlsSetValue( nTLSKey, NULL ); CPLCleanupTLSList( papTLSList );}#endif /* def CPL_MULTIPROC_WIN32 */#ifdef CPL_MULTIPROC_PTHREAD#include <pthread.h>#include <time.h> /************************************************************************/ /* ==================================================================== */ /* CPL_MULTIPROC_PTHREAD */ /* */ /* PTHREAD Implementation of multiprocessing functions. */ /* ==================================================================== */ /************************************************************************//************************************************************************//* CPLGetThreadingModel() *//************************************************************************/const char *CPLGetThreadingModel(){ return "pthread";}/************************************************************************//* CPLCreateMutex() *//************************************************************************/void *CPLCreateMutex(){ pthread_mutex_t *hMutex; hMutex = (pthread_mutex_t *) malloc(sizeof(pthread_mutex_t));#if defined(PTHREAD_MUTEX_RECURSIVE) { pthread_mutexattr_t attr; pthread_mutexattr_init( &attr ); pthread_mutexattr_settype( &attr, PTHREAD_MUTEX_RECURSIVE ); pthread_mutex_init( hMutex, &attr ); }#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) pthread_mutex_t tmp_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; *hMutex = tmp_mutex;#else#error "Recursive mutexes apparently unsupported, configure --without-threads" #endif // mutexes are implicitly acquired when created. CPLAcquireMutex( hMutex, 0.0 ); return (void *) hMutex;}/************************************************************************//* CPLAcquireMutex() *//************************************************************************/int CPLAcquireMutex( void *hMutexIn, double dfWaitInSeconds ){ int err; /* we need to add timeout support */ err = pthread_mutex_lock( (pthread_mutex_t *) hMutexIn ); if( err != 0 ) { if( err == EDEADLK ) CPLDebug( "CPLAcquireMutex", "Error = %d/EDEADLK", err ); else CPLDebug( "CPLAcquireMutex", "Error = %d", err ); return FALSE; } return TRUE;}/************************************************************************//* CPLReleaseMutex() *//************************************************************************/void CPLReleaseMutex( void *hMutexIn ){ pthread_mutex_unlock( (pthread_mutex_t *) hMutexIn );}/************************************************************************//* CPLDestroyMutex() *//************************************************************************/void CPLDestroyMutex( void *hMutexIn ){ pthread_mutex_destroy( (pthread_mutex_t *) hMutexIn ); CPLFree( hMutexIn );}/************************************************************************//* CPLLockFile() *//************************************************************************/void *CPLLockFile( const char *pszPath, double dfWaitInSeconds ){ CPLError( CE_Failure, CPLE_NotSupported, "PThreads CPLLockFile() not implemented yet." ); return NULL;}/************************************************************************//* CPLUnlockFile() *//************************************************************************/void CPLUnlockFile( void *hLock ){}/************************************************************************//* CPLGetPID() *//************************************************************************/int CPLGetPID(){ return (int) pthread_self();}/************************************************************************//* CPLStdCallThreadJacket() *//************************************************************************/typedef struct { void *pAppData; CPLThreadFunc pfnMain; pthread_t hThread;} CPLStdCallThreadInfo;static void *CPLStdCallThreadJacket( void *pData ){ CPLStdCallThreadInfo *psInfo = (CPLStdCallThreadInfo *) pData; psInfo->pfnMain( psInfo->pAppData ); CPLFree( psInfo ); return NULL;}/************************************************************************//* CPLCreateThread() *//* *//* The WIN32 CreateThread() call requires an entry point that *//* has __stdcall conventions, so we provide a jacket function *//* to supply that. *//************************************************************************/int CPLCreateThread( CPLThreadFunc pfnMain, void *pThreadArg ){ CPLStdCallThreadInfo *psInfo; pthread_attr_t hThreadAttr; psInfo = (CPLStdCallThreadInfo*) CPLCalloc(sizeof(CPLStdCallThreadInfo),1); psInfo->pAppData = pThreadArg; psInfo->pfnMain = pfnMain; pthread_attr_init( &hThreadAttr ); pthread_attr_setdetachstate( &hThreadAttr, PTHREAD_CREATE_DETACHED ); if( pthread_create( &(psInfo->hThread), &hThreadAttr, CPLStdCallThreadJacket, (void *) psInfo ) != 0 ) { CPLFree( psInfo ); return -1; } return 1; /* can we return the actual thread pid? */}/************************************************************************//* CPLSleep() *//************************************************************************/void CPLSleep( double dfWaitInSeconds ){ struct timespec sRequest, sRemain; sRequest.tv_sec = (int) floor(dfWaitInSeconds); sRequest.tv_nsec = (int) ((dfWaitInSeconds - sRequest.tv_sec)*1000000000); nanosleep( &sRequest, &sRemain );}static int bTLSKeySetup = FALSE;static pthread_key_t oTLSKey;/************************************************************************//* CPLCleanupTLS() *//************************************************************************/void CPLCleanupTLS(){ void **papTLSList; if( !bTLSKeySetup ) return; papTLSList = (void **) pthread_getspecific( oTLSKey ); if( papTLSList == NULL ) return; pthread_setspecific( oTLSKey, NULL ); CPLCleanupTLSList( papTLSList );}/************************************************************************//* CPLGetTLSList() *//************************************************************************/static void **CPLGetTLSList(){ void **papTLSList; if( !bTLSKeySetup ) { if( pthread_key_create( &oTLSKey, (void (*)(void*)) CPLCleanupTLSList ) != 0 ) { CPLError( CE_Fatal, CPLE_AppDefined, "pthread_key_create() failed!" ); } bTLSKeySetup = TRUE; } papTLSList = (void **) pthread_getspecific( oTLSKey ); if( papTLSList == NULL ) { papTLSList = (void **) CPLCalloc(sizeof(void*),CTLS_MAX*2); if( pthread_setspecific( oTLSKey, papTLSList ) != 0 ) { CPLError( CE_Fatal, CPLE_AppDefined, "pthread_setspecific() failed!" ); } } return papTLSList;}#endif /* def CPL_MULTIPROC_PTHREAD *//************************************************************************//* CPLGetTLS() *//************************************************************************/void *CPLGetTLS( int nIndex ){ void** papTLSList = CPLGetTLSList(); CPLAssert( nIndex >= 0 && nIndex < CTLS_MAX ); return papTLSList[nIndex];}/************************************************************************//* CPLSetTLS() *//************************************************************************/void CPLSetTLS( int nIndex, void *pData, int bFreeOnExit ){ void **papTLSList = CPLGetTLSList(); CPLAssert( nIndex >= 0 && nIndex < CTLS_MAX ); papTLSList[nIndex] = pData; papTLSList[CTLS_MAX + nIndex] = (void *) bFreeOnExit;}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?