mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	gh-74953: _PyThread_cond_after() uses _PyTime_t (#94056)
pthread _PyThread_cond_after() implementation now uses the _PyTime_t type to handle properly overflow: clamp to the maximum value. Remove MICROSECONDS_TO_TIMESPEC() function.
This commit is contained in:
		
							parent
							
								
									616fa3465d
								
							
						
					
					
						commit
						c7a79bb036
					
				
					 2 changed files with 16 additions and 29 deletions
				
			
		|  | @ -68,9 +68,9 @@ void _PyThread_cond_after(long long us, struct timespec *abs); | |||
| Py_LOCAL_INLINE(int) | ||||
| PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) | ||||
| { | ||||
|     struct timespec abs; | ||||
|     _PyThread_cond_after(us, &abs); | ||||
|     int ret = pthread_cond_timedwait(cond, mut, &abs); | ||||
|     struct timespec abs_timeout; | ||||
|     _PyThread_cond_after(us, &abs_timeout); | ||||
|     int ret = pthread_cond_timedwait(cond, mut, &abs_timeout); | ||||
|     if (ret == ETIMEDOUT) { | ||||
|         return 1; | ||||
|     } | ||||
|  |  | |||
|  | @ -113,19 +113,6 @@ | |||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #define MICROSECONDS_TO_TIMESPEC(microseconds, ts) \ | ||||
| do { \ | ||||
|     struct timeval tv; \ | ||||
|     gettimeofday(&tv, NULL); \ | ||||
|     tv.tv_usec += microseconds % 1000000; \ | ||||
|     tv.tv_sec += microseconds / 1000000; \ | ||||
|     tv.tv_sec += tv.tv_usec / 1000000; \ | ||||
|     tv.tv_usec %= 1000000; \ | ||||
|     ts.tv_sec = tv.tv_sec; \ | ||||
|     ts.tv_nsec = tv.tv_usec * 1000; \ | ||||
| } while(0) | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * pthread_cond support | ||||
|  */ | ||||
|  | @ -156,23 +143,23 @@ _PyThread_cond_init(PyCOND_T *cond) | |||
|     return pthread_cond_init(cond, condattr_monotonic); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| void | ||||
| _PyThread_cond_after(long long us, struct timespec *abs) | ||||
| { | ||||
|     _PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us); | ||||
|     _PyTime_t t; | ||||
| #ifdef CONDATTR_MONOTONIC | ||||
|     if (condattr_monotonic) { | ||||
|         clock_gettime(CLOCK_MONOTONIC, abs); | ||||
|         abs->tv_sec  += us / 1000000; | ||||
|         abs->tv_nsec += (us % 1000000) * 1000; | ||||
|         abs->tv_sec  += abs->tv_nsec / 1000000000; | ||||
|         abs->tv_nsec %= 1000000000; | ||||
|         return; | ||||
|         t = _PyTime_GetMonotonicClock(); | ||||
|     } | ||||
|     else | ||||
| #endif | ||||
| 
 | ||||
|     struct timespec ts; | ||||
|     MICROSECONDS_TO_TIMESPEC(us, ts); | ||||
|     *abs = ts; | ||||
|     { | ||||
|         t = _PyTime_GetSystemClock(); | ||||
|     } | ||||
|     t = _PyTime_Add(t, timeout); | ||||
|     _PyTime_AsTimespec_clamp(t, abs); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -639,9 +626,9 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, | |||
|         goto unlock; | ||||
|     } | ||||
| 
 | ||||
|     struct timespec abs; | ||||
|     struct timespec abs_timeout; | ||||
|     if (microseconds > 0) { | ||||
|         _PyThread_cond_after(microseconds, &abs); | ||||
|         _PyThread_cond_after(microseconds, &abs_timeout); | ||||
|     } | ||||
|     // Continue trying until we get the lock
 | ||||
| 
 | ||||
|  | @ -649,7 +636,7 @@ PyThread_acquire_lock_timed(PyThread_type_lock lock, PY_TIMEOUT_T microseconds, | |||
|     while (1) { | ||||
|         if (microseconds > 0) { | ||||
|             status = pthread_cond_timedwait(&thelock->lock_released, | ||||
|                                             &thelock->mut, &abs); | ||||
|                                             &thelock->mut, &abs_timeout); | ||||
|             if (status == 1) { | ||||
|                 break; | ||||
|             } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner