Skip to content

Commit 0a16e53

Browse files
committedOct 6, 2016
Fix C++11 Windows build of threading code
The initial problem was that mutex_auto_lock.h tries to use std::unique_lock<std::mutex> despite mutex.h not using C++11's std::mutex on Windows. The problem here is the mismatch between C++11 usage conditions of the two headers. This commit moves the decision logic to threads.h and makes sure mutex.h, mutex_auto_lock.h and event.h all use the same features.
1 parent 155288e commit 0a16e53

File tree

8 files changed

+65
-57
lines changed

8 files changed

+65
-57
lines changed
 

‎src/threading/event.cpp

+8-8
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ DEALINGS IN THE SOFTWARE.
2727

2828
Event::Event()
2929
{
30-
#if __cplusplus < 201103L
31-
# ifdef _WIN32
30+
#ifndef USE_CPP11_MUTEX
31+
# if USE_WIN_MUTEX
3232
event = CreateEvent(NULL, false, false, NULL);
3333
# else
3434
pthread_cond_init(&cv, NULL);
@@ -38,10 +38,10 @@ Event::Event()
3838
#endif
3939
}
4040

41-
#if __cplusplus < 201103L
41+
#ifndef USE_CPP11_MUTEX
4242
Event::~Event()
4343
{
44-
#ifdef _WIN32
44+
#if USE_WIN_MUTEX
4545
CloseHandle(event);
4646
#else
4747
pthread_cond_destroy(&cv);
@@ -53,13 +53,13 @@ Event::~Event()
5353

5454
void Event::wait()
5555
{
56-
#if __cplusplus >= 201103L
56+
#if USE_CPP11_MUTEX
5757
MutexAutoLock lock(mutex);
5858
while (!notified) {
5959
cv.wait(lock);
6060
}
6161
notified = false;
62-
#elif defined(_WIN32)
62+
#elif USE_WIN_MUTEX
6363
WaitForSingleObject(event, INFINITE);
6464
#else
6565
pthread_mutex_lock(&mutex);
@@ -74,11 +74,11 @@ void Event::wait()
7474

7575
void Event::signal()
7676
{
77-
#if __cplusplus >= 201103L
77+
#if USE_CPP11_MUTEX
7878
MutexAutoLock lock(mutex);
7979
notified = true;
8080
cv.notify_one();
81-
#elif defined(_WIN32)
81+
#elif USE_WIN_MUTEX
8282
SetEvent(event);
8383
#else
8484
pthread_mutex_lock(&mutex);

‎src/threading/event.h

+6-11
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,12 @@ DEALINGS IN THE SOFTWARE.
2626
#ifndef THREADING_EVENT_H
2727
#define THREADING_EVENT_H
2828

29-
#if __cplusplus >= 201103L
29+
#include "threads.h"
30+
31+
#if USE_CPP11_MUTEX
3032
#include <condition_variable>
3133
#include "threading/mutex.h"
3234
#include "threading/mutex_auto_lock.h"
33-
#elif defined(_WIN32)
34-
#ifndef WIN32_LEAN_AND_MEAN
35-
#define WIN32_LEAN_AND_MEAN
36-
#endif
37-
#include <windows.h>
38-
#else
39-
#include <pthread.h>
4035
#endif
4136

4237

@@ -49,18 +44,18 @@ DEALINGS IN THE SOFTWARE.
4944
class Event {
5045
public:
5146
Event();
52-
#if __cplusplus < 201103L
47+
#ifndef USE_CPP11_MUTEX
5348
~Event();
5449
#endif
5550
void wait();
5651
void signal();
5752

5853
private:
59-
#if __cplusplus >= 201103L
54+
#if USE_CPP11_MUTEX
6055
std::condition_variable cv;
6156
Mutex mutex;
6257
bool notified;
63-
#elif defined(_WIN32)
58+
#elif USE_WIN_MUTEX
6459
HANDLE event;
6560
#else
6661
pthread_cond_t cv;

‎src/threading/mutex.cpp

+9-10
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,13 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2323
DEALINGS IN THE SOFTWARE.
2424
*/
2525

26-
// Windows std::mutex is much slower than the critical section API
27-
#if __cplusplus < 201103L || defined(_WIN32)
26+
#include "threads.h"
27+
28+
#ifndef USE_CPP11_MUTEX
2829

2930
#include "threading/mutex.h"
3031

31-
#ifndef _WIN32
32-
#include <cassert>
33-
#endif
32+
#include <cassert>
3433

3534
#define UNUSED(expr) do { (void)(expr); } while (0)
3635

@@ -47,7 +46,7 @@ Mutex::Mutex(bool recursive)
4746

4847
void Mutex::init_mutex(bool recursive)
4948
{
50-
#ifdef _WIN32
49+
#if USE_WIN_MUTEX
5150
// Windows critical sections are recursive by default
5251
UNUSED(recursive);
5352

@@ -69,7 +68,7 @@ void Mutex::init_mutex(bool recursive)
6968

7069
Mutex::~Mutex()
7170
{
72-
#ifdef _WIN32
71+
#if USE_WIN_MUTEX
7372
DeleteCriticalSection(&mutex);
7473
#else
7574
int ret = pthread_mutex_destroy(&mutex);
@@ -80,7 +79,7 @@ Mutex::~Mutex()
8079

8180
void Mutex::lock()
8281
{
83-
#ifdef _WIN32
82+
#if USE_WIN_MUTEX
8483
EnterCriticalSection(&mutex);
8584
#else
8685
int ret = pthread_mutex_lock(&mutex);
@@ -91,7 +90,7 @@ void Mutex::lock()
9190

9291
void Mutex::unlock()
9392
{
94-
#ifdef _WIN32
93+
#if USE_WIN_MUTEX
9594
LeaveCriticalSection(&mutex);
9695
#else
9796
int ret = pthread_mutex_unlock(&mutex);
@@ -104,5 +103,5 @@ RecursiveMutex::RecursiveMutex()
104103
: Mutex(true)
105104
{}
106105

107-
#endif
106+
#endif // C++11
108107

‎src/threading/mutex.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -26,22 +26,23 @@ DEALINGS IN THE SOFTWARE.
2626
#ifndef THREADING_MUTEX_H
2727
#define THREADING_MUTEX_H
2828

29-
// Windows std::mutex is much slower than the critical section API
30-
#if __cplusplus >= 201103L && !defined(_WIN32)
29+
#include "threads.h"
30+
31+
#if USE_CPP11_MUTEX
3132
#include <mutex>
3233
using Mutex = std::mutex;
3334
using RecursiveMutex = std::recursive_mutex;
3435
#else
3536

36-
#ifdef _WIN32
37+
#if USE_WIN_MUTEX
3738
#ifndef _WIN32_WINNT
3839
#define _WIN32_WINNT 0x0501
3940
#endif
4041
#ifndef WIN32_LEAN_AND_MEAN
4142
#define WIN32_LEAN_AND_MEAN
4243
#endif
4344
#include <windows.h>
44-
#else // pthread
45+
#else
4546
#include <pthread.h>
4647
#endif
4748

@@ -59,9 +60,9 @@ class Mutex
5960
Mutex(bool recursive);
6061
void init_mutex(bool recursive);
6162
private:
62-
#ifdef _WIN32
63+
#if USE_WIN_MUTEX
6364
CRITICAL_SECTION mutex;
64-
#else // pthread
65+
#else
6566
pthread_mutex_t mutex;
6667
#endif
6768

@@ -76,6 +77,6 @@ class RecursiveMutex : public Mutex
7677
DISABLE_CLASS_COPY(RecursiveMutex);
7778
};
7879

79-
#endif // C++11
80+
#endif // C++11
8081

8182
#endif

‎src/threading/mutex_auto_lock.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ DEALINGS IN THE SOFTWARE.
2626
#ifndef THREADING_MUTEX_AUTO_LOCK_H
2727
#define THREADING_MUTEX_AUTO_LOCK_H
2828

29-
#if __cplusplus >= 201103L
29+
#include "threads.h"
30+
31+
#if USE_CPP11_MUTEX
3032
#include <mutex>
3133
using MutexAutoLock = std::unique_lock<std::mutex>;
3234
using RecursiveMutexAutoLock = std::unique_lock<std::recursive_mutex>;

‎src/threading/thread.cpp

+10-10
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ bool Thread::kill()
198198

199199
m_running = false;
200200

201-
#ifdef _WIN32
201+
#if USE_WIN_THREADS
202202
TerminateThread(m_thread_handle, 0);
203203
CloseHandle(m_thread_handle);
204204
#else
@@ -310,10 +310,16 @@ void Thread::setName(const std::string &name)
310310

311311
unsigned int Thread::getNumberOfProcessors()
312312
{
313-
#if __cplusplus >= 201103L
313+
#if USE_CPP11_THREADS
314314

315315
return std::thread::hardware_concurrency();
316316

317+
#elif USE_WIN_THREADS
318+
319+
SYSTEM_INFO sysinfo;
320+
GetSystemInfo(&sysinfo);
321+
return sysinfo.dwNumberOfProcessors;
322+
317323
#elif defined(_SC_NPROCESSORS_ONLN)
318324

319325
return sysconf(_SC_NPROCESSORS_ONLN);
@@ -335,12 +341,6 @@ unsigned int Thread::getNumberOfProcessors()
335341

336342
return get_nprocs();
337343

338-
#elif defined(_WIN32)
339-
340-
SYSTEM_INFO sysinfo;
341-
GetSystemInfo(&sysinfo);
342-
return sysinfo.dwNumberOfProcessors;
343-
344344
#elif defined(PTW32_VERSION) || defined(__hpux)
345345

346346
return pthread_num_processors_np();
@@ -359,7 +359,7 @@ bool Thread::bindToProcessor(unsigned int proc_number)
359359

360360
return false;
361361

362-
#elif defined(_WIN32)
362+
#elif USE_WIN_THREADS
363363

364364
return SetThreadAffinityMask(getThreadHandle(), 1 << proc_number);
365365

@@ -407,7 +407,7 @@ bool Thread::bindToProcessor(unsigned int proc_number)
407407

408408
bool Thread::setPriority(int prio)
409409
{
410-
#if defined(_WIN32)
410+
#if USE_WIN_THREADS
411411

412412
return SetThreadPriority(getThreadHandle(), prio);
413413

‎src/threading/thread.h

+4-9
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ DEALINGS IN THE SOFTWARE.
3232
#include "threads.h"
3333

3434
#include <string>
35-
#if USE_CPP11_THREADS
36-
#include <thread> // for std::thread
37-
#endif
3835
#ifdef _AIX
3936
#include <sys/thread.h> // for tid_t
4037
#endif
@@ -157,9 +154,11 @@ class Thread {
157154
Atomic<bool> m_running;
158155
Mutex m_mutex;
159156

160-
#ifndef USE_CPP11_THREADS
157+
#if USE_CPP11_THREADS
158+
std::thread *m_thread_obj;
159+
#else
161160
threadhandle_t m_thread_handle;
162-
# if _WIN32
161+
# if USE_WIN_THREADS
163162
threadid_t m_thread_id;
164163
# endif
165164
#endif
@@ -172,10 +171,6 @@ class Thread {
172171
tid_t m_kernel_thread_id;
173172
#endif
174173

175-
#if USE_CPP11_THREADS
176-
std::thread *m_thread_obj;
177-
#endif
178-
179174
DISABLE_CLASS_COPY(Thread);
180175
};
181176

‎src/threads.h

+17-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2121
#define THREADS_HEADER
2222

2323
//
24-
// Determine which threading API we will use
24+
// Determine which threading APIs we will use
2525
//
2626
#if __cplusplus >= 201103L
2727
#define USE_CPP11_THREADS 1
@@ -31,11 +31,27 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3131
#define USE_POSIX_THREADS 1
3232
#endif
3333

34+
#if defined(_WIN32)
35+
// Prefer critical section API because std::mutex is much slower on Windows
36+
#define USE_WIN_MUTEX 1
37+
#elif __cplusplus >= 201103L
38+
#define USE_CPP11_MUTEX 1
39+
#else
40+
#define USE_POSIX_MUTEX 1
41+
#endif
42+
3443
///////////////
3544

3645

3746
#if USE_CPP11_THREADS
3847
#include <thread>
48+
#elif USE_POSIX_THREADS
49+
#include <pthread.h>
50+
#else
51+
#ifndef WIN32_LEAN_AND_MEAN
52+
#define WIN32_LEAN_AND_MEAN
53+
#endif
54+
#include <windows.h>
3955
#endif
4056

4157
#include "threading/mutex.h"

0 commit comments

Comments
 (0)
Please sign in to comment.