~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/pbms/src/cslib/CSMutex.cc

  • Committer: Mark Atwood
  • Date: 2011-12-20 02:32:53 UTC
  • mfrom: (2469.1.1 drizzle-build)
  • Revision ID: me@mark.atwood.name-20111220023253-bvu0kr14kwsdvz7g
mergeĀ lp:~brianaker/drizzle/deprecate-pbms

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* Copyright (C) 2008 PrimeBase Technologies GmbH, Germany
2
 
 *
3
 
 * PrimeBase Media Stream for MySQL
4
 
 *
5
 
 * This program is free software; you can redistribute it and/or modify
6
 
 * it under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * This program is distributed in the hope that it will be useful,
11
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 * GNU General Public License for more details.
14
 
 *
15
 
 * You should have received a copy of the GNU General Public License
16
 
 * along with this program; if not, write to the Free Software
17
 
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
 
 *
19
 
 * Original author: Paul McCullagh (H&G2JCtL)
20
 
 * Continued development: Barry Leslie
21
 
 *
22
 
 * 2007-06-06
23
 
 *
24
 
 * A basic mutex (mutual exclusion) object.
25
 
 *
26
 
 */
27
 
 
28
 
#include "CSConfig.h"
29
 
 
30
 
#include <assert.h>
31
 
#ifdef OS_WINDOWS
32
 
extern int gettimeofday(struct timeval *tv, struct timezone *tz);
33
 
#else
34
 
#include <sys/time.h>
35
 
#endif
36
 
 
37
 
#include <unistd.h>
38
 
 
39
 
#include "CSException.h"
40
 
#include "CSMutex.h"
41
 
#include "CSGlobal.h"
42
 
#include "CSLog.h"
43
 
 
44
 
/*
45
 
 * ---------------------------------------------------------------
46
 
 * A MUTEX ENTITY
47
 
 */
48
 
 
49
 
CSMutex::CSMutex()
50
 
#ifdef DEBUG
51
 
:
52
 
iLocker(NULL),
53
 
trace(false)
54
 
#endif
55
 
{
56
 
        int err;
57
 
 
58
 
        if ((err = pthread_mutex_init(&iMutex, NULL)))
59
 
                CSException::throwOSError(CS_CONTEXT, err);
60
 
}
61
 
 
62
 
CSMutex::~CSMutex()
63
 
{
64
 
        pthread_mutex_destroy(&iMutex);
65
 
}
66
 
 
67
 
void CSMutex::lock()
68
 
{
69
 
        int err = 0;
70
 
 
71
 
#ifdef DEBUG
72
 
        int waiting = 2000;
73
 
        while (((err = pthread_mutex_trylock(&iMutex)) == EBUSY) && (waiting > 0)) {
74
 
                usleep(500);
75
 
                waiting--;
76
 
        }
77
 
        if (err) {
78
 
                if (err == EBUSY) {
79
 
                        CSL.logf(iLocker, CSLog::Protocol, "Thread holding lock.\n");
80
 
                }
81
 
                
82
 
                if ((err) || (err = pthread_mutex_lock(&iMutex)))
83
 
                        CSException::throwOSError(CS_CONTEXT, err);
84
 
        }
85
 
 
86
 
        iLocker = CSThread::getSelf();
87
 
        if (trace)
88
 
                CSL.logf(iLocker, CSLog::Protocol, "Mutex locked\n");
89
 
#else
90
 
        if ((err = pthread_mutex_lock(&iMutex)))
91
 
                CSException::throwOSError(CS_CONTEXT, err);
92
 
#endif
93
 
}
94
 
 
95
 
void CSMutex::unlock()
96
 
{
97
 
#ifdef DEBUG
98
 
        if (trace)
99
 
                CSL.logf(iLocker, CSLog::Protocol, "Mutex unlocked\n");
100
 
        iLocker = NULL;
101
 
#endif
102
 
        pthread_mutex_unlock(&iMutex);
103
 
}
104
 
 
105
 
/*
106
 
 * ---------------------------------------------------------------
107
 
 * A LOCK ENTITY
108
 
 */
109
 
 
110
 
CSLock::CSLock():
111
 
CSMutex(),
112
 
iLockingThread(NULL),
113
 
