~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: lbieber
  • Date: 2010-10-01 13:06:31 UTC
  • mfrom: (1802.2.2 drizzle-bug-651948)
  • mto: This revision was merged to the branch mainline in revision 1805.
  • Revision ID: lbieber@orisndriz08-20101001130631-xubscnhmj7r5dn6g
Merge Andrew - Fix bug 651948 - Index lengths not retrieved using drizzledump

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
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
 
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
307
87
        UT_LIST_INIT(os_event_list);
308
88
        UT_LIST_INIT(os_mutex_list);
309
89
 
310
 
        os_sync_mutex = NULL;
311
 
        os_sync_mutex_inited = FALSE;
312
 
 
313
 
        /* Now for Windows only */
314
 
        os_cond_module_init();
315
 
 
316
 
        os_sync_mutex = os_mutex_create();
 
90
        os_sync_mutex = os_mutex_create(NULL);
317
91
 
318
92
        os_sync_mutex_inited = TRUE;
319
93
}
367
141
        const char*     name)   /*!< in: the name of the event, if NULL
368
142
                                the event is created without a name */
369
143
{
370
 
        os_event_t      event;
371
 
 
372
144
#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;
 
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());
408
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__ */
409
180
 
410
181
        /* The os_sync_mutex can be NULL because during startup an event
411
182
        can be created [ because it's embedded in the mutex/rwlock ] before
435
206
/*=========*/
436
207
        os_event_t      event)  /*!< in: event to set */
437
208
{
438
 
        ut_a(event);
439
 
 
440
209
#ifdef __WIN__
441
 
        if (!srv_use_native_conditions) {
442
 
                ut_a(SetEvent(event->handle));
443
 
                return;
444
 
        }
445
 
#endif
446
 
 
 
210
        ut_a(event);
 
211
        ut_a(SetEvent(event->handle));
 
212
#else
447
213
        ut_a(event);
448
214
 
449
215
        os_fast_mutex_lock(&(event->os_mutex));
453
219
        } else {
454
220
                event->is_set = TRUE;
455
221
                event->signal_count += 1;
456
 
                os_cond_broadcast(&(event->cond_var));
 
222
                ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
457
223
        }
458
224
 
459
225
        os_fast_mutex_unlock(&(event->os_mutex));
 
226
#endif
460
227
}
461
228
 
462
229
/**********************************************************//**
475
242
{
476
243
        ib_int64_t      ret = 0;
477
244
 
478
 
        ut_a(event);
479
 
 
480
245
#ifdef __WIN__
481
 
        if(!srv_use_native_conditions) {
482
 
                ut_a(ResetEvent(event->handle));
483
 
                return(0);
484
 
        }
485
 
#endif
 
246
        ut_a(event);
 
247
 
 
248
        ut_a(ResetEvent(event->handle));
 
249
#else
 
250
        ut_a(event);
486
251
 
487
252
        os_fast_mutex_lock(&(event->os_mutex));
488
253
 
494
259
        ret = event->signal_count;
495
260
 
496
261
        os_fast_mutex_unlock(&(event->os_mutex));
 
262
#endif
497
263
        return(ret);
498
264
}
499
265
 
506
272
        os_event_t      event)  /*!< in: event to free */
507
273
{
508
274
#ifdef __WIN__
509
 
        if(!srv_use_native_conditions) {
510
 
                ut_a(event);
511
 
                ut_a(CloseHandle(event->handle));
512
 
        } 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)));
513
285
#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
286
        /* Remove from the list of events */
 
287
 
524
288
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
525
289
 
526
290
        os_event_count--;
537
301
        os_event_t      event)  /*!< in: event to free */
538
302
 
539
303
{
540
 
        ut_a(event);
541
304
#ifdef __WIN__
542
 
        if(!srv_use_native_conditions){
543
 
                ut_a(CloseHandle(event->handle));
544
 
        } 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)));
545
313
#endif
546
 
        {
547
 
                os_fast_mutex_free(&(event->os_mutex));
548
 
 
549
 
                os_cond_destroy(&(event->cond_var));
550
 
        }
551
 
 
552
314
        /* Remove from the list of events */
 
315
 
553
316
        os_mutex_enter(os_sync_mutex);
554
317
 
555
318
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
590
353
                                        returned by previous call of
591
354
                                        os_event_reset(). */
592
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
593
372
        ib_int64_t      old_signal_count;
594
373
 
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
374
        os_fast_mutex_lock(&(event->os_mutex));
616
375
 
