~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2008-12-23 07:19:26 UTC
  • Revision ID: brian@tangent.org-20081223071926-69z2ugpftfz1lfnm
Remove dead variables.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
 
 
5
 
This program is free software; you can redistribute it and/or modify it under
6
 
the terms of the GNU General Public License as published by the Free Software
7
 
Foundation; version 2 of the License.
8
 
 
9
 
This program is distributed in the hope that it will be useful, but WITHOUT
10
 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
 
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
 
 
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
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file os/os0sync.c
 
1
/******************************************************
21
2
The interface to the operating system
22
3
synchronization primitives.
23
4
 
 
5
(c) 1995 Innobase Oy
 
6
 
24
7
Created 9/6/1995 Heikki Tuuri
25
8
*******************************************************/
26
9
 
35
18
 
36
19
#include "ut0mem.h"
37
20
#include "srv0start.h"
38
 
#include "srv0srv.h"
39
 
#include "ha_prototypes.h"
40
21
 
41
22
/* Type definition for an operating system mutex struct */
42
23
struct os_mutex_struct{
43
 
        os_event_t      event;  /*!< Used by sync0arr.c for queing threads */
44
 
        void*           handle; /*!< OS handle to mutex */
45
 
        ulint           count;  /*!< we use this counter to check
 
24
        os_event_t      event;  /* Used by sync0arr.c for queing threads */
 
25
        void*           handle; /* OS handle to mutex */
 
26
        ulint           count;  /* we use this counter to check
46
27
                                that the same thread does not
47
28
                                recursively lock the mutex: we
48
29
                                do not assume that the OS mutex
52
33
                                /* list of all 'slow' OS mutexes created */
53
34
};
54
35
 
55
 
/** Mutex protecting counts and the lists of OS mutexes and events */
 
36
/* Mutex protecting counts and the lists of OS mutexes and events */
56
37
UNIV_INTERN os_mutex_t  os_sync_mutex;
57
 
/** TRUE if os_sync_mutex has been initialized */
58
38
static ibool            os_sync_mutex_inited    = FALSE;
59
 
/** TRUE when os_sync_free() is being executed */
60
39
static ibool            os_sync_free_called     = FALSE;
61
40
 
62
 
/** This is incremented by 1 in os_thread_create and decremented by 1 in
 
41
/* This is incremented by 1 in os_thread_create and decremented by 1 in
63
42
os_thread_exit */
64
43
UNIV_INTERN ulint       os_thread_count         = 0;
65
44
 
66
 
/** The list of all events created */
 
45
/* The list of all events created */
67
46
static UT_LIST_BASE_NODE_T(os_event_struct_t)   os_event_list;
68
47
 
69
 
/** The list of all OS 'slow' mutexes */
 
48
/* The list of all OS 'slow' mutexes */
70
49
static UT_LIST_BASE_NODE_T(os_mutex_str_t)      os_mutex_list;
71
50
 
72
51
UNIV_INTERN ulint       os_event_count          = 0;
78
57
This version of the free event function doesn't acquire the global lock */
79
58
static void os_event_free_internal(os_event_t   event);
80
59
 
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
 
/*********************************************************//**
 
60
/*************************************************************
231
61
Initializes global event and OS 'slow' mutex lists. */
232
62
UNIV_INTERN
233
63
void
237
67
        UT_LIST_INIT(os_event_list);
238
68
        UT_LIST_INIT(os_mutex_list);
239
69
 
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();
 
70
        os_sync_mutex = os_mutex_create(NULL);
247
71
 
248
72
        os_sync_mutex_inited = TRUE;
249
73
}
250
74
 
251
 
/*********************************************************//**
 
75
/*************************************************************
252
76
Frees created events and OS 'slow' mutexes. */
253
77
UNIV_INTERN
254
78
void
285
109
        os_sync_free_called = FALSE;
286
110
}
287
111
 
288
 
/*********************************************************//**
 
112
/*************************************************************
289
113
Creates an event semaphore, i.e., a semaphore which may just have two
290
114
states: signaled and nonsignaled. The created event is manual reset: it
291
 
must be reset explicitly by calling sync_os_reset_event.
292
 
@return the event handle */
 
115
must be reset explicitly by calling sync_os_reset_event. */
293
116
UNIV_INTERN
294
117
os_event_t
295
118
os_event_create(
296
119
/*============*/
297
 
        const char*     name)   /*!< in: the name of the event, if NULL
 
120
                                /* out: the event handle */
 
