~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/os/os0sync.c

  • Committer: Brian Aker
  • Date: 2010-12-18 10:14:05 UTC
  • mfrom: (2008.1.3 clean)
  • Revision ID: brian@tangent.org-20101218101405-qjbse29shi9coklg
Merge of user identifier work

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
 
36
36
#include "ut0mem.h"
37
37
#include "srv0start.h"
 
38
#include "srv0srv.h"
38
39
#include "ha_prototypes.h"
39
40
 
40
41
/* Type definition for an operating system mutex struct */
77
78
This version of the free event function doesn't acquire the global lock */
78
79
static void os_event_free_internal(os_event_t   event);
79
80
 
 
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);
 
85
 
 
86
#ifdef __WIN__
 
87
/* Prototypes and function pointers for condition variable functions */
 
88
typedef VOID (WINAPI* InitializeConditionVariableProc)
 
89
             (PCONDITION_VARIABLE ConditionVariable);
 
90
static InitializeConditionVariableProc initialize_condition_variable;
 
91
 
 
92
typedef BOOL (WINAPI* SleepConditionVariableCSProc)
 
93
             (PCONDITION_VARIABLE ConditionVariable,
 
94
              PCRITICAL_SECTION CriticalSection,
 
95
              DWORD dwMilliseconds);
 
96
static SleepConditionVariableCSProc sleep_condition_variable;
 
97
 
 
98
typedef VOID (WINAPI* WakeAllConditionVariableProc)
 
99
             (PCONDITION_VARIABLE ConditionVariable);
 
100
static WakeAllConditionVariableProc wake_all_condition_variable;
 
101
 
 
102
typedef VOID (WINAPI* WakeConditionVariableProc)
 
103
             (PCONDITION_VARIABLE ConditionVariable);
 
104
static WakeConditionVariableProc wake_condition_variable;
 
105
#endif
 
106
 
 
107
/*********************************************************//**
 
108
Initialitze condition variable */
 
109
UNIV_INLINE
 
110
void
 
111
os_cond_init(
 
112
/*=========*/
 
113
        os_cond_t*      cond)   /*!< in: condition variable. */
 
114
{
 
115
        ut_a(cond);
 
116
 
 
117
#ifdef __WIN__
 
118
        ut_a(initialize_condition_variable != NULL);
 
119
        initialize_condition_variable(cond);
 
120
#else
 
121
        ut_a(pthread_cond_init(cond, NULL) == 0);
 
122
#endif
 
123
}
 
124
 
 
125
/*********************************************************//**
 
126
Wait on condition variable */
 
127
UNIV_INLINE
 
128
void
 
129
os_cond_wait(
 
130
/*=========*/
 
131
        os_cond_t*              cond,   /*!< in: condition variable. */
 
132
        os_fast_mutex_t*        mutex)  /*!< in: fast mutex */
 
133
{
 
134
        ut_a(cond);
 
135
        ut_a(mutex);
 
136
 
 
137
#ifdef __WIN__
 
138
        ut_a(sleep_condition_variable != NULL);
 
139
        ut_a(sleep_condition_variable(cond, mutex, INFINITE));
 
140
#else
 
141
        ut_a(pthread_cond_wait(cond, mutex) == 0);
 
142
#endif
 
143
}
 
144
 
 
145
/*********************************************************//**
 
146
Wakes all threads  waiting for condition variable */
 
147
UNIV_INLINE
 
148
void
 
149
os_cond_broadcast(
 
150
/*==============*/
 
151
        os_cond_t*      cond)   /*!< in: condition variable. */
 
152
{
 
153
        ut_a(cond);
 
154
 
 
155
#ifdef __WIN__
 
156
        ut_a(wake_all_condition_variable != NULL);
 
157
        wake_all_condition_variable(cond);
 
158
#else
 
159
        ut_a(pthread_cond_broadcast(cond) == 0);
 
160
#endif
 
161
}
 
162
 
 
163
/*********************************************************//**
 
164
Wakes one thread waiting for condition variable */
 
