~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Lee Bieber
  • Date: 2010-11-14 23:15:42 UTC
  • mfrom: (1929.1.42 warning-stack-frame)
  • Revision ID: kalebral@gmail.com-20101114231542-fnnu6ydd2p17n582
Merge Monty - fix bug 672372: some functions use > 32k stack

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1995, 2009, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
23
23
 
24
24
Created 9/6/1995 Heikki Tuuri
25
25
*******************************************************/
26
 
#include "univ.i"
27
 
 
28
 
#include <errno.h>
29
26
 
30
27
#include "os0sync.h"
31
28
#ifdef UNIV_NONINL
38
35
 
39
36
#include "ut0mem.h"
40
37
#include "srv0start.h"
41
 
#include "srv0srv.h"
42
38
#include "ha_prototypes.h"
43
39
 
44
40
/* Type definition for an operating system mutex struct */
76
72
UNIV_INTERN ulint       os_mutex_count          = 0;
77
73
UNIV_INTERN ulint       os_fast_mutex_count     = 0;
78
74
 
79
 
/* The number of microsecnds in a second. */
80
 
static const ulint MICROSECS_IN_A_SECOND = 1000000;
81
 
 
82
75
/* Because a mutex is embedded inside an event and there is an
83
76
event embedded inside a mutex, on free, this generates a recursive call.
84
77
This version of the free event function doesn't acquire the global lock */
85
78
static void os_event_free_internal(os_event_t   event);
86
79
 
87
 
/* On Windows (Vista and later), load function pointers for condition
88
 
variable handling. Those functions are not available in prior versions,
89
 
so we have to use them via runtime loading, as long as we support XP. */
90
 
static void os_cond_module_init(void);
91
 
 
92
 
#ifdef __WIN__
93
 
/* Prototypes and function pointers for condition variable functions */
94
 
typedef VOID (WINAPI* InitializeConditionVariableProc)
95
 
             (PCONDITION_VARIABLE ConditionVariable);
96
 
static InitializeConditionVariableProc initialize_condition_variable;
97
 
 
98
 
typedef BOOL (WINAPI* SleepConditionVariableCSProc)
99
 
             (PCONDITION_VARIABLE ConditionVariable,
100
 
              PCRITICAL_SECTION CriticalSection,
101
 
              DWORD dwMilliseconds);
102
 
static SleepConditionVariableCSProc sleep_condition_variable;
103
 
 
104
 
typedef VOID (WINAPI* WakeAllConditionVariableProc)
105
 
             (PCONDITION_VARIABLE ConditionVariable);
106
 
static WakeAllConditionVariableProc wake_all_condition_variable;
107
 
 
108
 
typedef VOID (WINAPI* WakeConditionVariableProc)
109
 
             (PCONDITION_VARIABLE ConditionVariable);
110
 
static WakeConditionVariableProc wake_condition_variable;
111
 
#endif
112
 
 
113
 
/*********************************************************//**
114
 
Initialitze condition variable */
115
 
UNIV_INLINE
116
 
void
117
 
os_cond_init(
118
 
/*=========*/
119
 
        os_cond_t*      cond)   /*!< in: condition variable. */
120
 
{
121
 
        ut_a(cond);
122
 
 
123
 
#ifdef __WIN__
124
 
        ut_a(initialize_condition_variable != NULL);
125
 
        initialize_condition_variable(cond);
126
 
#else
127
 
        ut_a(pthread_cond_init(cond, NULL) == 0);
128
 
#endif
129
 
}
130
 
 
131
 
/*********************************************************//**
132
 
Do a timed wait on condition variable.
133
 
@return TRUE if timed out, FALSE otherwise */
134
 
UNIV_INLINE
135
 
ibool
136
 
os_cond_wait_timed(
137
 
/*===============*/
138
 
        os_cond_t*              cond,           /*!< in: condition variable. */
139
 
        os_fast_mutex_t*        mutex,          /*!< in: fast mutex */
140
 
#ifndef __WIN__
141
 
        const struct timespec*  abstime         /*!< in: timeout */
142
 
#else
143
 
        DWORD                   time_in_ms      /*!< in: timeout in
144
 
                                                milliseconds*/
145
 
#endif /* !__WIN__ */
146
 
)
147
 