121
        const char*     name)   /* in: the name of the event, if NULL
298
122
                                the event is created without a name */
299
123
{
 
124
#ifdef __WIN__
 
125
        os_event_t event;
 
126
 
 
127
        event = ut_malloc(sizeof(struct os_event_struct));
 
128
 
 
129
        event->handle = CreateEvent(NULL, /* No security attributes */
 
130
                                    TRUE, /* Manual reset */
 
131
                                    FALSE, /* Initial state nonsignaled */
 
132
                                    (LPCTSTR) name);
 
133
        if (!event->handle) {
 
134
                fprintf(stderr,
 
135
                        "InnoDB: Could not create a Windows event semaphore;"
 
136
                        " Windows error %lu\n",
 
137
                        (ulong) GetLastError());
 
138
        }
 
139
#else /* Unix */
300
140
        os_event_t      event;
301
141
 
302
 
#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 */
 
142
        UT_NOT_USED(name);
 
143
 
 
144
        event = ut_malloc(sizeof(struct os_event_struct));
 
145
 
 
146
        os_fast_mutex_init(&(event->os_mutex));
 
147
 
 
148
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
 
149
        ut_a(0 == pthread_cond_init(&(event->cond_var),
 
150
                                    pthread_condattr_default));
 
151
#else
 
152
        ut_a(0 == pthread_cond_init(&(event->cond_var), NULL));
318
153
#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;
338
 
        }
 
154
        event->is_set = FALSE;
 
155
 
 
156
        /* We return this value in os_event_reset(), which can then be
 
157
        be used to pass to the os_event_wait_low(). The value of zero
 
158
        is reserved in os_event_wait_low() for the case when the
 
159
        caller does not want to pass any signal_count value. To
 
160
        distinguish between the two cases we initialize signal_count
 
161
        to 1 here. */
 
162
        event->signal_count = 1;
 
163
#endif /* __WIN__ */
339
164
 
340
165
        /* The os_sync_mutex can be NULL because during startup an event
341
166
        can be created [ because it's embedded in the mutex/rwlock ] before
356
181
        return(event);
357
182
}
358
183
 
359
 
/**********************************************************//**
 
184
#ifdef __WIN__
 
185
/*************************************************************
 
186
Creates an auto-reset event semaphore, i.e., an event which is automatically
 
187
reset when a single thread is released. Works only in Windows. */
 
188
UNIV_INTERN
 
189
os_event_t
 
190
os_event_create_auto(
 
191
/*=================*/
 
192
                                /* out: the event handle */
 
193
        const char*     name)   /* in: the name of the event, if NULL
 
194
                                the event is created without a name */
 
195
{
 
196
        os_event_t event;
 
197
 
 
198
        event = ut_malloc(sizeof(struct os_event_struct));
 
199
 
 
200
        event->handle = CreateEvent(NULL, /* No security attributes */
 
201
                                    FALSE, /* Auto-reset */
 
202
                                    FALSE, /* Initial state nonsignaled */
 
203
                                    (LPCTSTR) name);
 
204
 
 
205
        if (!event->handle) {
 
206
                fprintf(stderr,
 
207
                        "InnoDB: Could not create a Windows auto"
 
208
                        " event semaphore; Windows error %lu\n",
 
209
                        (ulong) GetLastError());
 
210
        }
 
211
 
 
212
        /* Put to the list of events */
 
213
        os_mutex_enter(os_sync_mutex);
 
214
 
 
215
        UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
 
216
 
 
217
        os_event_count++;
 
218
 
 
219
        os_mutex_exit(os_sync_mutex);
 
220
 
 
221
        return(event);
 
222
}
 
223
#endif
 
224
 
 
225
/**************************************************************
360
226
Sets an event semaphore to the signaled state: lets waiting threads
361
227
proceed. */
362
228
UNIV_INTERN
363
229
void
364
230
os_event_set(
365
231
/*=========*/
366
 
        os_event_t      event)  /*!< in: event to set */
 
232
        os_event_t      event)  /* in: event to set */