165
UNIV_INLINE
 
166
void
 
167
os_cond_signal(
 
168
/*==========*/
 
169
        os_cond_t*      cond)   /*!< in: condition variable. */
 
170
{
 
171
        ut_a(cond);
 
172
 
 
173
#ifdef __WIN__
 
174
        ut_a(wake_condition_variable != NULL);
 
175
        wake_condition_variable(cond);
 
176
#else
 
177
        ut_a(pthread_cond_signal(cond) == 0);
 
178
#endif
 
179
}
 
180
 
 
181
/*********************************************************//**
 
182
Destroys condition variable */
 
183
UNIV_INLINE
 
184
void
 
185
os_cond_destroy(
 
186
/*============*/
 
187
        os_cond_t*      cond)   /*!< in: condition variable. */
 
188
{
 
189
#ifdef __WIN__
 
190
        /* Do nothing */
 
191
#else
 
192
        ut_a(pthread_cond_destroy(cond) == 0);
 
193
#endif
 
194
}
 
195
 
 
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. */
 
200
static
 
201
void
 
202
os_cond_module_init(void)
 
203
/*=====================*/
 
204
{
 
205
#ifdef __WIN__
 
206
        HMODULE         h_dll;
 
207
 
 
208
        if (!srv_use_native_conditions)
 
209
                return;
 
210
 
 
211
        h_dll = GetModuleHandle("kernel32");
 
212
 
 
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");
 
221
 
 
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);
 
227
#endif
 
228
}
 
229
 
80
230
/*********************************************************//**
81
231
Initializes global event and OS 'slow' mutex lists. */
82
232
UNIV_INTERN
90
240
        os_sync_mutex = NULL;
91
241
        os_sync_mutex_inited = FALSE;
92
242
 
93
 
        os_sync_mutex = os_mutex_create(NULL);
 
243
        /* Now for Windows only */
 
244
        os_cond_module_init();
 
245
 
 
246
        os_sync_mutex = os_mutex_create();
94
247
 
95
248
        os_sync_mutex_inited = TRUE;
96
249
}
144
297
        const char*     name)   /*!< in: the name of the event, if NULL
145
298
                                the event is created without a name */
146
299
{
 
300
        os_event_t      event;
 
301
 
147
302
#ifdef __WIN__
148
 
        os_event_t event;
149
 
 
150
 
        event = ut_malloc(sizeof(struct os_event_struct));
151
 
 
152
 
        event->handle = CreateEvent(NULL, /* No security attributes */
153
 
                                    TRUE, /* Manual reset */
154
 
                                    FALSE, /* Initial state nonsignaled */
155
 
                                    (LPCTSTR) name);
156
 
        if (!event->handle) {
157
 
                fprintf(stderr,
158
 
                        "InnoDB: Could not create a Windows event semaphore;"
159
 
                        " Windows error %lu\n",
160
 
                        (ulong) GetLastError());
 
303
        if(!srv_use_native_conditions) {
 
304
 
 
305
                event = ut_malloc(sizeof(struct os_event_struct));
 
306
 
 
307
                event->handle = CreateEvent(NULL,
 
308
                                            TRUE,
 
309
                                            FALSE,
 
310
                                            (LPCTSTR) name);
 
311
                if (!event->handle) {
 
312
                        fprintf(stderr,
 
313
                                "InnoDB: Could not create a Windows event"
 
314
                                " semaphore; Windows error %lu\n",
 
315
                                (ulong) GetLastError());
 
316
                }
 
317
        } else /* Windows with condition variables */
 
318
#endif
 
319
 
 
320
        {
 
321
                UT_NOT_USED(name);
 
322
 
 
323
                event = ut_malloc(sizeof(struct os_event_struct));
 
324
 
 
325
                os_fast_mutex_init(&(event->os_mutex));
 
326
 
 
327
                os_cond_init(&(event->cond_var));
 
328
 
 
329
                event->is_set = FALSE;
 
330
 
 
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
 
336
                to 1 here. */
 
337
                event->signal_count = 1;
161
338
        }
162
 
#else /* Unix */
163
 
        os_event_t      event;
164
 
 
165
 
        UT_NOT_USED(name);
166
 
 
167
 
        event = ut_malloc(sizeof(struct os_event_struct));
168
 
 
169
 
        os_fast_mutex_init(&(event->os_mutex));
170
 
 
171
 
        ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
172
 
 
173
 
        event->is_set = FALSE;
174
 
 
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
180
 
        to 1 here. */
181
 
        event->signal_count = 1;
182
 
#endif /* __WIN__ */
183
339
 
184
340
        /* The os_sync_mutex can be NULL because during startup an event
185
341
        can be created [ because it's embedded in the mutex/rwlock ] before
209
365
/*=========*/
210
366
        os_event_t      event)  /*!< in: event to set */
211
367
{
 
368
        ut_a(event);
 
369
 
212
370
#ifdef __WIN__
213
 
        ut_a(event);
214
 
        ut_a(SetEvent(event->handle));
215
 
#else
 
371
        if (!srv_use_native_conditions) {
 
372
                ut_a(SetEvent(event->handle));
 
373
                return;
 
374
        }
 
375
#endif
 
376
 
216
377
        ut_a(event);
217
378
 
218
379
        os_fast_mutex_lock(&(event->os_mutex));
222
383
        } else {
223
384
                event->is_set = TRUE;
224
385
                event->signal_count += 1;
225
 
                ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
 
386
                os_cond_broadcast(&(event->cond_var));
226
387
        }
227
388
 
228
389
        os_fast_mutex_unlock(&(event->os_mutex));
229
 
#endif
230
390
}
231
391
 
