~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2010-06-19 16:36:52 UTC
  • mto: This revision was merged to the branch mainline in revision 1628.
  • Revision ID: mordred@inaugust.com-20100619163652-6fej38011wsop52k
Moved password parsing code into get_password.cc.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
12
 
13
13
You should have received a copy of the GNU General Public License along with
14
 
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
 
St, Fifth Floor, Boston, MA 02110-1301 USA
 
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
 
15
Place, Suite 330, Boston, MA 02111-1307 USA
16
16
 
17
17
*****************************************************************************/
18
18
 
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
237
87
        UT_LIST_INIT(os_event_list);
238
88
        UT_LIST_INIT(os_mutex_list);
239
89
 
240
 
        os_sync_mutex = NULL;
241
 
        os_sync_mutex_inited = FALSE;
242
 
 
243
 
        /* Now for Windows only */
244
 
        os_cond_module_init();
245
 
 
246
 
        os_sync_mutex = os_mutex_create();
 
90
        os_sync_mutex = os_mutex_create(NULL);
247
91
 
248
92
        os_sync_mutex_inited = TRUE;
249
93
}
297
141
        const char*     name)   /*!< in: the name of the event, if NULL
298
142
                                the event is created without a name */
299
143
{
300
 
        os_event_t      event;
301
 
 
302
144
#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;
 
145
        os_event_t event;
 
146
 
 
147
        event = ut_malloc(sizeof(struct os_event_struct));
 
148
 
 
149
        event->handle = CreateEvent(NULL, /* No security attributes */
 
150
                                    TRUE, /* Manual reset */
 
151
                                    FALSE, /* Initial state nonsignaled */
 
152
                                    (LPCTSTR) name);
 
153
        if (!event->handle) {
 
154
                fprintf(stderr,
 
155
                        "InnoDB: Could not create a Windows event semaphore;"
 
156
                        " Windows error %lu\n",
 
157
                        (ulong) GetLastError());
338
158
        }
 
159
#else /* Unix */
 
160
        os_event_t      event;
 
161
 
 
162
        UT_NOT_USED(name);
 
163
 
 
164
        event = ut_malloc(sizeof(struct os_event_struct));
 
165
 
 
166
        os_fast_mutex_init(&(event->os_mutex));
 
167
 
 
168
        ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
 
169
 
 
170
        event->is_set = FALSE;
 
171
 
 
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
 
177
        to 1 here. */
 
178
        event->signal_count = 1;
 
179
#endif /* __WIN__ */
339
180
 
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
365
206
/*=========*/
366
207
        os_event_t      event)  /*!< in: event to set */
367
208
{
368
 
        ut_a(event);
369
 
 
370
209
#ifdef __WIN__
371
 
        if (!srv_use_native_conditions) {
372
 
                ut_a(SetEvent(event->handle));
373
 
                return;
374
 
        }
375
 
#endif
376
 
 
 
210
        ut_a(event);
 
211
        ut_a(SetEvent(event->handle));
 
212
#else
377
213
        ut_a(event);
378
214
 
379
215
        os_fast_mutex_lock(&(event->os_mutex));
383
219
        } else {
384
220
                event->is_set = TRUE;
385
221
                event->signal_count += 1;
386
 
                os_cond_broadcast(&(event->cond_var));
 
222
                ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
387
223
        }
388
224
 
389
225
        os_fast_mutex_unlock(&(event->os_mutex));
 
226
#endif
390
227
}
391
228
 
392
229
/**********************************************************//**
405
242
{
406
243
        ib_int64_t      ret = 0;
407
244
 
408
 
        ut_a(event);
409
 
 
410
245
#ifdef __WIN__
411
 
        if(!srv_use_native_conditions) {
412
 
                ut_a(ResetEvent(event->handle));
413
 
                return(0);
414
 
        }
415
 
#endif
 
246
        ut_a(event);
 
247
 
 
248
        ut_a(ResetEvent(event->handle));
 
249
#else
 
250
        ut_a(event);
416
251
 
417
252
        os_fast_mutex_lock(&(event->os_mutex));
418
253
 
424
259
        ret = event->signal_count;
425
260
 
426
261
        os_fast_mutex_unlock(&(event->os_mutex));
 
262
#endif
427
263
        return(ret);
428
264
}
429
265
 
436
272
        os_event_t      event)  /*!< in: event to free */