{
148
 
#ifdef __WIN__
149
 
        BOOL    ret;
150
 
        DWORD   err;
151
 
 
152
 
        ut_a(sleep_condition_variable != NULL);
153
 
 
154
 
        ret = sleep_condition_variable(cond, mutex, time_in_ms);
155
 
 
156
 
        if (!ret) {
157
 
                err = GetLastError();
158
 
                /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx,
159
 
                "Condition variables are subject to spurious wakeups
160
 
                (those not associated with an explicit wake) and stolen wakeups
161
 
                (another thread manages to run before the woken thread)."
162
 
                Check for both types of timeouts.
163
 
                Conditions are checked by the caller.*/
164
 
                if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
165
 
                        return(TRUE);
166
 
                }
167
 
        }
168
 
 
169
 
        ut_a(ret);
170
 
 
171
 
        return(FALSE);
172
 
#else
173
 
        int     ret;
174
 
 
175
 
        ret = pthread_cond_timedwait(cond, mutex, abstime);
176
 
 
177
 
        switch (ret) {
178
 
        case 0:
179
 
        case ETIMEDOUT:
180
 
        /* We play it safe by checking for EINTR even though
181
 
        according to the POSIX documentation it can't return EINTR. */
182
 
        case EINTR:
183
 
                break;
184
 
 
185
 
        default:
186
 
                fprintf(stderr, "  InnoDB: pthread_cond_timedwait() returned: "
187
 
                                "%d: abstime={%lu,%lu}\n",
188
 
                                ret, (ulong) abstime->tv_sec, (ulong) abstime->tv_nsec);
189
 
                ut_error;
190
 
        }
191
 
 
192
 
        return(ret == ETIMEDOUT);
193
 
#endif
194
 
}
195
 
/*********************************************************//**
196
 
Wait on condition variable */
197
 
UNIV_INLINE
198
 
void
199
 
os_cond_wait(
200
 
/*=========*/
201
 
        os_cond_t*              cond,   /*!< in: condition variable. */
202
 
        os_fast_mutex_t*        mutex)  /*!< in: fast mutex */
203
 
{
204
 
        ut_a(cond);
205
 
        ut_a(mutex);
206
 
 
207
 
#ifdef __WIN__
208
 
        ut_a(sleep_condition_variable != NULL);
209
 
        ut_a(sleep_condition_variable(cond, mutex, INFINITE));
210
 
#else
211
 
        ut_a(pthread_cond_wait(cond, mutex) == 0);
212
 
#endif
213
 
}
214
 
 
215
 
/*********************************************************//**
216
 
Wakes all threads  waiting for condition variable */
217
 
UNIV_INLINE
218
 
void
219
 
os_cond_broadcast(
220
 
/*==============*/
221
 
        os_cond_t*      cond)   /*!< in: condition variable. */
222
 
{
223
 
        ut_a(cond);
224
 
 
225
 
#ifdef __WIN__
226
 
        ut_a(wake_all_condition_variable != NULL);
227
 
        wake_all_condition_variable(cond);
228
 
#else
229
 
        ut_a(pthread_cond_broadcast(cond) == 0);
230
 
#endif
231
 
}
232
 
 
233
 
/*********************************************************//**
234
 
Wakes one thread waiting for condition variable */
235
 
UNIV_INLINE
236
 
void
237
 
os_cond_signal(
238
 
/*==========*/
239
 
        os_cond_t*      cond)   /*!< in: condition variable. */
240
 
{
241
 
        ut_a(cond);
242
 
 
243
 
#ifdef __WIN__
244
 
        ut_a(wake_condition_variable != NULL);
245
 
        wake_condition_variable(cond);
246
 
#else
247
 
        ut_a(pthread_cond_signal(cond) == 0);
248
 
#endif
249
 
}
250
 
 
251
 
/*********************************************************//**
252
 
Destroys condition variable */
253
 
UNIV_INLINE
254
 
void
255
 
os_cond_destroy(
256
 
/*============*/
257
 
        os_cond_t*      cond)   /*!< in: condition variable. */
