78
77
This version of the free event function doesn't acquire the global lock */
79
78
static void os_event_free_internal(os_event_t event);
81
/* On Windows (Vista and later), load function pointers for condition
82
variable handling. Those functions are not available in prior versions,
83
so we have to use them via runtime loading, as long as we support XP. */
84
static void os_cond_module_init(void);
87
/* Prototypes and function pointers for condition variable functions */
88
typedef VOID (WINAPI* InitializeConditionVariableProc)
89
(PCONDITION_VARIABLE ConditionVariable);
90
static InitializeConditionVariableProc initialize_condition_variable;
92
typedef BOOL (WINAPI* SleepConditionVariableCSProc)
93
(PCONDITION_VARIABLE ConditionVariable,
94
PCRITICAL_SECTION CriticalSection,
95
DWORD dwMilliseconds);
96
static SleepConditionVariableCSProc sleep_condition_variable;
98
typedef VOID (WINAPI* WakeAllConditionVariableProc)
99
(PCONDITION_VARIABLE ConditionVariable);
100
static WakeAllConditionVariableProc wake_all_condition_variable;
102
typedef VOID (WINAPI* WakeConditionVariableProc)
103
(PCONDITION_VARIABLE ConditionVariable);
104
static WakeConditionVariableProc wake_condition_variable;
107
/*********************************************************//**
108
Initialitze condition variable */
113
os_cond_t* cond) /*!< in: condition variable. */
118
ut_a(initialize_condition_variable != NULL);
119
initialize_condition_variable(cond);
121
ut_a(pthread_cond_init(cond, NULL) == 0);
125
/*********************************************************//**
126
Wait on condition variable */
131
os_cond_t* cond, /*!< in: condition variable. */
132
os_fast_mutex_t* mutex) /*!< in: fast mutex */
138
ut_a(sleep_condition_variable != NULL);
139
ut_a(sleep_condition_variable(cond, mutex, INFINITE));
141
ut_a(pthread_cond_wait(cond, mutex) == 0);
145
/*********************************************************//**
146
Wakes all threads waiting for condition variable */
151
os_cond_t* cond) /*!< in: condition variable. */
156
ut_a(wake_all_condition_variable != NULL);
157
wake_all_condition_variable(cond);
159
ut_a(pthread_cond_broadcast(cond) == 0);
163
/*********************************************************//**
164
Wakes one thread waiting for condition variable */
169
os_cond_t* cond) /*!< in: condition variable. */
174
ut_a(wake_condition_variable != NULL);
175
wake_condition_variable(cond);
177
ut_a(pthread_cond_signal(cond) == 0);
181
/*********************************************************//**
182
Destroys condition variable */
187
os_cond_t* cond) /*!< in: condition variable. */
192
ut_a(pthread_cond_destroy(cond) == 0);
196
/*********************************************************//**
197
On Windows (Vista and later), load function pointers for condition variable
198
handling. Those functions are not available in prior versions, so we have to
199
use them via runtime loading, as long as we support XP. */
202
os_cond_module_init(void)
203
/*=====================*/
208
if (!srv_use_native_conditions)
211
h_dll = GetModuleHandle("kernel32");
213
initialize_condition_variable = (InitializeConditionVariableProc)
214
GetProcAddress(h_dll, "InitializeConditionVariable");
215
sleep_condition_variable = (SleepConditionVariableCSProc)
216
GetProcAddress(h_dll, "SleepConditionVariableCS");
217
wake_all_condition_variable = (WakeAllConditionVariableProc)
218
GetProcAddress(h_dll, "WakeAllConditionVariable");
219
wake_condition_variable = (WakeConditionVariableProc)
220
GetProcAddress(h_dll, "WakeConditionVariable");
222
/* When using native condition variables, check function pointers */
223
ut_a(initialize_condition_variable);
224
ut_a(sleep_condition_variable);
225
ut_a(wake_all_condition_variable);
226
ut_a(wake_condition_variable);
230
80
/*********************************************************//**
231
81
Initializes global event and OS 'slow' mutex lists. */
297
144
const char* name) /*!< in: the name of the event, if NULL
298
145
the event is created without a name */
303
if(!srv_use_native_conditions) {
305
event = ut_malloc(sizeof(struct os_event_struct));
307
event->handle = CreateEvent(NULL,
311
if (!event->handle) {
313
"InnoDB: Could not create a Windows event"
314
" semaphore; Windows error %lu\n",
315
(ulong) GetLastError());
317
} else /* Windows with condition variables */
323
event = ut_malloc(sizeof(struct os_event_struct));
325
os_fast_mutex_init(&(event->os_mutex));
327
os_cond_init(&(event->cond_var));
329
event->is_set = FALSE;
331
/* We return this value in os_event_reset(), which can then be
332
be used to pass to the os_event_wait_low(). The value of zero
333
is reserved in os_event_wait_low() for the case when the
334
caller does not want to pass any signal_count value. To
335
distinguish between the two cases we initialize signal_count
337
event->signal_count = 1;
150
event = ut_malloc(sizeof(struct os_event_struct));
152
event->handle = CreateEvent(NULL, /* No security attributes */
153
TRUE, /* Manual reset */
154
FALSE, /* Initial state nonsignaled */
156
if (!event->handle) {
158
"InnoDB: Could not create a Windows event semaphore;"
159
" Windows error %lu\n",
160
(ulong) GetLastError());
167
event = ut_malloc(sizeof(struct os_event_struct));
169
os_fast_mutex_init(&(event->os_mutex));
171
ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
173
event->is_set = FALSE;
175
/* We return this value in os_event_reset(), which can then be
176
be used to pass to the os_event_wait_low(). The value of zero
177
is reserved in os_event_wait_low() for the case when the
178
caller does not want to pass any signal_count value. To
179
distinguish between the two cases we initialize signal_count
181
event->signal_count = 1;
340
184
/* The os_sync_mutex can be NULL because during startup an event
341
185
can be created [ because it's embedded in the mutex/rwlock ] before
520
356
returned by previous call of
521
357
os_event_reset(). */
364
UT_NOT_USED(reset_sig_count);
366
/* Specify an infinite time limit for waiting */
367
err = WaitForSingleObject(event->handle, INFINITE);
369
ut_a(err == WAIT_OBJECT_0);
371
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
372
os_thread_exit(NULL);
523
375
ib_int64_t old_signal_count;
526
if(!srv_use_native_conditions) {
531
UT_NOT_USED(reset_sig_count);
533
/* Specify an infinite wait */
534
err = WaitForSingleObject(event->handle, INFINITE);
536
ut_a(err == WAIT_OBJECT_0);
538
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
539
os_thread_exit(NULL);
545
377
os_fast_mutex_lock(&(event->os_mutex));
547
379
if (reset_sig_count) {
568
os_cond_wait(&(event->cond_var), &(event->os_mutex));
400
pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
570
402
/* Solaris manual said that spurious wakeups may occur: we
571
403
have to check if the event really has been signaled after
572
404
we came here to wait */
409
/**********************************************************//**
410
Waits for an event object until it is in the signaled state or
411
a timeout is exceeded. In Unix the timeout is always infinite.
412
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
417
os_event_t event, /*!< in: event to wait */
418
ulint time) /*!< in: timeout in microseconds, or
419
OS_SYNC_INFINITE_TIME */
426
if (time != OS_SYNC_INFINITE_TIME) {
427
err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
429
err = WaitForSingleObject(event->handle, INFINITE);
432
if (err == WAIT_OBJECT_0) {
435
} else if (err == WAIT_TIMEOUT) {
437
return(OS_SYNC_TIME_EXCEEDED);
440
return(1000000); /* dummy value to eliminate compiler warn. */
445
/* In Posix this is just an ordinary, infinite wait */
447
os_event_wait(event);
454
/**********************************************************//**
455
Waits for any event in an OS native event array. Returns if even a single
456
one is signaled or becomes signaled.
457
@return index of the event which was signaled */
460
os_event_wait_multiple(
461
/*===================*/
462
ulint n, /*!< in: number of events in the
464
os_native_event_t* native_event_array)
465
/*!< in: pointer to an array of event
470
ut_a(native_event_array);
473
index = WaitForMultipleObjects((DWORD) n, native_event_array,
474
FALSE, /* Wait for any 1 event */
475
INFINITE); /* Infinite wait time
477
ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */
478
ut_a(index < WAIT_OBJECT_0 + n);
480
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
481
os_thread_exit(NULL);
484
return(index - WAIT_OBJECT_0);
576
488
/*********************************************************//**
577
489
Creates an operating system mutex semaphore. Because these are slow, the