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 * SPDX-License-Identifier: MIT
13 ****************************************************************************/
14
15#ifndef CPL_MULTIPROC_H_INCLUDED_
16#define CPL_MULTIPROC_H_INCLUDED_
17
18#include "cpl_port.h"
19
20/*
21** There are three primary implementations of the multi-process support
22** controlled by one of CPL_MULTIPROC_WIN32, CPL_MULTIPROC_PTHREAD or
23** CPL_MULTIPROC_STUB being defined. If none are defined, the stub
24** implementation will be used.
25*/
26
27#if defined(_WIN32) && !defined(CPL_MULTIPROC_STUB)
28#define CPL_MULTIPROC_WIN32
29/* MinGW can have pthread support, so disable it to avoid issues */
30/* in cpl_multiproc.cpp */
31#undef CPL_MULTIPROC_PTHREAD
32#endif
33
34#if !defined(CPL_MULTIPROC_WIN32) && !defined(CPL_MULTIPROC_PTHREAD) && \
35 !defined(CPL_MULTIPROC_STUB) && !defined(CPL_MULTIPROC_NONE)
36#define CPL_MULTIPROC_STUB
37#endif
38
40
41typedef void (*CPLThreadFunc)(void *);
42
43void CPL_DLL *CPLLockFile(const char *pszPath, double dfWaitInSeconds);
44void CPL_DLL CPLUnlockFile(void *hLock);
45
46typedef struct _CPLMutex CPLMutex;
47typedef struct _CPLCond CPLCond;
48typedef struct _CPLJoinableThread CPLJoinableThread;
49
50/* Options for CPLCreateMutexEx() and CPLCreateOrAcquireMutexEx() */
51#define CPL_MUTEX_RECURSIVE 0
52#define CPL_MUTEX_ADAPTIVE 1
53#define CPL_MUTEX_REGULAR 2
54
55CPLMutex CPL_DLL *CPLCreateMutex(void); /* returned acquired */
56CPLMutex CPL_DLL *CPLCreateMutexEx(int nOptions); /* returned acquired */
57int CPL_DLL CPLCreateOrAcquireMutex(CPLMutex **, double dfWaitInSeconds);
58int CPL_DLL CPLCreateOrAcquireMutexEx(CPLMutex **, double dfWaitInSeconds,
59 int nOptions);
60int CPL_DLL CPLAcquireMutex(CPLMutex *hMutex, double dfWaitInSeconds);
61void CPL_DLL CPLReleaseMutex(CPLMutex *hMutex);
62void CPL_DLL CPLDestroyMutex(CPLMutex *hMutex);
63void CPL_DLL CPLCleanupMasterMutex(void);
64
65CPLCond CPL_DLL *CPLCreateCond(void);
66void CPL_DLL CPLCondWait(CPLCond *hCond, CPLMutex *hMutex);
67
68typedef enum
69{
70 COND_TIMED_WAIT_COND,
71 COND_TIMED_WAIT_TIME_OUT,
72 COND_TIMED_WAIT_OTHER
73} CPLCondTimedWaitReason;
74
75CPLCondTimedWaitReason CPL_DLL CPLCondTimedWait(CPLCond *hCond,
76 CPLMutex *hMutex,
77 double dfWaitInSeconds);
78void CPL_DLL CPLCondSignal(CPLCond *hCond);
79void CPL_DLL CPLCondBroadcast(CPLCond *hCond);
80void CPL_DLL CPLDestroyCond(CPLCond *hCond);
81
84GIntBig CPL_DLL CPLGetPID(void);
85int CPL_DLL CPLGetCurrentProcessID(void);
86int CPL_DLL CPLCreateThread(CPLThreadFunc pfnMain, void *pArg);
87CPLJoinableThread CPL_DLL *CPLCreateJoinableThread(CPLThreadFunc pfnMain,
88 void *pArg);
89void CPL_DLL CPLJoinThread(CPLJoinableThread *hJoinableThread);
90void CPL_DLL CPLSleep(double dfWaitInSeconds);
91
92const char CPL_DLL *CPLGetThreadingModel(void);
93
94int CPL_DLL CPLGetNumCPUs(void);
95
96typedef struct _CPLLock CPLLock;
97
98/* Currently LOCK_ADAPTIVE_MUTEX is Linux-only and LOCK_SPIN only available */
99/* on systems with pthread_spinlock API (so not MacOsX). If a requested type */
100/* isn't available, it fallbacks to LOCK_RECURSIVE_MUTEX */
101typedef enum
102{
103 LOCK_RECURSIVE_MUTEX,
104 LOCK_ADAPTIVE_MUTEX,
105 LOCK_SPIN
106} CPLLockType;
107
108CPLLock CPL_DLL *CPLCreateLock(CPLLockType eType); /* returned NON acquired */
109int CPL_DLL CPLCreateOrAcquireLock(CPLLock **, CPLLockType eType);
110int CPL_DLL CPLAcquireLock(CPLLock *);
111void CPL_DLL CPLReleaseLock(CPLLock *);
112void CPL_DLL CPLDestroyLock(CPLLock *);
113void CPL_DLL CPLLockSetDebugPerf(
114 CPLLock *,
115 int bEnableIn); /* only available on x86/x86_64 with GCC for now */
116
118
119#if defined(__cplusplus) && !defined(CPL_SUPRESS_CPLUSPLUS)
120
121/* Instantiates the mutex if not already done. The parameter x should be a
122 * (void**). */
123#define CPLMutexHolderD(x) CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__)
124
125/* Instantiates the mutex with options if not already done. */
126/* The parameter x should be a (void**). */
127#define CPLMutexHolderExD(x, nOptions) \
128 CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__, nOptions)
129
130/* This variant assumes the mutex has already been created. If not, it will */
131/* be a no-op. The parameter x should be a (void*) */
132#define CPLMutexHolderOptionalLockD(x) \
133 CPLMutexHolder oHolder(x, 1000.0, __FILE__, __LINE__)
134
136class CPL_DLL CPLMutexHolder
137{
138 private:
139 CPLMutex *hMutex = nullptr;
140 // Only used for debugging.
141 const char *pszFile = nullptr;
142 int nLine = 0;
143
145
146 public:
148 explicit CPLMutexHolder(CPLMutex **phMutex, double dfWaitInSeconds = 1000.0,
149 const char *pszFile = __FILE__,
150 int nLine = __LINE__,
151 int nOptions = CPL_MUTEX_RECURSIVE);
152
155 explicit CPLMutexHolder(CPLMutex *hMutex, double dfWaitInSeconds = 1000.0,
156 const char *pszFile = __FILE__,
157 int nLine = __LINE__);
158
160};
161
162/* Instantiates the lock if not already done. The parameter x should be a
163 * (CPLLock**). */
164#define CPLLockHolderD(x, eType) \
165 CPLLockHolder oHolder(x, eType, __FILE__, __LINE__);
166
167/* This variant assumes the lock has already been created. If not, it will */
168/* be a no-op. The parameter should be (CPLLock*) */
169#define CPLLockHolderOptionalLockD(x) \
170 CPLLockHolder oHolder(x, __FILE__, __LINE__);
171
173class CPL_DLL CPLLockHolder
174{
175 private:
176 CPLLock *hLock = nullptr;
177 const char *pszFile = nullptr;
178 int nLine = 0;
179
181
182 public:
184 CPLLockHolder(CPLLock **phSpin, CPLLockType eType,
185 const char *pszFile = __FILE__, int nLine = __LINE__);
186
189 explicit CPLLockHolder(CPLLock *hSpin, const char *pszFile = __FILE__,
190 int nLine = __LINE__);
191
193};
194
195#endif /* def __cplusplus */
196
197/* -------------------------------------------------------------------- */
198/* Thread local storage. */
199/* -------------------------------------------------------------------- */
200
201#define CTLS_RLBUFFERINFO 1 /* cpl_conv.cpp */
202#define CTLS_WIN32_COND 2 /* cpl_multiproc.cpp */
203#define CTLS_CSVTABLEPTR 3 /* cpl_csv.cpp */
204#define CTLS_CSVDEFAULTFILENAME 4 /* cpl_csv.cpp */
205#define CTLS_ERRORCONTEXT 5 /* cpl_error.cpp */
206#define CTLS_VSICURL_CACHEDCONNECTION 6 /* cpl_vsil_curl.cpp */
207#define CTLS_PATHBUF 7 /* cpl_path.cpp */
208#define CTLS_ABSTRACTARCHIVE_SPLIT 8 /* cpl_vsil_abstract_archive.cpp */
209#define CTLS_GDALOPEN_ANTIRECURSION 9 /* gdaldataset.cpp */
210#define CTLS_CPLSPRINTF 10 /* cpl_string.h */
211#define CTLS_RESPONSIBLEPID 11 /* gdaldataset.cpp */
212#define CTLS_VERSIONINFO 12 /* gdal_misc.cpp */
213#define CTLS_VERSIONINFO_LICENCE 13 /* gdal_misc.cpp */
214#define CTLS_CONFIGOPTIONS 14 /* cpl_conv.cpp */
215#define CTLS_FINDFILE 15 /* cpl_findfile.cpp */
216#define CTLS_VSIERRORCONTEXT 16 /* cpl_vsi_error.cpp */
217/* 17: unused */
218#define CTLS_PROJCONTEXTHOLDER 18 /* ogr_proj_p.cpp */
219#define CTLS_GDALDEFAULTOVR_ANTIREC 19 /* gdaldefaultoverviews.cpp */
220#define CTLS_HTTPFETCHCALLBACK 20 /* cpl_http.cpp */
221
222#define CTLS_MAX 32
223
225void CPL_DLL *CPLGetTLS(int nIndex);
226void CPL_DLL *CPLGetTLSEx(int nIndex, int *pbMemoryErrorOccurred);
227void CPL_DLL CPLSetTLS(int nIndex, void *pData, int bFreeOnExit);
228
229/* Warning : the CPLTLSFreeFunc must not in any case directly or indirectly */
230/* use or fetch any TLS data, or a terminating thread will hang ! */
231typedef void (*CPLTLSFreeFunc)(void *pData);
232void CPL_DLL CPLSetTLSWithFreeFunc(int nIndex, void *pData,
233 CPLTLSFreeFunc pfnFree);
234void CPL_DLL CPLSetTLSWithFreeFuncEx(int nIndex, void *pData,
235 CPLTLSFreeFunc pfnFree,
236 int *pbMemoryErrorOccurred);
237
238void CPL_DLL CPLCleanupTLS(void);
240
241#endif /* CPL_MULTIPROC_H_INCLUDED_ */
Object to hold a lock.
Definition: cpl_multiproc.h:174
Object to hold a mutex.
Definition: cpl_multiproc.h:137
Core portability definitions for CPL.
#define CPL_C_END
Macro to end a block of C symbols.
Definition: cpl_port.h:283
#define CPL_C_START
Macro to start a block of C symbols.
Definition: cpl_port.h:279
#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:1030
long long GIntBig
Large signed integer type (generally 64-bit integer type).
Definition: cpl_port.h:199