~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: tdavies
  • Date: 2010-10-15 05:42:42 UTC
  • mto: (1849.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1850.
  • Revision ID: tdavies@molly-20101015054242-pwurc94i9m0w1guh
File:drizzled/internal/my_static.h; Converted struct 'st_irem' to c++ class and renamed it 'irem'. Also added constructor, and made the changed name consistant in my_static.cc

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"
39
38
#include "ha_prototypes.h"
40
39
 
41
40
/* Type definition for an operating system mutex struct */
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);
80
79
 
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
 
 
230
80
/*********************************************************//**
231
81
Initializes global event and OS 'slow' mutex lists. */
232
82
UNIV_INTERN
240
90
        os_sync_mutex = NULL;
241
91
        os_sync_mutex_inited = FALSE;
242
92
 
243
 
        /* Now for Windows only */
244
 
        os_cond_module_init();
245
 
 
246
 
        os_sync_mutex = os_mutex_create();
 
93
        os_sync_mutex = os_mutex_create(NULL);
247
94
 
248
95
        os_sync_mutex_inited = TRUE;
249
96
}
297
144
        const char*     name)   /*!< in: the name of the event, if NULL
298
145
                                the event is created without a name */
299
146
{
300
 
        os_event_t      event;
301
 
 
302
147
#ifdef __WIN__
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;
 
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());
338
161
        }
 
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__ */
339
183
 
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
365
209
/*=========*/
366
210
        os_event_t      event)  /*!< in: event to set */
367
211
{
368
 
        ut_a(event);
369
 
 
370
212
#ifdef __WIN__
371
 
        if (!srv_use_native_conditions) {
372
 
                ut_a(SetEvent(event->handle));
373
 
                return;
374
 
        }
375
 
#endif
376
 
 
 
213
        ut_a(event);
 
214
        ut_a(SetEvent(event->handle));
 
215
#else
377
216
        ut_a(event);
378
217
 
379
218
        os_fast_mutex_lock(&(event->os_mutex));
383
222
        } else {
384
223
                event->is_set = TRUE;
385
224
                event->signal_count += 1;
386
 
                os_cond_broadcast(&(event->cond_var));
 
225
                ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
387
226
        }
388
227
 
389
228
        os_fast_mutex_unlock(&(event->os_mutex));
 
229
#endif
390
230
}
391
231
 
392
232
/**********************************************************//**
405
245
{
406
246
        ib_int64_t      ret = 0;
407
247
 
408
 
        ut_a(event);
409
 
 
410
248
#ifdef __WIN__
411
 
        if(!srv_use_native_conditions) {
412
 
                ut_a(ResetEvent(event->handle));
413
 
                return(0);
414
 
        }
415
 
#endif
 
249
        ut_a(event);
 
250
 
 
251
        ut_a(ResetEvent(event->handle));
 
252
#else
 
253
        ut_a(event);
416
254
 
417
255
        os_fast_mutex_lock(&(event->os_mutex));
418
256
 
424
262
        ret = event->signal_count;
425
263
 
426
264
        os_fast_mutex_unlock(&(event->os_mutex));
 
265
#endif
427
266
        return(ret);
428
267
}
429
268
 
436
275
        os_event_t      event)  /*!< in: event to free */
437
276
{
438
277
#ifdef __WIN__
439
 
        if(!srv_use_native_conditions) {
440
 
                ut_a(event);
441
 
                ut_a(CloseHandle(event->handle));
442
 
        } else
 
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)));
443
288
#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
 
 
453
289
        /* Remove from the list of events */
 
290
 
454
291
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
455
292
 
456
293
        os_event_count--;
467
304
        os_event_t      event)  /*!< in: event to free */
468
305
 
469
306
{
470
 
        ut_a(event);
471
307
#ifdef __WIN__
472
 
        if(!srv_use_native_conditions){
473
 
                ut_a(CloseHandle(event->handle));
474
 
        } else /*Windows with condition variables */
 
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)));
475
316
#endif
476
 
        {
477
 
                os_fast_mutex_free(&(event->os_mutex));
478
 
 
479
 
                os_cond_destroy(&(event->cond_var));
480
 
        }
481
 
 
482
317
        /* Remove from the list of events */
 
318
 
483
319
        os_mutex_enter(os_sync_mutex);
484
320
 
485
321
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
520
356
                                        returned by previous call of
521
357
                                        os_event_reset(). */
522
358
{
 
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
523
375
        ib_int64_t      old_signal_count;
524
376
 
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
 
 
545
377
        os_fast_mutex_lock(&(event->os_mutex));
546
378
 
547
379
        if (reset_sig_count) {
565
397
                        return;
566
398
                }
567
399
 
568
 
                os_cond_wait(&(event->cond_var), &(event->os_mutex));
 
400
                pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
569
401
 
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 */
573
405
        }
574
 
}
 
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
575
487
 
576
488
/*********************************************************//**
577
489
Creates an operating system mutex semaphore. Because these are slow, the
579
491
@return the mutex handle */
580
492
UNIV_INTERN
581
493
os_mutex_t
582
 
os_mutex_create(void)
583
 
/*=================*/
 
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 */
584
498
{
 
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
585
508
        os_fast_mutex_t*        mutex;
586
509
        os_mutex_t              mutex_str;
587
510
 
 
511
        UT_NOT_USED(name);
 
512
 
588
513
        mutex = ut_malloc(sizeof(os_fast_mutex_t));
589
514
 
590
515
        os_fast_mutex_init(mutex);
 
516
#endif
591
517
        mutex_str = ut_malloc(sizeof(os_mutex_str_t));
592
518
 
593
519
        mutex_str->handle = mutex;
618
544
/*===========*/
619
545
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
620
546
{
 
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
621
560
        os_fast_mutex_lock(mutex->handle);
622
561
 
623
562
        (mutex->count)++;
624
563
 
625
564
        ut_a(mutex->count == 1);
 
565
#endif
626
566
}
627
567
 
628
568
/**********************************************************//**
638
578
        ut_a(mutex->count == 1);
639
579
 
640
580
        (mutex->count)--;
 
581
#ifdef __WIN__
 
582
        ut_a(ReleaseMutex(mutex->handle));
 
583
#else
641
584
        os_fast_mutex_unlock(mutex->handle);
 
585
#endif
642
586
}
643
587
 
644
588
/**********************************************************//**
667
611
                os_mutex_exit(os_sync_mutex);
668
612
        }
669
613
 
 
614
#ifdef __WIN__
 
615
        ut_a(CloseHandle(mutex->handle));
 
616
 
 
617
        ut_free(mutex);
 
618
#else
670
619
        os_fast_mutex_free(mutex->handle);
671
620
        ut_free(mutex->handle);
672
621
        ut_free(mutex);
 
622
#endif
673
623
}
674
624
 
675
625
/*********************************************************//**