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
141
const char* name) /*!< in: the name of the event, if NULL
298
142
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;
147
event = ut_malloc(sizeof(struct os_event_struct));
149
event->handle = CreateEvent(NULL, /* No security attributes */
150
TRUE, /* Manual reset */
151
FALSE, /* Initial state nonsignaled */
153
if (!event->handle) {
155
"InnoDB: Could not create a Windows event semaphore;"
156
" Windows error %lu\n",
157
(ulong) GetLastError());
164
event = ut_malloc(sizeof(struct os_event_struct));
166
os_fast_mutex_init(&(event->os_mutex));
168
ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
170
event->is_set = FALSE;
172
/* We return this value in os_event_reset(), which can then be
173
be used to pass to the os_event_wait_low(). The value of zero
174
is reserved in os_event_wait_low() for the case when the
175
caller does not want to pass any signal_count value. To
176
distinguish between the two cases we initialize signal_count
178
event->signal_count = 1;
340
181
/* The os_sync_mutex can be NULL because during startup an event
341
182
can be created [ because it's embedded in the mutex/rwlock ] before
520
353
returned by previous call of
521
354
os_event_reset(). */
361
UT_NOT_USED(reset_sig_count);
363
/* Specify an infinite time limit for waiting */
364
err = WaitForSingleObject(event->handle, INFINITE);
366
ut_a(err == WAIT_OBJECT_0);
368
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
369
os_thread_exit(NULL);
523
372
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
374
os_fast_mutex_lock(&(event->os_mutex));
547
376
if (reset_sig_count) {
568
os_cond_wait(&(event->cond_var), &(event->os_mutex));
397
pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
570
399
/* Solaris manual said that spurious wakeups may occur: we
571
400
have to check if the event really has been signaled after
572
401
we came here to wait */
406
/**********************************************************//**
407
Waits for an event object until it is in the signaled state or
408
a timeout is exceeded. In Unix the timeout is always infinite.
409
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
414
os_event_t event, /*!< in: event to wait */
415
ulint time) /*!< in: timeout in microseconds, or
416
OS_SYNC_INFINITE_TIME */
423
if (time != OS_SYNC_INFINITE_TIME) {
424
err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
426
err = WaitForSingleObject(event->handle, INFINITE);
429
if (err == WAIT_OBJECT_0) {
432
} else if (err == WAIT_TIMEOUT) {
434
return(OS_SYNC_TIME_EXCEEDED);
437
return(1000000); /* dummy value to eliminate compiler warn. */
442
/* In Posix this is just an ordinary, infinite wait */
444
os_event_wait(event);
451
/**********************************************************//**
452
Waits for any event in an OS native event array. Returns if even a single
453
one is signaled or becomes signaled.
454
@return index of the event which was signaled */
457
os_event_wait_multiple(
458
/*===================*/
459
ulint n, /*!< in: number of events in the
461
os_native_event_t* native_event_array)
462
/*!< in: pointer to an array of event
467
ut_a(native_event_array);
470
index = WaitForMultipleObjects((DWORD) n, native_event_array,
471
FALSE, /* Wait for any 1 event */
472
INFINITE); /* Infinite wait time
474
ut_a(index >= WAIT_OBJECT_0); /* NOTE: Pointless comparison */
475
ut_a(index < WAIT_OBJECT_0 + n);
477
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
478
os_thread_exit(NULL);
481
return(index - WAIT_OBJECT_0);
576
485
/*********************************************************//**
577
486
Creates an operating system mutex semaphore. Because these are slow, the