22
22
/* Type definition for an operating system mutex struct */
23
23
struct os_mutex_struct{
24
os_event_t event; /* Used by sync0arr.c for queing threads */
24
25
void* handle; /* OS handle to mutex */
25
26
ulint count; /* we use this counter to check
26
27
that the same thread does not
35
36
/* Mutex protecting counts and the lists of OS mutexes and events */
36
37
os_mutex_t os_sync_mutex;
37
38
ibool os_sync_mutex_inited = FALSE;
39
ibool os_sync_free_called = FALSE;
39
41
/* This is incremented by 1 in os_thread_create and decremented by 1 in
50
52
ulint os_mutex_count = 0;
51
53
ulint os_fast_mutex_count = 0;
55
/* Because a mutex is embedded inside an event and there is an
56
event embedded inside a mutex, on free, this generates a recursive call.
57
This version of the free event function doesn't acquire the global lock */
58
static void os_event_free_internal(os_event_t event);
54
60
/*************************************************************
55
61
Initializes global event and OS 'slow' mutex lists. */
144
152
ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
146
154
event->is_set = FALSE;
147
event->signal_count = 0;
156
/* We return this value in os_event_reset(), which can then be
157
be used to pass to the os_event_wait_low(). The value of zero
158
is reserved in os_event_wait_low() for the case when the
159
caller does not want to pass any signal_count value. To
160
distinguish between the two cases we initialize signal_count
162
event->signal_count = 1;
148
163
#endif /* __WIN__ */
165
/* The os_sync_mutex can be NULL because during startup an event
166
can be created [ because it's embedded in the mutex/rwlock ] before
167
this module has been initialized */
168
if (os_sync_mutex != NULL) {
169
os_mutex_enter(os_sync_mutex);
150
172
/* Put to the list of events */
151
os_mutex_enter(os_sync_mutex);
153
173
UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
155
175
os_event_count++;
157
os_mutex_exit(os_sync_mutex);
177
if (os_sync_mutex != NULL) {
178
os_mutex_exit(os_sync_mutex);
232
254
/**************************************************************
233
255
Resets an event semaphore to the nonsignaled state. Waiting threads will
234
stop to wait for the event. */
256
stop to wait for the event.
257
The return value should be passed to os_even_wait_low() if it is desired
258
that this thread should not wait in case of an intervening call to
259
os_event_set() between this os_event_reset() and the
260
os_event_wait_low() call. See comments for os_event_wait_low(). */
265
/* out: current signal_count. */
239
266
os_event_t event) /* in: event to reset */
253
282
event->is_set = FALSE;
284
ret = event->signal_count;
256
286
os_fast_mutex_unlock(&(event->os_mutex));
291
/**************************************************************
292
Frees an event object, without acquiring the global lock. */
295
os_event_free_internal(
296
/*===================*/
297
os_event_t event) /* in: event to free */
302
ut_a(CloseHandle(event->handle));
306
/* This is to avoid freeing the mutex twice */
307
os_fast_mutex_free(&(event->os_mutex));
309
ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
311
/* Remove from the list of events */
313
UT_LIST_REMOVE(os_event_list, os_event_list, event);
260
320
/**************************************************************
293
353
Waits for an event object until it is in the signaled state. If
294
354
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
295
355
waiting thread when the event becomes signaled (or immediately if the
296
event is already in the signaled state). */
356
event is already in the signaled state).
358
Typically, if the event has been signalled after the os_event_reset()
359
we'll return immediately because event->is_set == TRUE.
360
There are, however, situations (e.g.: sync_array code) where we may
361
lose this information. For example:
363
thread A calls os_event_reset()
364
thread B calls os_event_set() [event->is_set == TRUE]
365
thread C calls os_event_reset() [event->is_set == FALSE]
366
thread A calls os_event_wait() [infinite wait!]
367
thread C calls os_event_wait() [infinite wait!]
369
Where such a scenario is possible, to avoid infinite wait, the
370
value returned by os_event_reset() should be passed in as
301
os_event_t event) /* in: event to wait */
376
os_event_t event, /* in: event to wait */
377
ib_longlong reset_sig_count)/* in: zero or the value
378
returned by previous call of
386
UT_NOT_USED(reset_sig_count);
308
388
/* Specify an infinite time limit for waiting */
309
389
err = WaitForSingleObject(event->handle, INFINITE);
319
399
os_fast_mutex_lock(&(event->os_mutex));
321
old_signal_count = event->signal_count;
401
if (reset_sig_count) {
402
old_signal_count = reset_sig_count;
404
old_signal_count = event->signal_count;
324
408
if (event->is_set == TRUE