258
 
{
259
 
#ifdef __WIN__
260
 
        /* Do nothing */
261
 
#else
262
 
        ut_a(pthread_cond_destroy(cond) == 0);
263
 
#endif
264
 
}
265
 
 
266
 
/*********************************************************//**
267
 
On Windows (Vista and later), load function pointers for condition variable
268
 
handling. Those functions are not available in prior versions, so we have to
269
 
use them via runtime loading, as long as we support XP. */
270
 
static
271
 
void
272
 
os_cond_module_init(void)
273
 
/*=====================*/
274
 
{
275
 
#ifdef __WIN__
276
 
        HMODULE         h_dll;
277
 
 
278
 
        if (!srv_use_native_conditions)
279
 
                return;
280
 
 
281
 
        h_dll = GetModuleHandle("kernel32");
282
 
 
283
 
        initialize_condition_variable = (InitializeConditionVariableProc)
284
 
                         GetProcAddress(h_dll, "InitializeConditionVariable");
285
 
        sleep_condition_variable = (SleepConditionVariableCSProc)
286
 
                          GetProcAddress(h_dll, "SleepConditionVariableCS");
287
 
        wake_all_condition_variable = (WakeAllConditionVariableProc)
288
 
                             GetProcAddress(h_dll, "WakeAllConditionVariable");
289
 
        wake_condition_variable = (WakeConditionVariableProc)
290
 
                         GetProcAddress(h_dll, "WakeConditionVariable");
291
 
 
292
 
        /* When using native condition variables, check function pointers */
293
 
        ut_a(initialize_condition_variable);
294
 
        ut_a(sleep_condition_variable);
295
 
        ut_a(wake_all_condition_variable);
296
 
        ut_a(wake_condition_variable);
297
 
#endif
298
 
}
299
 
 
300
80
/*********************************************************//**
301
81
Initializes global event and OS 'slow' mutex lists. */
302
82
UNIV_INTERN
310
90
        os_sync_mutex = NULL;
311
91
        os_sync_mutex_inited = FALSE;
312
92
 
313
 
        /* Now for Windows only */
314
 
        os_cond_module_init();
315
 
 
316
 
        os_sync_mutex = os_mutex_create();
 
93
        os_sync_mutex = os_mutex_create(NULL);
317
94
 
318
95
        os_sync_mutex_inited = TRUE;
319
96
}
367
144
        const char*     name)   /*!< in: the name of the event, if NULL
368
145
                                the event is created without a name */
369
146
{
370
 
        os_event_t      event;
371
 
 
372
147
#ifdef __WIN__
373
 
        if(!srv_use_native_conditions) {
374
 
 
375
 
                event = ut_malloc(sizeof(struct os_event_struct));
376
 
 
377
 
                event->handle = CreateEvent(NULL,
378
 
                                            TRUE,
379
 
                                            FALSE,
380
 
                                            (LPCTSTR) name);
381
 
                if (!event->handle) {
382
 
                        fprintf(stderr,
383
 
                                "InnoDB: Could not create a Windows event"
384
 
                                " semaphore; Windows error %lu\n",
385
 
                                (ulong) GetLastError());
386
 
                }
387
 
        } else /* Windows with condition variables */
388
 
#endif
389
 
 
390
 
        {
391
 
                UT_NOT_USED(name);
392
 
 
393
 
                event = static_cast<os_event_struct*>(ut_malloc(sizeof(struct os_event_struct)));
394
 
 
395
 
                os_fast_mutex_init(&(event->os_mutex));
396
 
 
397
 
                os_cond_init(&(event->cond_var));
398
 
 
399
 
                event->is_set = FALSE;
400
 
 
401
 
                /* We return this value in os_event_reset(), which can then be
402
 
                be used to pass to the os_event_wait_low(). The value of zero
403
 
                is reserved in os_event_wait_low() for the case when the
404
 
                caller does not want to pass any signal_count value. To
405
 
                distinguish between the two cases we initialize signal_count
406
 
                to 1 here. */
407
 
                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());
408
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__ */
409
183
 
410
184
        /* The os_sync_mutex can be NULL because during startup an event
411
185
        can be created [ because it's embedded in the mutex/rwlock ] before
435
209
/*=========*/
436
210
        os_event_t      event)  /*!< in: event to set */