367
233
{
368
 
        ut_a(event);
369
 
 
370
234
#ifdef __WIN__
371
 
        if (!srv_use_native_conditions) {
372
 
                ut_a(SetEvent(event->handle));
373
 
                return;
374
 
        }
375
 
#endif
376
 
 
 
235
        ut_a(event);
 
236
        ut_a(SetEvent(event->handle));
 
237
#else
377
238
        ut_a(event);
378
239
 
379
240
        os_fast_mutex_lock(&(event->os_mutex));
383
244
        } else {
384
245
                event->is_set = TRUE;
385
246
                event->signal_count += 1;
386
 
                os_cond_broadcast(&(event->cond_var));
 
247
                ut_a(0 == pthread_cond_broadcast(&(event->cond_var)));
387
248
        }
388
249
 
389
250
        os_fast_mutex_unlock(&(event->os_mutex));
 
251
#endif
390
252
}
391
253
 
392
 
/**********************************************************//**
 
254
/**************************************************************
393
255
Resets an event semaphore to the nonsignaled state. Waiting threads will
394
256
stop to wait for the event.
395
257
The return value should be passed to os_even_wait_low() if it is desired
396
258
that this thread should not wait in case of an intervening call to
397
259
os_event_set() between this os_event_reset() and the
398
 
os_event_wait_low() call. See comments for os_event_wait_low().
399
 
@return current signal_count. */
 
260
os_event_wait_low() call. See comments for os_event_wait_low(). */
400
261
UNIV_INTERN
401
262
ib_int64_t
402
263
os_event_reset(
403
264
/*===========*/
404
 
        os_event_t      event)  /*!< in: event to reset */
 
265
                                /* out: current signal_count. */
 
266
        os_event_t      event)  /* in: event to reset */
405
267
{
406
268
        ib_int64_t      ret = 0;
407
269
 
408
 
        ut_a(event);
409
 
 
410
270
#ifdef __WIN__
411
 
        if(!srv_use_native_conditions) {
412
 
                ut_a(ResetEvent(event->handle));
413
 
                return(0);
414
 
        }
415
 
#endif
 
271
        ut_a(event);
 
272
 
 
273
        ut_a(ResetEvent(event->handle));
 
274
#else
 
275
        ut_a(event);
416
276
 
417
277
        os_fast_mutex_lock(&(event->os_mutex));
418
278
 
424
284
        ret = event->signal_count;
425
285
 
426
286
        os_fast_mutex_unlock(&(event->os_mutex));
 
287
#endif
427
288
        return(ret);
428
289
}
429
290
 
430
 
/**********************************************************//**
 
291
/**************************************************************
431
292
Frees an event object, without acquiring the global lock. */
432
293
static
433
294
void
434
295
os_event_free_internal(
435
296
/*===================*/
436
 
        os_event_t      event)  /*!< in: event to free */
 
297
        os_event_t      event)  /* in: event to free */
437
298
{
438
299
#ifdef __WIN__
439
 
        if(!srv_use_native_conditions) {
440
 
                ut_a(event);
441
 
                ut_a(CloseHandle(event->handle));
442
 
        } else
 
300
        ut_a(event);
 
301
 
 
302
        ut_a(CloseHandle(event->handle));
 
303
#else
 
304
        ut_a(event);
 
305
 
 
306
        /* This is to avoid freeing the mutex twice */
 
307
        os_fast_mutex_free(&(event->os_mutex));
 
308
 
 
309
        ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
443
310
#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
311
        /* Remove from the list of events */
 
312
 
454
313
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
455
314
 
456
315
        os_event_count--;
458
317
        ut_free(event);
459
318
}
460
319
 
461
 
/**********************************************************//**
 
320
/**************************************************************
462
321
Frees an event object. */
463
322
UNIV_INTERN
464
323
void
465
324
os_event_free(
466
325
/*==========*/
467
 
        os_event_t      event)  /*!< in: event to free */
 
326
        os_event_t      event)  /* in: event to free */
468
327
 
469
328
{
470
 
        ut_a(event);
471
329
#ifdef __WIN__
472
 
        if(!srv_use_native_conditions){
473
 
                ut_a(CloseHandle(event->handle));
474
 
        } else /*Windows with condition variables */
 
330
        ut_a(event);
 
331
 
 
332
        ut_a(CloseHandle(event->handle));
 
333
#else
 
334
        ut_a(event);
 
335
 
 
336
        os_fast_mutex_free(&(event->os_mutex));
 
337
        ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
475
338
#endif
476
 
        {
477
 
                os_fast_mutex_free(&(event->os_mutex));
478
 
 
479
 
                os_cond_destroy(&(event->cond_var));
480
 
        }
481
 
 
482
339
        /* Remove from the list of events */
 
340
 
483
341
        os_mutex_enter(os_sync_mutex);
484
342
 
485
343
        UT_LIST_REMOVE(os_event_list, os_event_list, event);
491
349
        ut_free(event);
492
350
}
493
351
 
