GDAL
|
00001 /********************************************************************** 00002 * $Id: cpl_multiproc.h 28470 2015-02-12 21:01:32Z rouault $ 00003 * 00004 * Project: CPL - Common Portability Library 00005 * Purpose: CPL Multi-Threading, and process handling portability functions. 00006 * Author: Frank Warmerdam, warmerdam@pobox.com 00007 * 00008 ********************************************************************** 00009 * Copyright (c) 2002, Frank Warmerdam 00010 * Copyright (c) 2008-2013, Even Rouault <even dot rouault at mines-paris dot org> 00011 * 00012 * Permission is hereby granted, free of charge, to any person obtaining a 00013 * copy of this software and associated documentation files (the "Software"), 00014 * to deal in the Software without restriction, including without limitation 00015 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 00016 * and/or sell copies of the Software, and to permit persons to whom the 00017 * Software is furnished to do so, subject to the following conditions: 00018 * 00019 * The above copyright notice and this permission notice shall be included 00020 * in all copies or substantial portions of the Software. 00021 * 00022 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00025 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00027 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00028 * DEALINGS IN THE SOFTWARE. 00029 ****************************************************************************/ 00030 00031 #ifndef _CPL_MULTIPROC_H_INCLUDED_ 00032 #define _CPL_MULTIPROC_H_INCLUDED_ 00033 00034 #include "cpl_port.h" 00035 00036 /* 00037 ** There are three primary implementations of the multi-process support 00038 ** controlled by one of CPL_MULTIPROC_WIN32, CPL_MULTIPROC_PTHREAD or 00039 ** CPL_MULTIPROC_STUB being defined. If none are defined, the stub 00040 ** implementation will be used. 00041 */ 00042 00043 #if defined(WIN32) && !defined(CPL_MULTIPROC_STUB) 00044 # define CPL_MULTIPROC_WIN32 00045 /* MinGW can have pthread support, so disable it to avoid issues */ 00046 /* in cpl_multiproc.cpp */ 00047 # undef CPL_MULTIPROC_PTHREAD 00048 #endif 00049 00050 #if !defined(CPL_MULTIPROC_WIN32) && !defined(CPL_MULTIPROC_PTHREAD) \ 00051 && !defined(CPL_MULTIPROC_STUB) && !defined(CPL_MULTIPROC_NONE) 00052 # define CPL_MULTIPROC_STUB 00053 #endif 00054 00055 CPL_C_START 00056 00057 typedef void (*CPLThreadFunc)(void *); 00058 00059 void CPL_DLL *CPLLockFile( const char *pszPath, double dfWaitInSeconds ); 00060 void CPL_DLL CPLUnlockFile( void *hLock ); 00061 00062 #ifdef DEBUG 00063 typedef struct _CPLMutex CPLMutex; 00064 typedef struct _CPLCond CPLCond; 00065 typedef struct _CPLJoinableThread CPLJoinableThread; 00066 #else 00067 #define CPLMutex void 00068 #define CPLCond void 00069 #define CPLJoinableThread void 00070 #endif 00071 00072 /* Options for CPLCreateMutexEx() and CPLCreateOrAcquireMutexEx() */ 00073 #define CPL_MUTEX_RECURSIVE 0 00074 #define CPL_MUTEX_ADAPTIVE 1 00075 00076 CPLMutex CPL_DLL *CPLCreateMutex( void ); /* returned acquired */ 00077 CPLMutex CPL_DLL *CPLCreateMutexEx( int nOptions ); /* returned acquired */ 00078 int CPL_DLL CPLCreateOrAcquireMutex( CPLMutex **, double dfWaitInSeconds ); 00079 int CPL_DLL CPLCreateOrAcquireMutexEx( CPLMutex **, double dfWaitInSeconds, int nOptions ); 00080 int CPL_DLL CPLAcquireMutex( CPLMutex *hMutex, double dfWaitInSeconds ); 00081 void CPL_DLL CPLReleaseMutex( CPLMutex *hMutex ); 00082 void CPL_DLL CPLDestroyMutex( CPLMutex *hMutex ); 00083 void CPL_DLL CPLCleanupMasterMutex( void ); 00084 00085 CPLCond CPL_DLL *CPLCreateCond( void ); 00086 void CPL_DLL CPLCondWait( CPLCond *hCond, CPLMutex* hMutex ); 00087 void CPL_DLL CPLCondSignal( CPLCond *hCond ); 00088 void CPL_DLL CPLCondBroadcast( CPLCond *hCond ); 00089 void CPL_DLL CPLDestroyCond( CPLCond *hCond ); 00090 00091 GIntBig CPL_DLL CPLGetPID( void ); 00092 int CPL_DLL CPLCreateThread( CPLThreadFunc pfnMain, void *pArg ); 00093 CPLJoinableThread CPL_DLL* CPLCreateJoinableThread( CPLThreadFunc pfnMain, void *pArg ); 00094 void CPL_DLL CPLJoinThread(CPLJoinableThread* hJoinableThread); 00095 void CPL_DLL CPLSleep( double dfWaitInSeconds ); 00096 00097 const char CPL_DLL *CPLGetThreadingModel( void ); 00098 00099 int CPL_DLL CPLGetNumCPUs( void ); 00100 00101 00102 typedef struct _CPLLock CPLLock; 00103 00104 /* Currently LOCK_ADAPTIVE_MUTEX is Linux-only and LOCK_SPIN only available */ 00105 /* on systems with pthread_spinlock API (so not MacOsX). If a requested type */ 00106 /* isn't available, it fallbacks to LOCK_RECURSIVE_MUTEX */ 00107 typedef enum 00108 { 00109 LOCK_RECURSIVE_MUTEX, 00110 LOCK_ADAPTIVE_MUTEX, 00111 LOCK_SPIN 00112 } CPLLockType; 00113 00114 CPLLock CPL_DLL *CPLCreateLock( CPLLockType eType ); /* returned NON acquired */ 00115 int CPL_DLL CPLCreateOrAcquireLock( CPLLock**, CPLLockType eType ); 00116 int CPL_DLL CPLAcquireLock( CPLLock* ); 00117 void CPL_DLL CPLReleaseLock( CPLLock* ); 00118 void CPL_DLL CPLDestroyLock( CPLLock* ); 00119 void CPL_DLL CPLLockSetDebugPerf( CPLLock*, int bEnableIn ); /* only available on x86/x86_64 with GCC for now */ 00120 00121 00122 CPL_C_END 00123 00124 #ifdef __cplusplus 00125 00126 /* Instanciates the mutex if not already done. The parameter x should be a (void**) */ 00127 #define CPLMutexHolderD(x) CPLMutexHolder oHolder(x,1000.0,__FILE__,__LINE__); 00128 00129 /* Instanciates the mutex with options if not already done. */ 00130 /* The parameter x should be a (void**) */ 00131 #define CPLMutexHolderExD(x, nOptions) CPLMutexHolder oHolder(x,1000.0,__FILE__,__LINE__,nOptions); 00132 00133 /* This variant assumes the the mutex has already been created. If not, it will */ 00134 /* be a no-op. The parameter x should be a (void*) */ 00135 #define CPLMutexHolderOptionalLockD(x) CPLMutexHolder oHolder(x,1000.0,__FILE__,__LINE__); 00136 00137 class CPL_DLL CPLMutexHolder 00138 { 00139 private: 00140 CPLMutex *hMutex; 00141 const char *pszFile; 00142 int nLine; 00143 00144 public: 00145 00146 /* Instanciates the mutex if not already done */ 00147 CPLMutexHolder( CPLMutex **phMutex, double dfWaitInSeconds = 1000.0, 00148 const char *pszFile = __FILE__, 00149 int nLine = __LINE__, 00150 int nOptions = CPL_MUTEX_RECURSIVE); 00151 00152 /* This variant assumes the the mutex has already been created. If not, it will */ 00153 /* be a no-op */ 00154 CPLMutexHolder( CPLMutex* hMutex, double dfWaitInSeconds = 1000.0, 00155 const char *pszFile = __FILE__, 00156 int nLine = __LINE__ ); 00157 00158 ~CPLMutexHolder(); 00159 }; 00160 00161 /* Instanciates the lock if not already done. The parameter x should be a (CPLLock**) */ 00162 #define CPLLockHolderD(x, eType) CPLLockHolder oHolder(x,eType,__FILE__,__LINE__); 00163 00164 /* This variant assumes the the lock has already been created. If not, it will */ 00165 /* be a no-op. The parameter should be (CPLLock*) */ 00166 #define CPLLockHolderOptionalLockD(x) CPLLockHolder oHolder(x,__FILE__,__LINE__); 00167 00168 class CPL_DLL CPLLockHolder 00169 { 00170 private: 00171 CPLLock *hLock; 00172 const char *pszFile; 00173 int nLine; 00174 00175 public: 00176 00177 /* Instanciates the lock if not already done */ 00178 CPLLockHolder( CPLLock **phSpin, CPLLockType eType, 00179 const char *pszFile = __FILE__, 00180 int nLine = __LINE__); 00181 00182 /* This variant assumes the the lock has already been created. If not, it will */ 00183 /* be a no-op */ 00184 CPLLockHolder( CPLLock* hSpin, 00185 const char *pszFile = __FILE__, 00186 int nLine = __LINE__ ); 00187 00188 ~CPLLockHolder(); 00189 }; 00190 00191 00192 #endif /* def __cplusplus */ 00193 00194 /* -------------------------------------------------------------------- */ 00195 /* Thread local storage. */ 00196 /* -------------------------------------------------------------------- */ 00197 00198 #define CTLS_RLBUFFERINFO 1 /* cpl_conv.cpp */ 00199 #define CTLS_WIN32_COND 2 /* cpl_multiproc.cpp */ 00200 #define CTLS_CSVTABLEPTR 3 /* cpl_csv.cpp */ 00201 #define CTLS_CSVDEFAULTFILENAME 4 /* cpl_csv.cpp */ 00202 #define CTLS_ERRORCONTEXT 5 /* cpl_error.cpp */ 00203 #define CTLS_GDALDATASET_REC_PROTECT_MAP 6 /* gdaldataset.cpp */ 00204 #define CTLS_PATHBUF 7 /* cpl_path.cpp */ 00205 #define CTLS_UNUSED3 8 00206 #define CTLS_UNUSED4 9 00207 #define CTLS_CPLSPRINTF 10 /* cpl_string.h */ 00208 #define CTLS_RESPONSIBLEPID 11 /* gdaldataset.cpp */ 00209 #define CTLS_VERSIONINFO 12 /* gdal_misc.cpp */ 00210 #define CTLS_VERSIONINFO_LICENCE 13 /* gdal_misc.cpp */ 00211 #define CTLS_CONFIGOPTIONS 14 /* cpl_conv.cpp */ 00212 #define CTLS_FINDFILE 15 /* cpl_findfile.cpp */ 00213 00214 #define CTLS_MAX 32 00215 00216 CPL_C_START 00217 void CPL_DLL * CPLGetTLS( int nIndex ); 00218 void CPL_DLL CPLSetTLS( int nIndex, void *pData, int bFreeOnExit ); 00219 00220 /* Warning : the CPLTLSFreeFunc must not in any case directly or indirectly */ 00221 /* use or fetch any TLS data, or a terminating thread will hang ! */ 00222 typedef void (*CPLTLSFreeFunc)( void* pData ); 00223 void CPL_DLL CPLSetTLSWithFreeFunc( int nIndex, void *pData, CPLTLSFreeFunc pfnFree ); 00224 00225 void CPL_DLL CPLCleanupTLS( void ); 00226 CPL_C_END 00227 00228 #endif /* _CPL_MULTIPROC_H_INCLUDED_ */