437
211
{
438
 
        ut_a(event);
439
 
 
440
212
#ifdef __WIN__
441
 
        if (!srv_use_native_conditions) {
442
 
                ut_a(SetEvent(event->handle));
443
 
                return;
444
 
        }
445
 
#endif
446
 
 
 
213
        ut_a(event);
 
214
        ut_a(SetEvent(event->handle));
 
215
#else
447
216
        ut_a(event);
448
217
 
449
218
        os_fast_mutex_lock(&(event->os_mutex));
453
222
        } else {
454
223
                event->is_set = TRUE;
455
224
                event->signal_count += 1;
456
 
                os_cond_broadcast(&(event->cond_var));
 
225
                ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
457
226
        }
458
227
 
459
228
        os_fast_mutex_unlock(&(event->os_mutex));
 
229
#endif
460
230
}
461
231
 
462
232
/**********************************************************//**
475
245
{
476
246
        ib_int64_t      ret = 0;
477
247
 
478
 
        ut_a(event);
479
 
 
480
248
#ifdef __WIN__
481
 
        if(!srv_use_native_conditions) {
482
 
                ut_a(ResetEvent(event->handle));
483
 
                return(0);
484
 
        }
485
 
#endif
 
249
        ut_a(event);
 
250
 
 
251
        ut_a(ResetEvent(event->handle));
 
252
#else
 
253
        ut_a(event);
486
254
 
487
255
        os_fast_mutex_lock(&(event->os_mutex));
488
256
 
494
262
        ret = event->signal_count;
495
263
 
496
264
        os_fast_mutex_unlock(&(event->os_mutex));
 
265
#endif
497
266
        return(ret);
498
267
}
499
268
 
506
275
        os_event_t      event)  /*!< in: event to free */
507
276
{
508
277
#ifdef __WIN__
509
 
        if(!srv_use_native_conditions) {
510
 
                ut_a(event);
511
 
                ut_a(CloseHandle(event->handle));
512
 
        } 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)));
513
288
#endif
514
 
        {
515
 
                ut_a(event);
516
 
 
517
 
                /* This is to avoid freeing the mutex twice */
518
 
                os_fast_mutex_free(&(event->os_mutex));
519
 
 
520
 
                os_cond_destroy(&(event->cond_var));
521
 
        }
522
 
 
523
289
        /* Remove from the list of events */
 
290
 
524
291
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
525
292
 
526
293
        os_event_count--;
537
304
        os_event_t      event)  /*!< in: event to free */
538
305
 
539
306
{
540
 
        ut_a(event);
541
307
#ifdef __WIN__
542
 
        if(!srv_use_native_conditions){
543
 
                ut_a(CloseHandle(event->handle));
544
 
        } 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)));
545
316
#endif
546
 
        {
547
 
                os_fast_mutex_free(&(event->os_mutex));
548
 
 
549
 
                os_cond_destroy(&(event->cond_var));
550
 
        }
551
 
 
552
317
        /* Remove from the list of events */
 
318
 
553
319
        os_mutex_enter(os_sync_mutex);
554
320
 
555
321
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
590
356
                                        returned by previous call of
591
357
                                        os_event_reset(). */
592
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
593
375
        ib_int64_t      old_signal_count;
594
376
 
595
 
#ifdef __WIN__
596
 
        if(!srv_use_native_conditions) {
597
 
                DWORD   err;
598
 
 
599
 
                ut_a(event);
600
 
 
601
 
                UT_NOT_USED(reset_sig_count);
602
 
 
603
 
                /* Specify an infinite wait */
604
 
                err = WaitForSingleObject(event->handle, INFINITE);
605
 
 
606
 
                ut_a(err == WAIT_OBJECT_0);
607
 
 
608
 
                if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
609
 
                        os_thread_exit(NULL);
610
 
                }
611
 
                return;
612
 
        }
613
 
#endif
614
 
 
615
377
        os_fast_mutex_lock(&(event->os_mutex));
