source: filezilla/trunk/fuentes/src/include/mutex.h @ 130

Last change on this file since 130 was 130, checked in by jrpelegrina, 4 years ago

First release to xenial

File size: 2.3 KB
Line 
1#ifndef FILEZILLA_MUTEX_HEADER
2#define FILEZILLA_MUTEX_HEADER
3
4/* A mutex, or critical section, should be as lightweight as possible.
5 * Unfortunately, wxWidgets' mutex isn't lightweight at all.
6 * Testing has shown that locking or unlocking a wxMutex consists of
7 * 60% useless cruft, e.g. deadlock detection (Why try to detect deadlocks?
8 * Deadlocks detect itself!)
9 *
10 * Likewise, wxCondition carries a heavy overhead as well. In particular, under MSW
11 * it doesn't and can't (due to XP compatibility) use Vista+'s CONDITION_VARIABLE.
12 *
13 * Unfortunately we can't use std::mutex for the rescue as MinGW doesn't implement
14 * C++11 threading yet in common configurations.
15 */
16
17#ifndef __WXMSW__
18#include <pthread.h>
19#endif
20
21class mutex final
22{
23public:
24        explicit mutex(bool recursive = true);
25        ~mutex();
26
27        mutex( mutex const& ) = delete;
28        mutex& operator=( mutex const& ) = delete;
29
30        // Beware, manual locking isn't exception safe
31        void lock();
32        void unlock();
33
34private:
35        friend class condition;
36        friend class scoped_lock;
37
38#ifdef __WXMSW__
39        CRITICAL_SECTION m_;
40#else
41        pthread_mutex_t m_;
42#endif
43};
44
45class scoped_lock final
46{
47public:
48        explicit scoped_lock(mutex& m)
49                : m_(&m.m_)
50        {
51#ifdef __WXMSW__
52                EnterCriticalSection(m_);
53#else
54                pthread_mutex_lock(m_);
55#endif
56        }
57
58        ~scoped_lock()
59        {
60                if (locked_) {
61        #ifdef __WXMSW__
62                        LeaveCriticalSection(m_);
63        #else
64                        pthread_mutex_unlock(m_);
65        #endif
66                }
67
68        }
69
70        scoped_lock( scoped_lock const& ) = delete;
71        scoped_lock& operator=( scoped_lock const& ) = delete;
72
73        void lock()
74        {
75                locked_ = true;
76#ifdef __WXMSW__
77                EnterCriticalSection(m_);
78#else
79                pthread_mutex_lock(m_);
80#endif
81        }
82
83        void unlock()
84        {
85                locked_ = false;
86#ifdef __WXMSW__
87                LeaveCriticalSection(m_);
88#else
89                pthread_mutex_unlock(m_);
90#endif
91        }
92
93private:
94        friend class condition;
95
96#ifdef __WXMSW__
97        CRITICAL_SECTION * const m_;
98#else
99        pthread_mutex_t * const m_;
100#endif
101        bool locked_{true};
102};
103
104class condition final
105{
106public:
107        condition();
108        ~condition();
109
110        condition(condition const&) = delete;
111        condition& operator=(condition const&) = delete;
112
113        void wait(scoped_lock& l);
114
115        // Milliseconds
116        // Returns false on timeout
117        bool wait(scoped_lock& l, int timeout_ms);
118
119        void signal(scoped_lock& l);
120
121        bool signalled(scoped_lock const&) const { return signalled_; }
122private:
123#ifdef __WXMSW__
124        CONDITION_VARIABLE cond_;
125#else
126        pthread_cond_t cond_;
127#endif
128        bool signalled_;
129};
130
131#endif
Note: See TracBrowser for help on using the repository browser.