437
273
{
438
274
#ifdef __WIN__
439
 
        if(!srv_use_native_conditions) {
440
 
                ut_a(event);
441
 
                ut_a(CloseHandle(event->handle));
442
 
        } else
 
275
        ut_a(event);
 
276
 
 
277
        ut_a(CloseHandle(event->handle));
 
278
#else
 
279
        ut_a(event);
 
280
 
 
281
        /* This is to avoid freeing the mutex twice */
 
282
        os_fast_mutex_free(&(event->os_mutex));
 
283
 
 
284
        ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
443
285
#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
286
        /* Remove from the list of events */
 
287
 
454
288
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
455
289
 
456
290
        os_event_count--;
467
301
        os_event_t      event)  /*!< in: event to free */
468
302
 
469
303
{
470
 
        ut_a(event);
471
304
#ifdef __WIN__
472
 
        if(!srv_use_native_conditions){
473
 
                ut_a(CloseHandle(event->handle));
474
 
        } else /*Windows with condition variables */
 
305
        ut_a(event);
 
306
 
 
307
        ut_a(CloseHandle(event->handle));
 
308
#else
 
309
        ut_a(event);
 
310
 
 
311
        os_fast_mutex_free(&(event->os_mutex));
 
312
        ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
475
313
#endif
476
 
        {
477
 
                os_fast_mutex_free(&(event->os_mutex));
478
 
 
479
 
                os_cond_destroy(&(event->cond_var));
480
 
        }
481
 
 
482
314
        /* Remove from the list of events */
 
315
 
483
316
        os_mutex_enter(os_sync_mutex);
484
317
 
485
318
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
520
353
                                        returned by previous call of
521
354
                                        os_event_reset(). */
522
355
{
 
356
#ifdef __WIN__
 
357
        DWORD   err;
 
358
 
 
359
        ut_a(event);
 
360
 
 
361
        UT_NOT_USED(reset_sig_count);
 
362
 
 
363
        /* Specify an infinite time limit for waiting */
 
364
        err = WaitForSingleObject(event->handle, INFINITE);
 
365
 
 
366
        ut_a(err == WAIT_OBJECT_0);
 
367
 
 
368
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
 
369
                os_thread_exit(NULL);
 
370
        }
 
371
#else
523
372
        ib_int64_t      old_signal_count;
524
373
 
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
374
        os_fast_mutex_lock(&(event->os_mutex));
546
375
 
547
376
        if (reset_sig_count) {
565
394
                        return;
566
395
                }
567
396
 
568
 
                os_cond_wait(&(event->cond_var), &(event->os_mutex));
 
397
                pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
569
398
 
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 */
573
402
        }
574
 
}
 
403
#endif
 
404
}
 
405
 
 
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 */
 
410
UNIV_INTERN
 
411
ulint
 
412
os_event_wait_time(
 
413
/*===============*/
 
414
        os_event_t      event,  /*!< in: event to wait */
 
415
        ulint           time)   /*!< in: timeout in microseconds, or
 
416
                                OS_SYNC_INFINITE_TIME */
 
417
{
 
418
#ifdef __WIN__
 
419
        DWORD   err;
 
420
 
 
421
        ut_a(event);
 
422
 
 
423
        if (time != OS_SYNC_INFINITE_TIME) {
 
424
                err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
 
425
        } else {
 
426
                err = WaitForSingleObject(event->handle, INFINITE);
 
427
        }
 
428
 
 
429
        if (err == WAIT_OBJECT_0) {
 
430
 
 
431
                return(0);
 
432
        } else if (err == WAIT_TIMEOUT) {
 
433
 
 
434
                return(OS_SYNC_TIME_EXCEEDED);
 
435
        } else {
 
436
                ut_error;
 
437
                return(1000000); /* dummy value to eliminate compiler warn. */
 
438
        }
 
439
#else
 
440
        UT_NOT_USED(time);
 
441
 
 
442
        /* In Posix this is just an ordinary, infinite wait */
 
443
 
 
444
        os_event_wait(event);
 
445
 
 
446
        return(0);
 
447
#endif
 
448
}
 
449
 
 
450
#ifdef __WIN__
 
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 */
 
455
UNIV_INTERN
 
456
ulint
 
