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 + -
显示快捷键?