494
 
/**********************************************************//**
 
352
/**************************************************************
495
353
Waits for an event object until it is in the signaled state. If
496
354
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
497
355
waiting thread when the event becomes signaled (or immediately if the
515
373
void
516
374
os_event_wait_low(
517
375
/*==============*/
518
 
        os_event_t      event,          /*!< in: event to wait */
519
 
        ib_int64_t      reset_sig_count)/*!< in: zero or the value
 
376
        os_event_t      event,          /* in: event to wait */
 
377
        ib_int64_t      reset_sig_count)/* in: zero or the value
520
378
                                        returned by previous call of
521
379
                                        os_event_reset(). */
522
380
{
 
381
#ifdef __WIN__
 
382
        DWORD   err;
 
383
 
 
384
        ut_a(event);
 
385
 
 
386
        UT_NOT_USED(reset_sig_count);
 
387
 
 
388
        /* Specify an infinite time limit for waiting */
 
389
        err = WaitForSingleObject(event->handle, INFINITE);
 
390
 
 
391
        ut_a(err == WAIT_OBJECT_0);
 
392
 
 
393
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
 
394
                os_thread_exit(NULL);
 
395
        }
 
396
#else
523
397
        ib_int64_t      old_signal_count;
524
398
 
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
399
        os_fast_mutex_lock(&(event->os_mutex));
546
400
 
547
401
        if (reset_sig_count) {
565
419
                        return;
566
420
                }
567
421
 
568
 
                os_cond_wait(&(event->cond_var), &(event->os_mutex));
 
422
                pthread_cond_wait(&(event->cond_var), &(event->os_mutex));
569
423
 
570
424
                /* Solaris manual said that spurious wakeups may occur: we
571
425
                have to check if the event really has been signaled after
572
426
                we came here to wait */
573
427
        }
574
 
}
575
 
 
576
 
/*********************************************************//**
 
428
#endif
 
429
}
 
430
 
 
431
/**************************************************************
 
432
Waits for an event object until it is in the signaled state or
 
433
a timeout is exceeded. In Unix the timeout is always infinite. */
 
434
UNIV_INTERN
 
435
ulint
 
436
os_event_wait_time(
 
437
/*===============*/
 
438
                                /* out: 0 if success, OS_SYNC_TIME_EXCEEDED if
 
439
                                timeout was exceeded */
 
440
        os_event_t      event,  /* in: event to wait */
 
441
        ulint           time)   /* in: timeout in microseconds, or
 
442
                                OS_SYNC_INFINITE_TIME */
 
443
{
 
444
#ifdef __WIN__
 
445
        DWORD   err;
 
446
 
 
447
        ut_a(event);
 
448
 
 
449
        if (time != OS_SYNC_INFINITE_TIME) {
 
450
                err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
 
451
        } else {
 
452
                err = WaitForSingleObject(event->handle, INFINITE);
 
453
        }
 
454
 
 
455
        if (err == WAIT_OBJECT_0) {
 
456
 
 
457
                return(0);
 
458
        } else if (err == WAIT_TIMEOUT) {
 
459
 
 
460
                return(OS_SYNC_TIME_EXCEEDED);
 
461
        } else {
 
462
                ut_error;
 
463
                return(1000000); /* dummy value to eliminate compiler warn. */
 
464
        }
 
465
#else
 
466
        UT_NOT_USED(time);
 
467
 
 
468
        /* In Posix this is just an ordinary, infinite wait */
 
469
 
 
470
        os_event_wait(event);
 
471
 
 
472
        return(0);
 
473
#endif
 
474
}
 
475
 
 
476
#ifdef __WIN__
 
477
/**************************************************************
 
478
Waits for any event in an OS native event array. Returns if even a single
 
479
one is signaled or becomes signaled. */
 
480
UNIV_INTERN
 
481
ulint
 