616
378
 
617
379
        if (reset_sig_count) {
635
397
                        return;
636
398
                }
637
399
 
638
 
                os_cond_wait(&(event->cond_var), &(event->os_mutex));
 
400
                pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
639
401
 
640
402
                /* Solaris manual said that spurious wakeups may occur: we
641
403
                have to check if the event really has been signaled after
642
404
                we came here to wait */
643
405
        }
 
406
#endif
644
407
}
645
408
 
646
409
/**********************************************************//**
647
410
Waits for an event object until it is in the signaled state or
648
 
a timeout is exceeded.
 
411
a timeout is exceeded. In Unix the timeout is always infinite.
649
412
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
650
413
UNIV_INTERN
651
414
ulint
652
 
os_event_wait_time_low(
 
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(
653
461
/*===================*/
654
 
        os_event_t      event,                  /*!< in: event to wait */
655
 
        ulint           time_in_usec,           /*!< in: timeout in
656
 
                                                microseconds, or
657
 
                                                OS_SYNC_INFINITE_TIME */
658
 
        ib_int64_t      reset_sig_count)        /*!< in: zero or the value
659
 
                                                returned by previous call of
660
 
                                                os_event_reset(). */
661
 
 
 
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 */
662
467
{
663
 
        ibool           timed_out = FALSE;
664
 
        ib_int64_t      old_signal_count;
665
 
 
666
 
#ifdef __WIN__
667
 
        DWORD           time_in_ms;
668
 
 
669
 
        if (!srv_use_native_conditions) {
670
 
                DWORD   err;
671
 
 
672
 
                ut_a(event);
673
 
 
674
 
                if (time_in_usec != OS_SYNC_INFINITE_TIME) {
675
 
                        time_in_ms = time_in_usec / 1000;
676
 
                        err = WaitForSingleObject(event->handle, time_in_ms);
677
 
                } else {
678
 
                        err = WaitForSingleObject(event->handle, INFINITE);
679
 
                }
680
 
 
681
 
                if (err == WAIT_OBJECT_0) {
682
 
                        return(0);
683
 
                } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) {
684
 
                        return(OS_SYNC_TIME_EXCEEDED);
685
 
                }
686
 
 
687
 
                ut_error;
688
 
                /* Dummy value to eliminate compiler warning. */
689
 
                return(42);
690
 
        } else {
691
 
                ut_a(sleep_condition_variable != NULL);
692
 
 
693
 
                if (time_in_usec != OS_SYNC_INFINITE_TIME) {
694
 
                        time_in_ms = time_in_usec / 1000;
695
 
                } else {
696
 
                        time_in_ms = INFINITE;
697
 
                }
698
 
        }
699
 
#else
700
 
        struct timespec abstime;
701
 
 
702
 
        if (time_in_usec != OS_SYNC_INFINITE_TIME) {
703
 
                struct timeval  tv;
704
 
                int             ret;
705
 
                ulint           sec;
706
 
                ulint           usec;
707
 
 
708
 
                ret = ut_usectime(&sec, &usec);
709
 
                ut_a(ret == 0);
710
 
 
711
 
                tv.tv_sec = sec;
712
 
                tv.tv_usec = usec;
713
 
 
714
 
                tv.tv_usec += time_in_usec;
715
 
 
716
 
                if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) {
717
 
                        tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND;
718
 
                        tv.tv_usec %= MICROSECS_IN_A_SECOND;
719
 
                }
720
 
 
721
 
                abstime.tv_sec  = tv.tv_sec;
722
 
                abstime.tv_nsec = tv.tv_usec * 1000;
723
 
        } else {
724
 
                abstime.tv_nsec = 999999999;
725
 
                abstime.tv_sec = (time_t) ULINT_MAX;
726
 
        }
727
 
 
728
 
        ut_a(abstime.tv_nsec <= 999999999);
729
 
 
730
 
#endif /* __WIN__ */
731
 
 
732
 
        os_fast_mutex_lock(&event->os_mutex);
733
 
 
734
 
        if (reset_sig_count) {
735
 
                old_signal_count = reset_sig_count;
736
 
        } else {
737
 
                old_signal_count = event->signal_count;
738
 
        }
