GDAL
cpl_multiproc.h
1 /**********************************************************************
2  * $Id$
3  *
4  * Project: CPL - Common Portability Library
5  * Purpose: CPL Multi-Threading, and process handling portability functions.
6  * Author: Frank Warmerdam, warmerdam@pobox.com
7  *
8  **********************************************************************
9  * Copyright (c) 2002, Frank Warmerdam
10  * Copyright (c) 2008-2013, Even Rouault <even dot rouault at spatialys.com>
11  *
12  * Permission is hereby granted, free of charge, to any person obtaining a
13  * copy of this software and associated documentation files (the "Software"),
14  * to deal in the Software without restriction, including without limitation
15  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16  * and/or sell copies of the Software, and to permit persons to whom the
17  * Software is furnished to do so, subject to the following conditions:
18  *
19  * The above copyright notice and this permission notice shall be included
20  * in all copies or substantial portions of the Software.
21  *
22  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28  * DEALINGS IN THE SOFTWARE.
29  ****************************************************************************/
30 
31 #ifndef CPL_MULTIPROC_H_INCLUDED_
32 #define CPL_MULTIPROC_H_INCLUDED_
33 
34 #include "cpl_port.h"
35 
36 /*
37 ** There are three primary implementations of the multi-process support
38 ** controlled by one of CPL_MULTIPROC_WIN32, CPL_MULTIPROC_PTHREAD or
39 ** CPL_MULTIPROC_STUB being defined. If none are defined, the stub
40 ** implementation will be used.
41 */
42 
43 #if defined(WIN32) && !defined(CPL_MULTIPROC_STUB)
44 #define CPL_MULTIPROC_WIN32
45 /* MinGW can have pthread support, so disable it to avoid issues */
46 /* in cpl_multiproc.cpp */
47 #undef CPL_MULTIPROC_PTHREAD
48 #endif
49 
50 #if !defined(CPL_MULTIPROC_WIN32) && !defined(CPL_MULTIPROC_PTHREAD) && \
51  !defined(CPL_MULTIPROC_STUB) && !defined(CPL_MULTIPROC_NONE)
52 #define CPL_MULTIPROC_STUB
53 #endif
54 
56 
57 typedef void (*CPLThreadFunc)(void *);
58 
59 void CPL_DLL *CPLLockFile(const char *pszPath, double dfWaitInSeconds);
60 void CPL_DLL CPLUnlockFile(void *hLock);
61 
62 #ifdef DEBUG
63 typedef struct _CPLMutex CPLMutex;
64 typedef struct _CPLCond CPLCond;
65 typedef struct _CPLJoinableThread CPLJoinableThread;
66 #else
67 #define CPLMutex void
68 #define CPLCond void
69 #define CPLJoinableThread void
70 #endif
71 
72 /* Options for CPLCreateMutexEx() and CPLCreateOrAcquireMutexEx() */
73 #define CPL_MUTEX_RECURSIVE 0
74 #define CPL_MUTEX_ADAPTIVE 1
75 #define CPL_MUTEX_REGULAR 2
76 
77 CPLMutex CPL_DLL *CPLCreateMutex(void); /* returned acquired */
78 CPLMutex CPL_DLL *CPLCreateMutexEx(int nOptions); /* returned acquired */
79 int CPL_DLL CPLCreateOrAcquireMutex(CPLMutex **, double dfWaitInSeconds);
80 int CPL_DLL CPLCreateOrAcquireMutexEx(CPLMutex **, double dfWaitInSeconds,
81  int nOptions);
82 int CPL_DLL CPLAcquireMutex(CPLMutex *hMutex, double dfWaitInSeconds);
83 void CPL_DLL CPLReleaseMutex(CPLMutex *hMutex);
84 void CPL_DLL CPLDestroyMutex(CPLMutex *hMutex);
85 void CPL_DLL CPLCleanupMasterMutex(void);
86 
87 CPLCond CPL_DLL *CPLCreateCond(void);
88 void CPL_DLL CPLCondWait(CPLCond *hCond, CPLMutex *hMutex);
89 typedef enum
90 {
91  COND_TIMED_WAIT_COND,
92  COND_TIMED_WAIT_TIME_OUT,
93  COND_TIMED_WAIT_OTHER
94 } CPLCondTimedWaitReason;
95 CPLCondTimedWaitReason CPL_DLL CPLCondTimedWait(CPLCond *hCond,
96  CPLMutex *hMutex,
97  double dfWaitInSeconds);
98 void CPL_DLL CPLCondSignal(CPLCond *hCond);
99 void CPL_DLL CPLCondBroadcast(CPLCond *hCond);
100 void CPL_DLL CPLDestroyCond(CPLCond *hCond);
101 
104 GIntBig CPL_DLL CPLGetPID(void);
105 int CPL_DLL CPLGetCurrentProcessID(void);
106 int CPL_DLL CPLCreateThread(CPLThreadFunc pfnMain, void *pArg);
107 CPLJoinableThread CPL_DLL *CPLCreateJoinableThread(CPLThreadFunc pfnMain,
108  void *pArg);
109 void CPL_DLL CPLJoinThread(CPLJoinableThread *hJoinableThread);
110 void CPL_DLL CPLSleep(double dfWaitInSeconds);
111 
112 const char CPL_DLL *CPLGetThreadingModel(void);
113 
114 int CPL_DLL CPLGetNumCPUs(void);
115 
116 typedef struct _CPLLock CPLLock;
117 
118 /* Currently LOCK_ADAPTIVE_MUTEX is Linux-only and LOCK_SPIN only available */
119 /* on systems with pthread_spinlock API (so not MacOsX). If a requested type */
120 /* isn't available, it fallbacks to LOCK_RECURSIVE_MUTEX */
121 typedef enum
122 {
123  LOCK_RECURSIVE_MUTEX,
124  LOCK_ADAPTIVE_MUTEX,
125  LOCK_SPIN
126 } CPLLockType;
127 
128 CPLLock CPL_DLL *CPLCreateLock(CPLLockType eType); /* returned NON acquired */
129 int CPL_DLL CPLCreateOrAcquireLock(CPLLock **, CPLLockType eType);
130 int CPL_DLL CPLAcquireLock(CPLLock *);
131 void CPL_DLL CPLReleaseLock(CPLLock *);
132 void CPL_DLL CPLDestroyLock(CPLLock *);
133 void CPL_DLL CPLLockSetDebugPerf(
134  CPLLock *,
135  int bEnableIn); /* only available on x86/x86_64 with GCC for now */
136 
137 CPL_C_END
138 
139 #if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
140 
141 /* Instantiates the mutex if not already done. The parameter x should be a
142  * (void**). */
143 #define CPLMutexHolderD(x) CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__)
144 
145 /* Instantiates the mutex with options if not already done. */
146 /* The parameter x should be a (void**). */
147 #define CPLMutexHolderExD(x, nOptions) \
148  CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__, nOptions)
149 
150 /* This variant assumes the mutex has already been created. If not, it will */
151 /* be a no-op. The parameter x should be a (void*) */
152 #define CPLMutexHolderOptionalLockD(x) \
153  CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__)
154 
156 class CPL_DLL CPLMutexHolder
157 {
158  private:
159  CPLMutex *hMutex = nullptr;
160  // Only used for debugging.
161  const char *pszFile = nullptr;
162  int nLine = 0;
163 
165 
166  public:
168  explicit CPLMutexHolder(CPLMutex **phMutex, double dfWaitInSeconds = 1000.0,
169  const char *pszFile = __FILE__,
170  int nLine = __LINE__,
171  int nOptions = CPL_MUTEX_RECURSIVE);
172 
175  explicit CPLMutexHolder(CPLMutex *hMutex, double dfWaitInSeconds = 1000.0,
176  const char *pszFile = __FILE__,
177  int nLine = __LINE__);
178 
179  ~CPLMutexHolder();
180 };
181 
182 /* Instantiates the lock if not already done. The parameter x should be a
183  * (CPLLock**). */
184 #define CPLLockHolderD(x, eType) \
185  CPLLockHolder oHolder(x, eType, __FILE__, __LINE__);
186 
187 /* This variant assumes the lock has already been created. If not, it will */
188 /* be a no-op. The parameter should be (CPLLock*) */
189 #define CPLLockHolderOptionalLockD(x) \
190  CPLLockHolder oHolder(x, __FILE__, __LINE__);
191 
193 class CPL_DLL CPLLockHolder
194 {
195  private:
196  CPLLock *hLock = nullptr;
197  const char *pszFile = nullptr;
198  int nLine = 0;
199 
201 
202  public:
204  CPLLockHolder(CPLLock **phSpin, CPLLockType eType,
205  const char *pszFile = __FILE__, int nLine = __LINE__);
206 
209  explicit CPLLockHolder(CPLLock *hSpin, const char *pszFile = __FILE__,
210  int nLine = __LINE__);
211 
212  ~CPLLockHolder();
213 };
214 
215 #endif /* def __cplusplus */
216 
217 /* -------------------------------------------------------------------- */
218 /* Thread local storage. */
219 /* -------------------------------------------------------------------- */
220 
221 #define CTLS_RLBUFFERINFO 1 /* cpl_conv.cpp */
222 #define CTLS_WIN32_COND 2 /* cpl_multiproc.cpp */
223 #define CTLS_CSVTABLEPTR 3 /* cpl_csv.cpp */
224 #define CTLS_CSVDEFAULTFILENAME 4 /* cpl_csv.cpp */
225 #define CTLS_ERRORCONTEXT 5 /* cpl_error.cpp */
226 #define CTLS_VSICURL_CACHEDCONNECTION 6 /* cpl_vsil_curl.cpp */
227 #define CTLS_PATHBUF 7 /* cpl_path.cpp */
228 #define CTLS_ABSTRACTARCHIVE_SPLIT 8 /* cpl_vsil_abstract_archive.cpp */
229 #define CTLS_GDALOPEN_ANTIRECURSION 9 /* gdaldataset.cpp */
230 #define CTLS_CPLSPRINTF 10 /* cpl_string.h */
231 #define CTLS_RESPONSIBLEPID 11 /* gdaldataset.cpp */
232 #define CTLS_VERSIONINFO 12 /* gdal_misc.cpp */
233 #define CTLS_VERSIONINFO_LICENCE 13 /* gdal_misc.cpp */
234 #define CTLS_CONFIGOPTIONS 14 /* cpl_conv.cpp */
235 #define CTLS_FINDFILE 15 /* cpl_findfile.cpp */
236 #define CTLS_VSIERRORCONTEXT 16 /* cpl_vsi_error.cpp */
237 /* 17: unused */
238 #define CTLS_PROJCONTEXTHOLDER 18 /* ogr_proj_p.cpp */
239 #define CTLS_GDALDEFAULTOVR_ANTIREC 19 /* gdaldefaultoverviews.cpp */
240 #define CTLS_HTTPFETCHCALLBACK 20 /* cpl_http.cpp */
241 
242 #define CTLS_MAX 32
243 
245 void CPL_DLL *CPLGetTLS(int nIndex);
246 void CPL_DLL *CPLGetTLSEx(int nIndex, int *pbMemoryErrorOccurred);
247 void CPL_DLL CPLSetTLS(int nIndex, void *pData, int bFreeOnExit);
248 
249 /* Warning : the CPLTLSFreeFunc must not in any case directly or indirectly */
250 /* use or fetch any TLS data, or a terminating thread will hang ! */
251 typedef void (*CPLTLSFreeFunc)(void *pData);
252 void CPL_DLL CPLSetTLSWithFreeFunc(int nIndex, void *pData,
253  CPLTLSFreeFunc pfnFree);
254 void CPL_DLL CPLSetTLSWithFreeFuncEx(int nIndex, void *pData,
255  CPLTLSFreeFunc pfnFree,
256  int *pbMemoryErrorOccurred);
257 
258 void CPL_DLL CPLCleanupTLS(void);
259 CPL_C_END
260 
261 #endif /* CPL_MULTIPROC_H_INCLUDED_ */
CPL_C_START
#define CPL_C_START
Macro to start a block of C symbols.
Definition: cpl_port.h:306
CPL_C_END
#define CPL_C_END
Macro to end a block of C symbols.
Definition: cpl_port.h:310
CPLMutexHolder
Object to hold a mutex.
Definition: cpl_multiproc.h:156
CPLLockHolder
Object to hold a lock.
Definition: cpl_multiproc.h:193
GIntBig
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition: cpl_port.h:226
cpl_port.h
CPL_DISALLOW_COPY_ASSIGN
#define CPL_DISALLOW_COPY_ASSIGN(ClassName)
Helper to remove the copy and assignment constructors so that the compiler will not generate the defa...
Definition: cpl_port.h:1042