16 #if defined(__APPLE__)
19 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
22 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
32 class NamedMutex::Impl
35 Impl(
const std::string&
name) : _name(
name)
36 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
40 #if defined(__APPLE__)
41 throwex SystemException(
"Named mutex is not supported!");
42 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
46 pthread_mutexattr_t mutex_attribute;
47 int result = pthread_mutexattr_init(&mutex_attribute);
49 throwex SystemException(
"Failed to initialize a named mutex attribute!", result);
50 result = pthread_mutexattr_setpshared(&mutex_attribute, PTHREAD_PROCESS_SHARED);
52 throwex SystemException(
"Failed to set a named mutex process shared attribute!", result);
53 result = pthread_mutex_init(&_shared->mutex, &mutex_attribute);
55 throwex SystemException(
"Failed to initialize a named mutex!", result);
56 result = pthread_mutexattr_destroy(&mutex_attribute);
58 throwex SystemException(
"Failed to destroy a named mutex attribute!", result);
60 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
61 _mutex = CreateMutexA(
nullptr, FALSE,
name.c_str());
62 if (_mutex ==
nullptr)
63 throwex SystemException(
"Failed to create or open a named mutex!");
69 #if defined(__APPLE__)
70 fatality(SystemException(
"Named mutex is not supported!"));
71 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
75 int result = pthread_mutex_destroy(&_shared->mutex);
77 fatality(SystemException(
"Failed to destroy a named mutex!", result));
79 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
80 if (!CloseHandle(_mutex))
81 fatality(SystemException(
"Failed to close a named mutex!"));
85 const std::string&
name()
const
92 #if defined(__APPLE__)
93 throwex SystemException(
"Named mutex is not supported!");
94 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
95 int result = pthread_mutex_trylock(&_shared->mutex);
96 if ((result != 0) && (result != EAGAIN) && (result != EBUSY) && (result != EDEADLK))
97 throwex SystemException(
"Failed to try lock a named mutex!", result);
99 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
100 DWORD result = WaitForSingleObject(_mutex, 0);
101 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
102 throwex SystemException(
"Failed to try lock a named mutex!");
103 return (result == WAIT_OBJECT_0);
111 #if defined(__APPLE__)
112 throwex SystemException(
"Named mutex is not supported!");
113 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
114 struct timespec timeout;
115 timeout.tv_sec = timespan.seconds();
116 timeout.tv_nsec = timespan.nanoseconds() % 1000000000;
117 int result = pthread_mutex_timedlock(&_shared->mutex, &timeout);
118 if ((result != 0) && (result != ETIMEDOUT))
119 throwex SystemException(
"Failed to try lock a named mutex for the given timeout!", result);
120 return (result == 0);
121 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
122 DWORD result = WaitForSingleObject(_mutex, std::max((DWORD)1, (DWORD)timespan.milliseconds()));
123 if ((result != WAIT_OBJECT_0) && (result != WAIT_TIMEOUT))
124 throwex SystemException(
"Failed to try lock a named mutex for the given timeout!");
125 return (result == WAIT_OBJECT_0);
131 #if defined(__APPLE__)
132 throwex SystemException(
"Named mutex is not supported!");
133 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
134 int result = pthread_mutex_lock(&_shared->mutex);
136 throwex SystemException(
"Failed to lock a named mutex!", result);
137 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
138 DWORD result = WaitForSingleObject(_mutex, INFINITE);
139 if (result != WAIT_OBJECT_0)
140 throwex SystemException(
"Failed to lock a named mutex!");
146 #if defined(__APPLE__)
147 throwex SystemException(
"Named mutex is not supported!");
148 #elif (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__CYGWIN__)
149 int result = pthread_mutex_unlock(&_shared->mutex);
151 throwex SystemException(
"Failed to unlock a named mutex!", result);
152 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
153 if (!ReleaseMutex(_mutex))
154 throwex SystemException(
"Failed to unlock a named mutex!");
160 #if (defined(unix) || defined(__unix) || defined(__unix__)) && !defined(__APPLE__) && !defined(__CYGWIN__)
164 pthread_mutex_t mutex;
168 SharedType<MutexHeader> _shared;
169 #elif defined(_WIN32) || defined(_WIN64) || defined(__CYGWIN__)
180 static_assert((StorageSize >=
sizeof(Impl)),
"NamedMutex::StorageSize must be increased!");
181 static_assert(((StorageAlign %
alignof(Impl)) == 0),
"NamedMutex::StorageAlign must be adjusted!");
184 new(&_storage)Impl(
name);
190 reinterpret_cast<Impl*
>(&_storage)->~Impl();
NamedMutex(const std::string &name)
Default class constructor.
bool TryLock()
Try to acquire mutex without block.
void Unlock()
Release mutex.
const std::string & name() const
Get the mutex name.
void Lock()
Acquire mutex with block.
bool TryLockFor(const Timespan ×pan)
Try to acquire mutex for the given timespan.
Aligned storage validator.
#define throwex
Throw extended exception macro.
Fatal abort execution definition.
#define fatality(...)
Fatal abort execution extended macro.
Named mutex synchronization primitive definition.
C++ Common project definitions.
Shared memory type definition.
Aligned storage validator definition.