source: filezilla/trunk/fuentes/src/engine/mutex.cpp @ 130

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

First release to xenial

File size: 2.9 KB
Line 
1#include <filezilla.h>
2#include "mutex.h"
3
4#ifndef __WXMSW__
5#include <sys/time.h>
6#endif
7
8#ifndef __WXMSW__
9namespace {
10// Static initializers for mutex and condition attributes
11template<int type>
12pthread_mutexattr_t* init_mutexattr()
13{
14        static pthread_mutexattr_t attr;
15        pthread_mutexattr_init(&attr);
16        pthread_mutexattr_settype(&attr, type);
17        return &attr;
18}
19
20pthread_mutexattr_t* get_mutex_attributes(bool recursive)
21{
22        if (recursive) {
23                static pthread_mutexattr_t *attr = init_mutexattr<PTHREAD_MUTEX_RECURSIVE>();
24                return attr;
25        }
26        else {
27                static pthread_mutexattr_t *attr = init_mutexattr<PTHREAD_MUTEX_NORMAL>();
28                return attr;
29        }
30}
31
32pthread_condattr_t* init_condattr()
33{
34#if HAVE_CLOCK_GETTIME && HAVE_DECL_PTHREAD_CONDATTR_SETCLOCK
35        static pthread_condattr_t attr;
36        pthread_condattr_init(&attr);
37        pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
38        return &attr;
39#else
40        return 0;
41#endif
42}
43}
44#endif
45
46mutex::mutex(bool recursive)
47{
48#ifdef __WXMSW__
49        (void)recursive; // Critical sections are always recursive
50        InitializeCriticalSection(&m_);
51#else
52        pthread_mutex_init(&m_, get_mutex_attributes(recursive));
53#endif
54}
55
56mutex::~mutex()
57{
58#ifdef __WXMSW__
59        DeleteCriticalSection(&m_);
60#else
61        pthread_mutex_destroy(&m_);
62#endif
63}
64
65void mutex::lock()
66{
67#ifdef __WXMSW__
68        EnterCriticalSection(&m_);
69#else
70        pthread_mutex_lock(&m_);
71#endif
72}
73
74void mutex::unlock()
75{
76#ifdef __WXMSW__
77        LeaveCriticalSection(&m_);
78#else
79        pthread_mutex_unlock(&m_);
80#endif
81}
82
83
84condition::condition()
85        : signalled_()
86{
87#ifdef __WXMSW__
88        InitializeConditionVariable(&cond_);
89#else
90
91        static pthread_condattr_t *attr = init_condattr();
92        pthread_cond_init(&cond_, attr);
93#endif
94}
95
96
97condition::~condition()
98{
99#ifdef __WXMSW__
100#else
101        pthread_cond_destroy(&cond_);
102#endif
103}
104
105void condition::wait(scoped_lock& l)
106{
107        while (!signalled_) {
108#ifdef __WXMSW__
109                SleepConditionVariableCS(&cond_, l.m_, INFINITE);
110#else
111                pthread_cond_wait(&cond_, l.m_);
112#endif
113        }
114        signalled_ = false;
115}
116
117bool condition::wait(scoped_lock& l, int timeout_ms)
118{
119        if (signalled_) {
120                signalled_ = false;
121                return true;
122        }
123#ifdef __WXMSW__
124        bool const success = SleepConditionVariableCS(&cond_, l.m_, timeout_ms) != 0;
125#else
126        int res;
127        timespec ts;
128#if HAVE_CLOCK_GETTIME && HAVE_DECL_PTHREAD_CONDATTR_SETCLOCK
129        clock_gettime(CLOCK_MONOTONIC, &ts);
130#else
131        timeval tv{};
132        gettimeofday(&tv, 0);
133        ts.tv_sec = tv.tv_sec;
134        ts.tv_nsec = tv.tv_usec * 1000;
135#endif
136
137        ts.tv_sec += timeout_ms / 1000;
138        ts.tv_nsec += (timeout_ms % 1000) * 1000 * 1000;
139        if (ts.tv_nsec > 1000000000ll) {
140                ++ts.tv_sec;
141                ts.tv_nsec -= 1000000000ll;
142        }
143
144        do {
145                res = pthread_cond_timedwait(&cond_, l.m_, &ts);
146        }
147        while (res == EINTR);
148        bool const success = res == 0;
149#endif
150        if (success) {
151                signalled_ = false;
152        }
153
154        return success;
155}
156
157
158void condition::signal(scoped_lock &)
159{
160        if (!signalled_) {
161                signalled_ = true;
162#ifdef __WXMSW__
163                WakeConditionVariable(&cond_);
164#else
165                pthread_cond_signal(&cond_);
166#endif
167        }
168}
Note: See TracBrowser for help on using the repository browser.