482
os_event_wait_multiple(
 
483
/*===================*/
 
484
                                        /* out: index of the event
 
485
                                        which was signaled */
 
486
        ulint                   n,      /* in: number of events in the
 
487
                                        array */
 
488
        os_native_event_t*      native_event_array)
 
489
                                        /* in: pointer to an array of event
 
490
                                        handles */
 
491
{
 
492
        DWORD   index;
 
493
 
 
494
        ut_a(native_event_array);
 
495
        ut_a(n > 0);
 
496
 
 
497
        index = WaitForMultipleObjects((DWORD) n, native_event_array,
 
498
                                       FALSE,      /* Wait for any 1 event */
 
499
                                       INFINITE); /* Infinite wait time
 
500
                                                  limit */
 
501
        ut_a(index >= WAIT_OBJECT_0);   /* NOTE: Pointless comparision */
 
502
        ut_a(index < WAIT_OBJECT_0 + n);
 
503
 
 
504
        if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
 
505
                os_thread_exit(NULL);
 
506
        }
 
507
 
 
508
        return(index - WAIT_OBJECT_0);
 
509
}
 
510
#endif
 
511
 
 
512
/*************************************************************
577
513
Creates an operating system mutex semaphore. Because these are slow, the
578
 
mutex semaphore of InnoDB itself (mutex_t) should be used where possible.
579
 
@return the mutex handle */
 
514
mutex semaphore of InnoDB itself (mutex_t) should be used where possible. */
580
515
UNIV_INTERN
581
516
os_mutex_t
582
 
os_mutex_create(void)
583
 
/*=================*/
 
517
os_mutex_create(
 
518
/*============*/
 
519
                                /* out: the mutex handle */
 
520
        const char*     name)   /* in: the name of the mutex, if NULL
 
521
                                the mutex is created without a name */
584
522
{
 
523
#ifdef __WIN__
 
524
        HANDLE          mutex;
 
525
        os_mutex_t      mutex_str;
 
526
 
 
527
        mutex = CreateMutex(NULL,       /* No security attributes */
 
528
                            FALSE,              /* Initial state: no owner */
 
529
                            (LPCTSTR) name);
 
530
        ut_a(mutex);
 
531
#else
585
532
        os_fast_mutex_t*        mutex;
586
533
        os_mutex_t              mutex_str;
587
534
 
 
535
        UT_NOT_USED(name);
 
536
 
588
537
        mutex = ut_malloc(sizeof(os_fast_mutex_t));
589
538
 
590
539
        os_fast_mutex_init(mutex);
 
540
#endif
591
541
        mutex_str = ut_malloc(sizeof(os_mutex_str_t));
592
542
 
593
543
        mutex_str->handle = mutex;
610
560
        return(mutex_str);
611
561
}
612
562
 
613
 
/**********************************************************//**
 
563
/**************************************************************
614
564
Acquires ownership of a mutex semaphore. */
615
565
UNIV_INTERN
616
566
void
617
567
os_mutex_enter(
618
568
/*===========*/
619
 
        os_mutex_t      mutex)  /*!< in: mutex to acquire */
 
569
        os_mutex_t      mutex)  /* in: mutex to acquire */
620
570
{
 
571
#ifdef __WIN__
 
572
        DWORD   err;
 
573
 
 
574
        ut_a(mutex);
 
575
 
 
576
        /* Specify infinite time limit for waiting */
 
577
        err = WaitForSingleObject(mutex->handle, INFINITE);
 
578
 
 
579
        ut_a(err == WAIT_OBJECT_0);
 
580
 
 
581
        (mutex->count)++;
 
582
        ut_a(mutex->count == 1);
 
583
#else
621
584
        os_fast_mutex_lock(mutex->handle);
622
585
 
623
586
        (mutex->count)++;
624
587
 
625
588
        ut_a(mutex->count == 1);
 
589
#endif
626
590
}
627
591
 
628
 
/**********************************************************//**
 
592
/**************************************************************
629
593
Releases ownership of a mutex. */
630
594
UNIV_INTERN
631
595
void
632
596
os_mutex_exit(
633
597
/*==========*/
634
 
        os_mutex_t      mutex)  /*!< in: mutex to release */
 
598
        os_mutex_t      mutex)  /* in: mutex to release */