457
os_event_wait_multiple(
 
458
/*===================*/
 
459
        ulint                   n,      /*!< in: number of events in the
 
460
                                        array */
 
461
        os_native_event_t*      native_event_array)
 
462
                                        /*!< in: pointer to an array of event
 
463
                                        handles */
 
464
{
 
465
        DWORD   index;
 
466
 
 
467
        ut_a(native_event_array);
 
468
        ut_a(n > 0);
 
469
 
 
470
        index = WaitForMultipleObjects((DWORD) n, native_event_array,
 
471
                                       FALSE,      /* Wait for any 1 event */
 
472
                                       INFINITE); /* Infinite wait time
 
473
                                                  limit */
 
474
        ut_a(index >= WAIT_OBJECT_0);   /* NOTE: Pointless comparison */
 
475
        ut_a(index < WAIT_OBJECT_0 + n);
 
476
 
 
477
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
 
478
                os_thread_exit(NULL);
 
479
        }
 
480
 
 
481
        return(index - WAIT_OBJECT_0);
 
482
}
 
483
#endif
575
484
 
576
485
/*********************************************************//**
577
486
Creates an operating system mutex semaphore. Because these are slow, the
579
488
@return the mutex handle */
580
489
UNIV_INTERN
581
490
os_mutex_t
582
 
os_mutex_create(void)
583
 
/*=================*/
 
491
os_mutex_create(
 
492
/*============*/
 
493
        const char*     name)   /*!< in: the name of the mutex, if NULL
 
494
                                the mutex is created without a name */
584
495
{
 
496
#ifdef __WIN__
 
497
        HANDLE          mutex;
 
498
        os_mutex_t      mutex_str;
 
499
 
 
500
        mutex = CreateMutex(NULL,       /* No security attributes */
 
501
                            FALSE,              /* Initial state: no owner */
 
502
                            (LPCTSTR) name);
 
503
        ut_a(mutex);
 
504
#else
585
505
        os_fast_mutex_t*        mutex;
586
506
        os_mutex_t              mutex_str;
587
507
 
 
508
        UT_NOT_USED(name);
 
509
 
588
510
        mutex = ut_malloc(sizeof(os_fast_mutex_t));
589
511
 
590
512
        os_fast_mutex_init(mutex);
 
513
#endif
591
514
        mutex_str = ut_malloc(sizeof(os_mutex_str_t));
592
515
 
593
516
        mutex_str->handle = mutex;
618
541
/*===========*/
619
542
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
620
543
{
 
544
#ifdef __WIN__
 
545
        DWORD   err;
 
546
 
 
547
        ut_a(mutex);
 
548
 
 
549
        /* Specify infinite time limit for waiting */
 
550
        err = WaitForSingleObject(mutex->handle, INFINITE);
 
551
 
 
552
        ut_a(err == WAIT_OBJECT_0);
 
553
 
 
554
        (mutex->count)++;
 
555
        ut_a(mutex->count == 1);
 
556
#else
621
557
        os_fast_mutex_lock(mutex->handle);
622
558
 
623
559
        (mutex->count)++;
624
560
 
625
561
        ut_a(mutex->count == 1);
 
562
#endif
626
563
}
627
564
 
628
565
/**********************************************************//**
638
575
        ut_a(mutex->count == 1);
639
576
 
640
577
        (mutex->count)--;
 
578
#ifdef __WIN__
 
579
        ut_a(ReleaseMutex(mutex->handle));
 
580
#else
641
581
        os_fast_mutex_unlock(mutex->handle);
 
582
#endif
642
583
}
643
584
 
644
585
/**********************************************************//**
667
608
                os_mutex_exit(os_sync_mutex);
668
609
        }
669
610
 
 
611
#ifdef __WIN__
 
612
        ut_a(CloseHandle(mutex->handle));
 
613
 
 
614
        ut_free(mutex);
 
615
#else
670
616
        os_fast_mutex_free(mutex->handle);
671
617
        ut_free(mutex->handle);
672
618
        ut_free(mutex);
 
619
#endif
673
620
}
674
621
 
675
622
/*********************************************************//**
767
714
                os_mutex_enter(os_sync_mutex);
768
715
        }
769
716
 
770
 
        ut_ad(os_fast_mutex_count > 0);
771
717
        os_fast_mutex_count--;
772
718
 
773
719
        if (UNIV_LIKELY(os_sync_mutex_inited)) {