232
392
/**********************************************************//**
245
405
{
246
406
        ib_int64_t      ret = 0;
247
407
 
 
408
        ut_a(event);
 
409
 
248
410
#ifdef __WIN__
249
 
        ut_a(event);
250
 
 
251
 
        ut_a(ResetEvent(event->handle));
252
 
#else
253
 
        ut_a(event);
 
411
        if(!srv_use_native_conditions) {
 
412
                ut_a(ResetEvent(event->handle));
 
413
                return(0);
 
414
        }
 
415
#endif
254
416
 
255
417
        os_fast_mutex_lock(&(event->os_mutex));
256
418
 
262
424
        ret = event->signal_count;
263
425
 
264
426
        os_fast_mutex_unlock(&(event->os_mutex));
265
 
#endif
266
427
        return(ret);
267
428
}
268
429
 
275
436
        os_event_t      event)  /*!< in: event to free */
276
437
{
277
438
#ifdef __WIN__
278
 
        ut_a(event);
279
 
 
280
 
        ut_a(CloseHandle(event->handle));
281
 
#else
282
 
        ut_a(event);
283
 
 
284
 
        /* This is to avoid freeing the mutex twice */
285
 
        os_fast_mutex_free(&(event->os_mutex));
286
 
 
287
 
        ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
 
439
        if(!srv_use_native_conditions) {
 
440
                ut_a(event);
 
441
                ut_a(CloseHandle(event->handle));
 
442
        } else
288
443
#endif
 
444
        {
 
445
                ut_a(event);
 
446
 
 
447
                /* This is to avoid freeing the mutex twice */
 
448
                os_fast_mutex_free(&(event->os_mutex));
 
449
 
 
450
                os_cond_destroy(&(event->cond_var));
 
451
        }
 
452
 
289
453
        /* Remove from the list of events */
290
 
 
291
454
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
292
455
 
293
456
        os_event_count--;
304
467
        os_event_t      event)  /*!< in: event to free */
305
468
 