635
599
{
636
600
        ut_a(mutex);
637
601
 
638
602
        ut_a(mutex->count == 1);
639
603
 
640
604
        (mutex->count)--;
 
605
#ifdef __WIN__
 
606
        ut_a(ReleaseMutex(mutex->handle));
 
607
#else
641
608
        os_fast_mutex_unlock(mutex->handle);
 
609
#endif
642
610
}
643
611
 
644
 
/**********************************************************//**
 
612
/**************************************************************
645
613
Frees a mutex object. */
646
614
UNIV_INTERN
647
615
void
648
616
os_mutex_free(
649
617
/*==========*/
650
 
        os_mutex_t      mutex)  /*!< in: mutex to free */
 
618
        os_mutex_t      mutex)  /* in: mutex to free */
651
619
{
652
620
        ut_a(mutex);
653
621
 
667
635
                os_mutex_exit(os_sync_mutex);
668
636
        }
669
637
 
 
638
#ifdef __WIN__
 
639
        ut_a(CloseHandle(mutex->handle));
 
640
 
 
641
        ut_free(mutex);
 
642
#else
670
643
        os_fast_mutex_free(mutex->handle);
671
644
        ut_free(mutex->handle);
672
645
        ut_free(mutex);
 
646
#endif
673
647
}
674
648
 
675
 
/*********************************************************//**
 
649
/*************************************************************
676
650
Initializes an operating system fast mutex semaphore. */
677
651
UNIV_INTERN
678
652
void
679
653
os_fast_mutex_init(
680
654
/*===============*/
681
 
        os_fast_mutex_t*        fast_mutex)     /*!< in: fast mutex */
 
655
        os_fast_mutex_t*        fast_mutex)     /* in: fast mutex */
682
656
{
683
657
#ifdef __WIN__
684
658
        ut_a(fast_mutex);
685
659
 
686
660
        InitializeCriticalSection((LPCRITICAL_SECTION) fast_mutex);
687
661
#else
688
 
        ut_a(0 == innobase_fast_mutex_init(fast_mutex));
 
662
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
 
663
        ut_a(0 == pthread_mutex_init(fast_mutex, pthread_mutexattr_default));
 
664
#else
 
665
        ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
 
666
#endif
689
667
#endif
690
668
        if (UNIV_LIKELY(os_sync_mutex_inited)) {
691
669
                /* When creating os_sync_mutex itself (in Unix) we cannot
701
679
        }
702
680
}
703
681
 
704
 
/**********************************************************//**
 
682
/**************************************************************
705
683
Acquires ownership of a fast mutex. */
706
684
UNIV_INTERN
707
685
void
708
686
os_fast_mutex_lock(
709
687
/*===============*/
710
 
        os_fast_mutex_t*        fast_mutex)     /*!< in: mutex to acquire */
 
688
        os_fast_mutex_t*        fast_mutex)     /* in: mutex to acquire */
711
689
{
712
690
#ifdef __WIN__
713
691
        EnterCriticalSection((LPCRITICAL_SECTION) fast_mutex);
716
694
#endif
717
695
}
718
696
 
719
 
/**********************************************************//**
 
697
/**************************************************************
720
698
Releases ownership of a fast mutex. */
721
699
UNIV_INTERN
722
700
void
723
701
os_fast_mutex_unlock(
724
702
/*=================*/
725
 
        os_fast_mutex_t*        fast_mutex)     /*!< in: mutex to release */
 
703
        os_fast_mutex_t*        fast_mutex)     /* in: mutex to release */
726
704
{
727
705
#ifdef __WIN__
728
706
        LeaveCriticalSection(fast_mutex);
731
709
#endif
732
710
}
733
711
 
734
 
/**********************************************************//**
 
712
/**************************************************************
735
713
Frees a mutex object. */
736
714
UNIV_INTERN
737
715
void
738
716
os_fast_mutex_free(
739
717
/*===============*/
740
 
        os_fast_mutex_t*        fast_mutex)     /*!< in: mutex to free */
 
718
        os_fast_mutex_t*        fast_mutex)     /* in: mutex to free */
741
719
{
742
720
#ifdef __WIN__
743
721
        ut_a(fast_mutex);
767
745
                os_mutex_enter(os_sync_mutex);
768
746
        }
769
747
 
770
 
        ut_ad(os_fast_mutex_count > 0);
771
748
        os_fast_mutex_count--;
772
749
 
773
750
        if (UNIV_LIKELY(os_sync_mutex_inited)) {