diff options
author | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2010-10-21 15:31:16 +0200 |
---|---|---|
committer | Jon Olav Hauglid <jon.hauglid@oracle.com> | 2010-10-21 15:31:16 +0200 |
commit | 346b73015af68dcbf9446a91425882278bd78cda (patch) | |
tree | 92aeebafd3c4ff480a41fdde1fc92be5a8525fea /storage/innobase/os | |
parent | 00490194630883b5fd08de0bd894c764dfeeffd0 (diff) | |
parent | 38f54271922aaec6e47a589fdf6d0388197c8928 (diff) | |
download | mariadb-git-346b73015af68dcbf9446a91425882278bd78cda.tar.gz |
Merge from mysql-5.5-innodb to mysql-5.5-bugteam
No conflicts
Diffstat (limited to 'storage/innobase/os')
-rw-r--r-- | storage/innobase/os/os0sync.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/storage/innobase/os/os0sync.c b/storage/innobase/os/os0sync.c index 3c70e93aae0..5c400ae31c5 100644 --- a/storage/innobase/os/os0sync.c +++ b/storage/innobase/os/os0sync.c @@ -72,6 +72,9 @@ UNIV_INTERN ulint os_event_count = 0; UNIV_INTERN ulint os_mutex_count = 0; UNIV_INTERN ulint os_fast_mutex_count = 0; +/* The number of microsecnds in a second. */ +static const ulint MICROSECS_IN_A_SECOND = 1000000; + /* Because a mutex is embedded inside an event and there is an event embedded inside a mutex, on free, this generates a recursive call. This version of the free event function doesn't acquire the global lock */ @@ -122,6 +125,57 @@ os_cond_init( } /*********************************************************//** +Do a timed wait on condition variable. +@return TRUE if timed out, FALSE otherwise */ +UNIV_INLINE +ibool +os_cond_wait_timed( +/*===============*/ + os_cond_t* cond, /*!< in: condition variable. */ + os_fast_mutex_t* mutex, /*!< in: fast mutex */ +#ifndef __WIN__ + const struct timespec* abstime /*!< in: timeout */ +#else + ulint time_in_ms /*!< in: timeout in + milliseconds*/ +#endif /* !__WIN__ */ +) +{ +#ifdef __WIN__ + BOOL ret; + + ut_a(sleep_condition_variable != NULL); + + ret = sleep_condition_variable(cond, mutex, time_in_ms); + + if (!ret && GetLastError() == WAIT_TIMEOUT) { + return(TRUE); + } + + ut_a(ret); + + return(FALSE); +#else + int ret; + + ret = pthread_cond_timedwait(cond, mutex, abstime); + + switch (ret) { + case 0: + case ETIMEDOUT: + break; + + default: + fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " + "%d: abstime={%lu,%lu}\n", + ret, abstime->tv_sec, abstime->tv_nsec); + ut_error; + } + + return(ret == ETIMEDOUT); +#endif +} +/*********************************************************//** Wait on condition variable */ UNIV_INLINE void @@ -572,6 +626,128 @@ os_event_wait_low( } } +/**********************************************************//** +Waits for an event object until it is in the signaled state or +a timeout is exceeded. +@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */ +UNIV_INTERN +ulint +os_event_wait_time_low( +/*===================*/ + os_event_t event, /*!< in: event to wait */ + ulint time_in_usec, /*!< in: timeout in + microseconds, or + OS_SYNC_INFINITE_TIME */ + ib_int64_t reset_sig_count) /*!< in: zero or the value + returned by previous call of + os_event_reset(). */ + +{ + ibool timed_out; + ib_int64_t old_signal_count; + +#ifdef __WIN__ + DWORD time_in_ms; + + if (!srv_use_native_conditions) { + DWORD err; + + ut_a(event); + + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + time_in_ms = time_in_ms / 1000; + err = WaitForSingleObject(event->handle, time_in_ms); + } else { + err = WaitForSingleObject(event->handle, INFINITE); + } + + if (err == WAIT_OBJECT_0) { + return(0); + } else if (err == WAIT_TIMEOUT) { + return(OS_SYNC_TIME_EXCEEDED); + } + + ut_error; + /* Dummy value to eliminate compiler warning. */ + return(42); + } else { + ut_a(sleep_condition_variable != NULL); + + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + time_in_ms = time_in_usec / 1000; + } else { + time_in_ms = INFINITE; + } + } +#else + struct timespec abstime; + + if (time_in_usec != OS_SYNC_INFINITE_TIME) { + struct timeval tv; + int ret; + ulint sec; + ulint usec; + + ret = ut_usectime(&sec, &usec); + ut_a(ret == 0); + + tv.tv_sec = sec; + tv.tv_usec = usec; + + tv.tv_usec += time_in_usec; + + if ((ulint) tv.tv_usec >= MICROSECS_IN_A_SECOND) { + tv.tv_sec += time_in_usec / MICROSECS_IN_A_SECOND; + tv.tv_usec %= MICROSECS_IN_A_SECOND; + } + + abstime.tv_sec = tv.tv_sec; + abstime.tv_nsec = tv.tv_usec * 1000; + } else { + abstime.tv_nsec = 999999999; + abstime.tv_sec = (time_t) ULINT_MAX; + } + + ut_a(abstime.tv_nsec <= 999999999); + +#endif /* __WIN__ */ + + os_fast_mutex_lock(&event->os_mutex); + + if (reset_sig_count) { + old_signal_count = reset_sig_count; + } else { + old_signal_count = event->signal_count; + } + + do { + if (event->is_set == TRUE + || event->signal_count != old_signal_count) { + + break; + } + + timed_out = os_cond_wait_timed( + &event->cond_var, &event->os_mutex, +#ifndef __WIN__ + &abstime +#else + time_in_ms +#endif /* !__WIN__ */ + ); + + } while (!timed_out); + + os_fast_mutex_unlock(&event->os_mutex); + + if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { + + os_thread_exit(NULL); + } + + return(timed_out ? OS_SYNC_TIME_EXCEEDED : 0); +} + /*********************************************************//** Creates an operating system mutex semaphore. Because these are slow, the mutex semaphore of InnoDB itself (mutex_t) should be used where possible. |