iLockCount(0)
114
 
{
115
 
}
116
 
 
117
 
CSLock::~CSLock()
118
 
{
119
 
}
120
 
 
121
 
void CSLock::lock()
122
 
{
123
 
        int err;
124
 
 
125
 
        enter_();
126
 
        if (iLockingThread != self) {
127
 
                if ((err = pthread_mutex_lock(&iMutex)))
128
 
                        CSException::throwOSError(CS_CONTEXT, err);
129
 
                iLockingThread = self;
130
 
        }
131
 
        iLockCount++;
132
 
        exit_();
133
 
}
134
 
 
135
 
void CSLock::unlock()
136
 
{
137
 
        enter_();
138
 
        ASSERT(iLockingThread == self);
139
 
        if (!(--iLockCount)) {
140
 
                iLockingThread = NULL;
141
 
                pthread_mutex_unlock(&iMutex);
142
 
        }
143
 
        exit_();
144
 
}
145
 
 
146
 
bool CSLock::haveLock()
147
 
{
148
 
        enter_();
149
 
        return_(iLockingThread == self);
150
 
}
151
 
 
152
 
/*
153
 
 * ---------------------------------------------------------------
154
 
 * A SYNCRONISATION ENTITY
155
 
 */
156
 
 
157
 
CSSync::CSSync():
158
 
CSLock()
159
 
{
160
 
        int err;
161
 
 
162
 
        if ((err = pthread_cond_init(&iCondition, NULL)))
163
 
                CSException::throwOSError(CS_CONTEXT, err);
164
 
}
165
 
 
166
 
CSSync::~CSSync()
167
 
{
168
 
        pthread_cond_destroy(&iCondition);
169
 
}
170
 
 
171
 
void CSSync::wait()
172
 
{
173
 
        int err;
174
 
        int lock_count;
175
 
 
176
 
        enter_();
177
 
        ASSERT(iLockingThread == self);
178
 
        lock_count = iLockCount;
179
 
        iLockCount = 0;
180
 
        iLockingThread = NULL;
181
 
        err = pthread_cond_wait(&iCondition, &iMutex);
182
 
        iLockCount = lock_count;
183
 
        iLockingThread = self;
184
 
        if (err)
185
 
                CSException::throwOSError(CS_CONTEXT, err);
186
 
        exit_();
187
 
}
188
 
 
189
 
void CSSync::wait(time_t milli_sec)
190
 
{
191
 
        struct timespec abstime;
192
 
        int                             lock_count;
193
 
        int                             err;
194
 
        uint64_t                micro_sec;
195
 
 
196
 
        enter_();
197
 
        struct timeval  now;
198
 
 
199
 
        /* Get the current time in microseconds: */
200
 
        gettimeofday(&now, NULL);
201
 
        micro_sec = (uint64_t) now.tv_sec * (uint64_t) 1000000 + (uint64_t) now.tv_usec;
202
 
        
203
 
        /* Add the timeout which is in milli seconds */
204
 
        micro_sec += (uint64_t) milli_sec * (uint64_t) 1000;
205
 
 
206
 
        /* Setup the end time, which is in nano-seconds. */
207
 
        abstime.tv_sec = (long) (micro_sec / 1000000);                          /* seconds */
208
 
        abstime.tv_nsec = (long) ((micro_sec % 1000000) * 1000);        /* and nanoseconds */
209
 
 
210
 
        ASSERT(iLockingThread == self);
211
 
        lock_count = iLockCount;
212
 
        iLockCount = 0;
213
 
        iLockingThread = NULL;
214
 
        err = pthread_cond_timedwait(&iCondition, &iMutex, &abstime);
215
 
        iLockCount = lock_count;
216
 
        iLockingThread = self;
217
 
        if (err && err != ETIMEDOUT)
218
 
                CSException::throwOSError(CS_CONTEXT, err);
219
 
        exit_();
220
 
}
221
 
 
222
 
void CSSync::wakeup()
223
 
{
224
 
        int err;
225
 
 
226
 
        if ((err = pthread_cond_broadcast(&iCondition)))
227
 
                CSException::throwOSError(CS_CONTEXT, err);
228
 
}
229
 
 
230
 
 
231