------------------------------------------------------------ revno: 3201 committer: kevin.lewis@oracle.com branch nick: mysql-5.5-innodb timestamp: Tue 2010-10-26 14:18:31 -0500 message: Bug#57720 - Windows Vista and possibly Windows 7 can return ERROR_TIMEOUT instead of WAIT_TIMEOUT from calls to SleepConditionVariableCS() which is used in os0sync.c; os_cond_wait_timeout() where it is mapped to sleep_condition_variable(). Consider ERROR_TIMEOUT to be a timeout just like WAIT_TIMEOUT. In addition, test for EINTR as a possible return value from pthread_cond_timeout() in the posix section of os_cond_wait_timeout(), even though it is not supposed to be returned, but just to be safe. diff: === modified file 'storage/innobase/os/os0sync.c' --- storage/innobase/os/os0sync.c revid:jimmy.yang@oracle.com-20101025070203-1pm5vrrx5d6wgk5q +++ storage/innobase/os/os0sync.c revid:kevin.lewis@oracle.com-20101026191831-1zm2j4vs0gchqxq0 @@ -142,14 +142,24 @@ ) { #ifdef __WIN__ - BOOL ret; + BOOL ret; + DWORD err; ut_a(sleep_condition_variable != NULL); ret = sleep_condition_variable(cond, mutex, time_in_ms); - if (!ret && GetLastError() == WAIT_TIMEOUT) { - return(TRUE); + if (!ret) { + err = GetLastError(); + /* From http://msdn.microsoft.com/en-us/library/ms686301%28VS.85%29.aspx, + "Condition variables are subject to spurious wakeups + (those not associated with an explicit wake) and stolen wakeups + (another thread manages to run before the woken thread)." + Check for both types of timeouts. + Conditions are checked by the caller.*/ + if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) { + return(TRUE); + } } ut_a(ret); @@ -163,12 +173,15 @@ switch (ret) { case 0: case ETIMEDOUT: - break; + /* We play it safe by checking for EINTR even though + according to the POSIX documentation it can't return EINTR. */ + case EINTR: + break; default: fprintf(stderr, " InnoDB: pthread_cond_timedwait() returned: " "%d: abstime={%lu,%lu}\n", - ret, abstime->tv_sec, abstime->tv_nsec); + ret, abstime->tv_sec, abstime->tv_nsec); ut_error; } @@ -663,7 +676,7 @@ if (err == WAIT_OBJECT_0) { return(0); - } else if (err == WAIT_TIMEOUT) { + } else if ((err == WAIT_TIMEOUT) || (err == ERROR_TIMEOUT)) { return(OS_SYNC_TIME_EXCEEDED); }