739
 
 
740
 
        do {
741
 
                if (event->is_set == TRUE
742
 
                    || event->signal_count != old_signal_count) {
743
 
 
744
 
                        break;
745
 
                }
746
 
 
747
 
                timed_out = os_cond_wait_timed(
748
 
                        &event->cond_var, &event->os_mutex,
749
 
#ifndef __WIN__
750
 
                        &abstime
751
 
#else
752
 
                        time_in_ms
753
 
#endif /* !__WIN__ */
754
 
                );
755
 
 
756
 
        } while (!timed_out);
757
 
 
758
 
        os_fast_mutex_unlock(&event->os_mutex);
 
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);
759
479
 
760
480
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
761
 
 
762
481
                os_thread_exit(NULL);
763
482
        }
764
483
 
765
 
        return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
 
484
        return(index - WAIT_OBJECT_0);
766
485
}
 
486
#endif
767
487
 
768
488
/*********************************************************//**
769
489
Creates an operating system mutex semaphore. Because these are slow, the
771
491
@return the mutex handle */
772
492
UNIV_INTERN
773
493
os_mutex_t
774
 
os_mutex_create(void)
775
 
/*=================*/
 
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 */
776
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
777
508
        os_fast_mutex_t*        mutex;
778
509
        os_mutex_t              mutex_str;
779
510
 
780
 
        mutex = static_cast<os_fast_mutex_t*>(ut_malloc(sizeof(os_fast_mutex_t)));
 
511
        UT_NOT_USED(name);
 
512
 
 
513
        mutex = ut_malloc(sizeof(os_fast_mutex_t));
781
514
 
782
515
        os_fast_mutex_init(mutex);
783
 
        mutex_str = static_cast<os_mutex_t>(ut_malloc(sizeof(os_mutex_str_t)));
 
516
#endif
 
517
        mutex_str = ut_malloc(sizeof(os_mutex_str_t));
784
518
 
785
519
        mutex_str->handle = mutex;
786
520
        mutex_str->count = 0;
810
544
/*===========*/
811
545
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
812
546
{
813
 
        os_fast_mutex_lock(static_cast<os_fast_mutex_t *>(mutex->handle));
814
 
 
815
 
        (mutex->count)++;
816
 
 
817
 
        ut_a(mutex->count == 1);
 
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
        os_fast_mutex_lock(mutex->handle);
 
561
 
 
562
        (mutex->count)++;
 
563
 
 
564
        ut_a(mutex->count == 1);
 
565
#endif
818
566
}
819
567
 
820
568
/**********************************************************//**
830
578
        ut_a(mutex->count == 1);
831
579
 
832
580
        (mutex->count)--;
833
 
        os_fast_mutex_unlock(static_cast<os_fast_mutex_t *>(mutex->handle));
 
581
#ifdef __WIN__
 
582
        ut_a(ReleaseMutex(mutex->handle));
 
583
#else
 
584
        os_fast_mutex_unlock(mutex->handle);
 
585
#endif
834
586
}
835
587
 
836
588
/**********************************************************//**
859
611
                os_mutex_exit(os_sync_mutex);
860
612
        }
861
613
 
862
 
        os_fast_mutex_free(static_cast<os_fast_mutex_t *>(mutex->handle));
 
614
#ifdef __WIN__
 
615
        ut_a(CloseHandle(mutex->handle));
 
616
 
 
617
        ut_free(mutex);
 
618
#else
 
619
        os_fast_mutex_free(mutex->handle);
863
620
        ut_free(mutex->handle);
864
621
        ut_free(mutex);
 
622
#endif
865
623
}
866
624
 
867
625
/*********************************************************//**
877
635
 
878
636
        InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
879
637
#else
880
 
        ut_a(0 == pthread_mutex_init(fast_mutex, NULL));
 
638
        ut_a(0 == innobase_fast_mutex_init(fast_mutex));
881
639
#endif
882
640
        if (UNIV_LIKELY(os_sync_mutex_inited)) {
883
641
                /* When creating os_sync_mutex itself (in Unix) we cannot