617
376
        if (reset_sig_count) {
635
394
                        return;
636
395
                }
637
396
 
638
 
                os_cond_wait(&(event->cond_var), &(event->os_mutex));
 
397
                pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
639
398
 
640
399
                /* Solaris manual said that spurious wakeups may occur: we
641
400
                have to check if the event really has been signaled after
642
401
                we came here to wait */
643
402
        }
 
403
#endif
644
404
}
645
405
 
646
406
/**********************************************************//**
647
407
Waits for an event object until it is in the signaled state or
648
 
a timeout is exceeded.
 
408
a timeout is exceeded. In Unix the timeout is always infinite.
649
409
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
650
410
UNIV_INTERN
651
411
ulint
652
 
os_event_wait_time_low(
 
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(
653
458
/*===================*/
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
 
 
 
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 */
662
464
{
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);
 
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);
759
476
 
760
477
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
761
 
 
762
478
                os_thread_exit(NULL);
763
479
        }
764
480
 
765
 
        return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0);
 
481
        return(index - WAIT_OBJECT_0);
766
482
}
 
483
#endif
767
484
 
768
485
/*********************************************************//**
769
486
Creates an operating system mutex semaphore. Because these are slow, the
771
488
@return the mutex handle */
772
489
UNIV_INTERN
773
490
os_mutex_t
774
 
os_mutex_create(void)
775
 
/*=================*/
 
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 */
776
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
777
505
        os_fast_mutex_t*        mutex;
778
506
        os_mutex_t              mutex_str;
779
507
 
780
 
        mutex = static_cast<os_fast_mutex_t*>(ut_malloc(sizeof(os_fast_mutex_t)));
 
508
        UT_NOT_USED(name);
 
509
 
 
510
        mutex = ut_malloc(sizeof(os_fast_mutex_t));
781
511
 
782
512
        os_fast_mutex_init(mutex);
783
 
        mutex_str = static_cast<os_mutex_t>(ut_malloc(sizeof(os_mutex_str_t)));
 
513
#endif
 
514
        mutex_str = ut_malloc(sizeof(os_mutex_str_t));
784
515
 
785
516
        mutex_str->handle = mutex;
786
517
        mutex_str->count = 0;
810
541
/*===========*/
811
542
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
812
543
{
813
 
        os_fast_mutex_lock(static_cast<os_fast_mutex_t *>(mutex->handle));
814
 
 
815
 
        (mutex->count)++;
816
 
 
817
 
        ut_a(mutex->count == 1);
 
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
 
557
        os_fast_mutex_lock(mutex->handle);
 
558
 
 
559
        (mutex->count)++;
 
560
 
 
561
        ut_a(mutex->count == 1);
 
562
#endif
818
563
}
819
564
 
820
565
/**********************************************************//**
830
575
        ut_a(mutex->count == 1);
831
576
 
832
577
        (mutex->count)--;
833
 
        os_fast_mutex_unlock(static_cast<os_fast_mutex_t *>(mutex->handle));
 
578
#ifdef __WIN__
 
579
        ut_a(ReleaseMutex(mutex->handle));
 
580
#else
 
581
        os_fast_mutex_unlock(mutex->handle);
 
582
#endif
834
583
}
835
584
 
836
585
/**********************************************************//**
859
608
                os_mutex_exit(os_sync_mutex);
860
609
        }
861
610
 
862
 
        os_fast_mutex_free(static_cast<os_fast_mutex_t *>(mutex->handle));
 
611
#ifdef __WIN__
 
612
        ut_a(CloseHandle(mutex->handle));
 
613
 
 
614
        ut_free(mutex);
 
615
#else
 
616
        os_fast_mutex_free(mutex->handle);
863
617
        ut_free(mutex->handle);
864
618
        ut_free(mutex);
 
619
#endif
865
620
}
866
621
 
867
622
/*********************************************************//**
877
632
 
878
633
        InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
879
634
#else
880
 
        ut_a(0 == pthread_mutex_init(fast_mutex, NULL));
 
635
        ut_a(0 == innobase_fast_mutex_init(fast_mutex));
881
636
#endif
882
637
        if (UNIV_LIKELY(os_sync_mutex_inited)) {
883
638
                /* When creating os_sync_mutex itself (in Unix) we cannot
959
714
                os_mutex_enter(os_sync_mutex);
960
715
        }
961
716
 
962
 
        ut_ad(os_fast_mutex_count > 0);
963
717
        os_fast_mutex_count--;
964
718
 
965
719
        if (UNIV_LIKELY(os_sync_mutex_inited)) {