306
469
{
 
470
        ut_a(event);
307
471
#ifdef __WIN__
308
 
        ut_a(event);
309
 
 
310
 
        ut_a(CloseHandle(event->handle));
311
 
#else
312
 
        ut_a(event);
313
 
 
314
 
        os_fast_mutex_free(&(event->os_mutex));
315
 
        ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
 
472
        if(!srv_use_native_conditions){
 
473
                ut_a(CloseHandle(event->handle));
 
474
        } else /*Windows with condition variables */
316
475
#endif
 
476
        {
 
477
                os_fast_mutex_free(&(event->os_mutex));
 
478
 
 
479
                os_cond_destroy(&(event->cond_var));
 
480
        }
 
481
 
317
482
        /* Remove from the list of events */
318
 
 
319
483
        os_mutex_enter(os_sync_mutex);
320
484
 
321
485
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
356
520
                                        returned by previous call of
357
521
                                        os_event_reset(). */
358
522
{
359
 
#ifdef __WIN__
360
 
        DWORD   err;
361
 
 
362
 
        ut_a(event);
363
 
 
364
 
        UT_NOT_USED(reset_sig_count);
365
 
 
366
 
        /* Specify an infinite time limit for waiting */
367
 
        err = WaitForSingleObject(event->handle, INFINITE);
368
 
 
369
 
        ut_a(err == WAIT_OBJECT_0);
370
 
 
371
 
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
372
 
                os_thread_exit(NULL);
373
 
        }
374
 
#else
375
523
        ib_int64_t      old_signal_count;
376
524
 
 
525
#ifdef __WIN__
 
526
        if(!srv_use_native_conditions) {
 
527
                DWORD   err;
 
528
 
 
529
                ut_a(event);
 
530
 
 
531
                UT_NOT_USED(reset_sig_count);
 
532
 
 
533
                /* Specify an infinite wait */
 
534
                err = WaitForSingleObject(event->handle, INFINITE);
 
535
 
 
536
                ut_a(err == WAIT_OBJECT_0);
 
537
 
 
538
                if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
 
539
                        os_thread_exit(NULL);
 
540
                }
 
541
                return;
 
542
        }
 
543
#endif
 
544
 
377
545
        os_fast_mutex_lock(&(event->os_mutex));
378
546
 
379
547
        if (reset_sig_count) {
397
565
                        return;
398
566
                }
399
567
 
400
 
                pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
 
568
                os_cond_wait(&(event->cond_var), &(event->os_mutex));
401
569
 
402
570
                /* Solaris manual said that spurious wakeups may occur: we
403
571
                have to check if the event really has been signaled after
404
572
                we came here to wait */
405
573
        }
406
 
#endif
407
 
}
408
 
 
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 */
413
 
UNIV_INTERN
414
 
ulint
415
 
os_event_wait_time(
416
 
/*===============*/
417
 
        os_event_t      event,  /*!< in: event to wait */
418
 
        ulint           time)   /*!< in: timeout in microseconds, or
419
 
                                OS_SYNC_INFINITE_TIME */
420
 
{
421
 
#ifdef __WIN__
422
 
        DWORD   err;
423
 
 
424
 
        ut_a(event);
425
 
 
426
 
        if (time != OS_SYNC_INFINITE_TIME) {
427
 
                err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
428
 
        } else {
429
 
                err = WaitForSingleObject(event->handle, INFINITE);
430
 
        }
431
 
 
432
 
        if (err == WAIT_OBJECT_0) {
433
 
 
434
 
                return(0);
435
 
        } else if (err == WAIT_TIMEOUT) {
436
 
 
437
 
                return(OS_SYNC_TIME_EXCEEDED);
438
 
        } else {
439
 
                ut_error;
440
 
                return(1000000); /* dummy value to eliminate compiler warn. */
441
 
        }
442
 
#else
443
 
        UT_NOT_USED(time);
444
 
 
445
 
        /* In Posix this is just an ordinary, infinite wait */
446
 
 
447
 
        os_event_wait(event);
448
 
 
449
 
        return(0);
450
 
#endif
451
 
}
452
 
 
453
 
#ifdef __WIN__
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 */
458
 
UNIV_INTERN
459
 
ulint
460
 
os_event_wait_multiple(
461
 
/*===================*/
462
 
        ulint                   n,      /*!< in: number of events in the
463
 
                                        array */
464
 
        os_native_event_t*      native_event_array)
