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
57typedef void (*CPLThreadFunc)(void *);
58
59void CPL_DLL *CPLLockFile(const char *pszPath, double dfWaitInSeconds);
60void CPL_DLL CPLUnlockFile(void *hLock);
61
62typedef struct _CPLMutex CPLMutex;
63typedef struct _CPLCond CPLCond;
64typedef struct _CPLJoinableThread CPLJoinableThread;
65
66/* Options for CPLCreateMutexEx() and CPLCreateOrAcquireMutexEx() */
67#define CPL_MUTEX_RECURSIVE 0
68#define CPL_MUTEX_ADAPTIVE 1
69#define CPL_MUTEX_REGULAR 2
70
71CPLMutex CPL_DLL *CPLCreateMutex(void); /* returned acquired */
72CPLMutex CPL_DLL *CPLCreateMutexEx(int nOptions); /* returned acquired */
73int CPL_DLL CPLCreateOrAcquireMutex(CPLMutex **, double dfWaitInSeconds);
74int CPL_DLL CPLCreateOrAcquireMutexEx(CPLMutex **, double dfWaitInSeconds,
75 int nOptions);
76int CPL_DLL CPLAcquireMutex(CPLMutex *hMutex, double dfWaitInSeconds);
77void CPL_DLL CPLReleaseMutex(CPLMutex *hMutex);
78void CPL_DLL CPLDestroyMutex(CPLMutex *hMutex);
79void CPL_DLL CPLCleanupMasterMutex(void);
80
81CPLCond CPL_DLL *CPLCreateCond(void);
82void CPL_DLL CPLCondWait(CPLCond *hCond, CPLMutex *hMutex);
83
84typedef enum
85{
86 COND_TIMED_WAIT_COND,
87 COND_TIMED_WAIT_TIME_OUT,
88 COND_TIMED_WAIT_OTHER
89} CPLCondTimedWaitReason;
90
91CPLCondTimedWaitReason CPL_DLL CPLCondTimedWait(CPLCond *hCond,
92 CPLMutex *hMutex,
93 double dfWaitInSeconds);
94void CPL_DLL CPLCondSignal(CPLCond *hCond);
95void CPL_DLL CPLCondBroadcast(CPLCond *hCond);
96void CPL_DLL CPLDestroyCond(CPLCond *hCond);
97
100GIntBig CPL_DLL CPLGetPID(void);
101int CPL_DLL CPLGetCurrentProcessID(void);
102int CPL_DLL CPLCreateThread(CPLThreadFunc pfnMain, void *pArg);
103CPLJoinableThread CPL_DLL *CPLCreateJoinableThread(CPLThreadFunc pfnMain,
104 void *pArg);
105void CPL_DLL CPLJoinThread(CPLJoinableThread *hJoinableThread);
106void CPL_DLL CPLSleep(double dfWaitInSeconds);
107
108const char CPL_DLL *CPLGetThreadingModel(void);
109
110int CPL_DLL CPLGetNumCPUs(void);
111
112typedef struct _CPLLock CPLLock;
113
114/* Currently LOCK_ADAPTIVE_MUTEX is Linux-only and LOCK_SPIN only available */
115/* on systems with pthread_spinlock API (so not MacOsX). If a requested type */
116/* isn't available, it fallbacks to LOCK_RECURSIVE_MUTEX */
117typedef enum
118{
119 LOCK_RECURSIVE_MUTEX,
120 LOCK_ADAPTIVE_MUTEX,
121 LOCK_SPIN
122} CPLLockType;
123
124CPLLock CPL_DLL *CPLCreateLock(CPLLockType eType); /* returned NON acquired */
125int CPL_DLL CPLCreateOrAcquireLock(CPLLock **, CPLLockType eType);
126int CPL_DLL CPLAcquireLock(CPLLock *);
127void CPL_DLL CPLReleaseLock(CPLLock *);
128void CPL_DLL CPLDestroyLock(CPLLock *);
129void CPL_DLL CPLLockSetDebugPerf(
130 CPLLock *,
131 int bEnableIn); /* only available on x86/x86_64 with GCC for now */
132
134
135#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
136
137/* Instantiates the mutex if not already done. The parameter x should be a
138 * (void**). */
139#define CPLMutexHolderD(x) CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__)
140
141/* Instantiates the mutex with options if not already done. */
142/* The parameter x should be a (void**). */
143#define CPLMutexHolderExD(x, nOptions) \
144 CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__, nOptions)
145
146/* This variant assumes the mutex has already been created. If not, it will */
147/* be a no-op. The parameter x should be a (void*) */
148#define CPLMutexHolderOptionalLockD(x) \
149 CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__)
150
152class CPL_DLL CPLMutexHolder
153{
154 private:
155 CPLMutex *hMutex = nullptr;
156 // Only used for debugging.
157 const char *pszFile = nullptr;
158 int nLine = 0;
159
161
162 public:
164 explicit CPLMutexHolder(CPLMutex **phMutex, double dfWaitInSeconds = 1000.0,
165 const char *pszFile = __FILE__,
166 int nLine = __LINE__,
167 int nOptions = CPL_MUTEX_RECURSIVE);
168
171 explicit CPLMutexHolder(CPLMutex *hMutex, double dfWaitInSeconds = 1000.0,
172 const char *pszFile = __FILE__,
173 int nLine = __LINE__);
174
176};
177
178/* Instantiates the lock if not already done. The parameter x should be a
179 * (CPLLock**). */
180#define CPLLockHolderD(x, eType) \
181 CPLLockHolder oHolder(x, eType, __FILE__, __LINE__);
182
183/* This variant assumes the lock has already been created. If not, it will */
184/* be a no-op. The parameter should be (CPLLock*) */
185#define CPLLockHolderOptionalLockD(x) \
186 CPLLockHolder oHolder(x, __FILE__, __LINE__);
187
189class CPL_DLL CPLLockHolder
190{
191 private:
192 CPLLock *hLock = nullptr;
193 const char *pszFile = nullptr;
194 int nLine = 0;
195
197
198 public:
200 CPLLockHolder(CPLLock **phSpin, CPLLockType eType,
201 const char *pszFile = __FILE__, int nLine = __LINE__);
202
205 explicit CPLLockHolder(CPLLock *hSpin, const char *pszFile = __FILE__,
206 int nLine = __LINE__);
207
209};
210
211#endif /* def __cplusplus */
212
213/* -------------------------------------------------------------------- */
214/* Thread local storage. */
215/* -------------------------------------------------------------------- */
216
217#define CTLS_RLBUFFERINFO 1 /* cpl_conv.cpp */
218#define CTLS_WIN32_COND 2 /* cpl_multiproc.cpp */
219#define CTLS_CSVTABLEPTR 3 /* cpl_csv.cpp */
220#define CTLS_CSVDEFAULTFILENAME 4 /* cpl_csv.cpp */
221#define CTLS_ERRORCONTEXT 5 /* cpl_error.cpp */
222#define CTLS_VSICURL_CACHEDCONNECTION 6 /* cpl_vsil_curl.cpp */
223#define CTLS_PATHBUF 7 /* cpl_path.cpp */
224#define CTLS_ABSTRACTARCHIVE_SPLIT 8 /* cpl_vsil_abstract_archive.cpp */
225#define CTLS_GDALOPEN_ANTIRECURSION 9 /* gdaldataset.cpp */
226#define CTLS_CPLSPRINTF 10 /* cpl_string.h */
227#define CTLS_RESPONSIBLEPID 11 /* gdaldataset.cpp */
228#define CTLS_VERSIONINFO 12 /* gdal_misc.cpp */
229#define CTLS_VERSIONINFO_LICENCE 13 /* gdal_misc.cpp */
230#define CTLS_CONFIGOPTIONS 14 /* cpl_conv.cpp */
231#define CTLS_FINDFILE 15 /* cpl_findfile.cpp */
232#define CTLS_VSIERRORCONTEXT 16 /* cpl_vsi_error.cpp */
233/* 17: unused */
234#define CTLS_PROJCONTEXTHOLDER 18 /* ogr_proj_p.cpp */
235#define CTLS_GDALDEFAULTOVR_ANTIREC 19 /* gdaldefaultoverviews.cpp */
236#define CTLS_HTTPFETCHCALLBACK 20 /* cpl_http.cpp */
237
238#define CTLS_MAX 32
239
241void CPL_DLL *CPLGetTLS(int nIndex);
242void CPL_DLL *CPLGetTLSEx(int nIndex, int *pbMemoryErrorOccurred);
243void CPL_DLL CPLSetTLS(int nIndex, void *pData, int bFreeOnExit);
244
245/* Warning : the CPLTLSFreeFunc must not in any case directly or indirectly */
246/* use or fetch any TLS data, or a terminating thread will hang ! */
247typedef void (*CPLTLSFreeFunc)(void *pData);
248void CPL_DLL CPLSetTLSWithFreeFunc(int nIndex, void *pData,
249 CPLTLSFreeFunc pfnFree);
250void CPL_DLL CPLSetTLSWithFreeFuncEx(int nIndex, void *pData,
251 CPLTLSFreeFunc pfnFree,
252 int *pbMemoryErrorOccurred);
253
254void CPL_DLL CPLCleanupTLS(void);
256
257#endif /* CPL_MULTIPROC_H_INCLUDED_ */
Object to hold a lock.
Definition cpl_multiproc.h:190
Object to hold a mutex.
Definition cpl_multiproc.h:153
Core portability definitions for CPL.
#define CPL_C_END
Macro to end a block of C symbols.
Definition cpl_port.h:299
#define CPL_C_START
Macro to start a block of C symbols.
Definition cpl_port.h:295
#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
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition cpl_port.h:215