~drizzle-trunk/drizzle/development

1548.2.1 by Barry.Leslie at PrimeBase
Added the PBMS daemon plugin.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
#include <sys/time.h>
32
33
#include "CSException.h"
34
#include "CSMutex.h"
35
#include "CSGlobal.h"
36
37
/*
38
 * ---------------------------------------------------------------
39
 * A MUTEX ENTITY
40
 */
41
42
CSMutex::CSMutex()
43
{
44
	int err;
45
46
	if ((err = pthread_mutex_init(&iMutex, NULL)))
47
		CSException::throwOSError(CS_CONTEXT, err);
48
}
49
50
CSMutex::~CSMutex()
51
{
52
	pthread_mutex_destroy(&iMutex);
53
}
54
55
void CSMutex::lock()
56
{
57
	int err;
58
59
	if ((err = pthread_mutex_lock(&iMutex)))
60
		CSException::throwOSError(CS_CONTEXT, err);
61
}
62
63
void CSMutex::unlock()
64
{
65
	pthread_mutex_unlock(&iMutex);
66
}
67
68
/*
69
 * ---------------------------------------------------------------
70
 * A LOCK ENTITY
71
 */
72
73
CSLock::CSLock():
74
CSMutex(),
75
iLockingThread(NULL),
76
iLockCount(0)
77
{
78
}
79
80
CSLock::~CSLock()
81
{
82
}
83
84
void CSLock::lock()
85
{
86
	int err;
87
88
	enter_();
89
	if (iLockingThread != self) {
90
		if ((err = pthread_mutex_lock(&iMutex)))
91
			CSException::throwOSError(CS_CONTEXT, err);
92
		iLockingThread = self;
93
	}
94
	iLockCount++;
95
	exit_();
96
}
97
98
void CSLock::unlock()
99
{
100
	enter_();
101
	ASSERT(iLockingThread == self);
102
	if (!(--iLockCount)) {
103
		iLockingThread = NULL;
104
		pthread_mutex_unlock(&iMutex);
105
	}
106
	exit_();
107
}
108
109
bool CSLock::haveLock()
110
{
111
	enter_();
112
	return_(iLockingThread == self);
113
}
114
115
/*
116
 * ---------------------------------------------------------------
117
 * A SYNCRONISATION ENTITY
118
 */
119
120
CSSync::CSSync():
121
CSLock()
122
{
123
	int err;
124
125
	if ((err = pthread_cond_init(&iCondition, NULL)))
126
		CSException::throwOSError(CS_CONTEXT, err);
127
}
128
129
CSSync::~CSSync()
130
{
131
	pthread_cond_destroy(&iCondition);
132
}
133
134
void CSSync::wait()
135
{
136
	int err;
137
	int lock_count;
138
139
	enter_();
140
	ASSERT(iLockingThread == self);
141
	lock_count = iLockCount;
142
	iLockCount = 0;
143
	iLockingThread = NULL;
144
	err = pthread_cond_wait(&iCondition, &iMutex);
145
	iLockCount = lock_count;
146
	iLockingThread = self;
147
	if (err)
148
		CSException::throwOSError(CS_CONTEXT, err);
149
	exit_();
150
}
151
152
void CSSync::wait(time_t milli_sec)
153
{
154
	struct timespec	abstime;
155
	int				lock_count;
156
	int				err;
157
158
	enter_();
159
#ifdef XT_WIN
160
	union ft64		now;
161
  
162
	GetSystemTimeAsFileTime(&now.ft);
163
164
	/* System time is measured in 100ns units.
165
	 * This calculation will be reversed by the Windows implementation
166
	 * of pthread_cond_timedwait(), in order to extract the
167
	 * milli-second timeout!
168
	 */
169
	abstime.tv.i64 = now.i64 + (milli_sec * 10000);
170
  
171
	abstime.max_timeout_msec = milli_sec;
172
#else
173
	struct timeval	now;
174
	uint64_t			micro_sec;
175
176
	/* Get the current time in microseconds: */
177
	gettimeofday(&now, NULL);
178
	micro_sec = (uint64_t) now.tv_sec * (uint64_t) 1000000 + (uint64_t) now.tv_usec;
179
	
180
	/* Add the timeout which is in milli seconds */
181
	micro_sec += (uint64_t) milli_sec * (uint64_t) 1000;
182
183
	/* Setup the end time, which is in nano-seconds. */
184
	abstime.tv_sec = (long) (micro_sec / 1000000);				/* seconds */
185
	abstime.tv_nsec = (long) ((micro_sec % 1000000) * 1000);	/* and nanoseconds */
186
#endif
187
	ASSERT(iLockingThread == self);
188
	lock_count = iLockCount;
189
	iLockCount = 0;
190
	iLockingThread = NULL;
191
	err = pthread_cond_timedwait(&iCondition, &iMutex, &abstime);
192
	iLockCount = lock_count;
193
	iLockingThread = self;
194
	if (err && err != ETIMEDOUT)
195
		CSException::throwOSError(CS_CONTEXT, err);
196
	exit_();
197
}
198
199
void CSSync::wakeup()
200
{
201
	int err;
202
203
	if ((err = pthread_cond_broadcast(&iCondition)))
204
		CSException::throwOSError(CS_CONTEXT, err);
205
}
206
207
208