465
 
                                        /*!< in: pointer to an array of event
466
 
                                        handles */
467
 
{
468
 
        DWORD   index;
469
 
 
470
 
        ut_a(native_event_array);
471
 
        ut_a(n > 0);
472
 
 
473
 
        index = WaitForMultipleObjects((DWORD) n, native_event_array,
474
 
                                       FALSE,      /* Wait for any 1 event */
475
 
                                       INFINITE); /* Infinite wait time
476
 
                                                  limit */
477
 
        ut_a(index >= WAIT_OBJECT_0);   /* NOTE: Pointless comparison */
478
 
        ut_a(index < WAIT_OBJECT_0 + n);
479
 
 
480
 
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
481
 
                os_thread_exit(NULL);
482
 
        }
483
 
 
484
 
        return(index - WAIT_OBJECT_0);
485
 
}
486
 
#endif
 
574
}
487
575
 
488
576
/*********************************************************//**
489
577
Creates an operating system mutex semaphore. Because these are slow, the
491
579
@return the mutex handle */
492
580
UNIV_INTERN
493
581
os_mutex_t
494
 
os_mutex_create(
495
 
/*============*/
496
 
        const char*     name)   /*!< in: the name of the mutex, if NULL
497
 
                                the mutex is created without a name */
 
582
os_mutex_create(void)
 
583
/*=================*/
498
584
{
499
 
#ifdef __WIN__
500
 
        HANDLE          mutex;
501
 
        os_mutex_t      mutex_str;
502
 
 
503
 
        mutex = CreateMutex(NULL,       /* No security attributes */
504
 
                            FALSE,              /* Initial state: no owner */
505
 
                            (LPCTSTR) name);
506
 
        ut_a(mutex);
507
 
#else
508
585
        os_fast_mutex_t*        mutex;
509
586
        os_mutex_t              mutex_str;
510
587
 
511
 
        UT_NOT_USED(name);
512
 
 
513
588
        mutex = ut_malloc(sizeof(os_fast_mutex_t));
514
589
 
515
590
        os_fast_mutex_init(mutex);
516
 
#endif
517
591
        mutex_str = ut_malloc(sizeof(os_mutex_str_t));
518
592
 
519
593
        mutex_str->handle = mutex;
544
618
/*===========*/
545
619
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
546
620
{
547
 
#ifdef __WIN__
548
 
        DWORD   err;
549
 
 
550
 
        ut_a(mutex);
551
 
 
552
 
        /* Specify infinite time limit for waiting */
553
 
        err = WaitForSingleObject(mutex->handle, INFINITE);
554
 
 
555
 
        ut_a(err == WAIT_OBJECT_0);
556
 
 
557
 
        (mutex->count)++;
558
 
        ut_a(mutex->count == 1);
559
 
#else
560
621
        os_fast_mutex_lock(mutex->handle);
561
622
 
562
623
        (mutex->count)++;
563
624
 
564
625
        ut_a(mutex->count == 1);
565
 
#endif
566
626
}
567
627
 
568
628
/**********************************************************//**
578
638
        ut_a(mutex->count == 1);
579
639
 
580
640
        (mutex->count)--;
581
 
#ifdef __WIN__
582
 
        ut_a(ReleaseMutex(mutex->handle));
583
 
#else
584
641
        os_fast_mutex_unlock(mutex->handle);
585
 
#endif
586
642
}
587
643
 
588
644
/**********************************************************//**
611
667
                os_mutex_exit(os_sync_mutex);
612
668
        }
613
669
 
614
 
#ifdef __WIN__
615
 
        ut_a(CloseHandle(mutex->handle));
616
 
 
617
 
        ut_free(mutex);
618
 
#else
619
670
        os_fast_mutex_free(mutex->handle);
620
671
        ut_free(mutex->handle);
621
672
        ut_free(mutex);
622
 
#endif
623
673
}
624
674
 
625
675
/*********************************************************//**