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) | Py_LOCAL_INLINE(int) | ||||||
| PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) | PyCOND_TIMEDWAIT(PyCOND_T *cond, PyMUTEX_T *mut, long long us) | ||||||
| { | { | ||||||
|     struct timespec abs; |     struct timespec abs_timeout; | ||||||
|     _PyThread_cond_after(us, &abs); |     _PyThread_cond_after(us, &abs_timeout); | ||||||
|     int ret = pthread_cond_timedwait(cond, mut, &abs); |     int ret = pthread_cond_timedwait(cond, mut, &abs_timeout); | ||||||
|     if (ret == ETIMEDOUT) { |     if (ret == ETIMEDOUT) { | ||||||
|         return 1; |         return 1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  | @ -113,19 +113,6 @@ | ||||||
| #endif | #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 |  * pthread_cond support | ||||||
|  */ |  */ | ||||||
|  | @ -156,23 +143,23 @@ _PyThread_cond_init(PyCOND_T *cond) | ||||||
|     return pthread_cond_init(cond, condattr_monotonic); |     return pthread_cond_init(cond, condattr_monotonic); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
| void | void | ||||||
| _PyThread_cond_after(long long us, struct timespec *abs) | _PyThread_cond_after(long long us, struct timespec *abs) | ||||||
| { | { | ||||||
|  |     _PyTime_t timeout = _PyTime_FromMicrosecondsClamp(us); | ||||||
|  |     _PyTime_t t; | ||||||
| #ifdef CONDATTR_MONOTONIC | #ifdef CONDATTR_MONOTONIC | ||||||
|     if (condattr_monotonic) { |     if (condattr_monotonic) { | ||||||
|         clock_gettime(CLOCK_MONOTONIC, abs); |         t = _PyTime_GetMonotonicClock(); | ||||||
|         abs->tv_sec  += us / 1000000; |  | ||||||
|         abs->tv_nsec += (us % 1000000) * 1000; |  | ||||||
|         abs->tv_sec  += abs->tv_nsec / 1000000000; |  | ||||||
|         abs->tv_nsec %= 1000000000; |  | ||||||
|         return; |  | ||||||
|     } |     } | ||||||
|  |     else | ||||||
| #endif | #endif | ||||||
| 
 |     { | ||||||
|     struct timespec ts; |         t = _PyTime_GetSystemClock(); | ||||||
|     MICROSECONDS_TO_TIMESPEC(us, ts); |     } | ||||||
|     *abs = ts; |     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; |         goto unlock; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     struct timespec abs; |     struct timespec abs_timeout; | ||||||
|     if (microseconds > 0) { |     if (microseconds > 0) { | ||||||
|         _PyThread_cond_after(microseconds, &abs); |         _PyThread_cond_after(microseconds, &abs_timeout); | ||||||
|     } |     } | ||||||
|     // Continue trying until we get the lock
 |     // 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) { |     while (1) { | ||||||
|         if (microseconds > 0) { |         if (microseconds > 0) { | ||||||
|             status = pthread_cond_timedwait(&thelock->lock_released, |             status = pthread_cond_timedwait(&thelock->lock_released, | ||||||
|                                             &thelock->mut, &abs); |                                             &thelock->mut, &abs_timeout); | ||||||
|             if (status == 1) { |             if (status == 1) { | ||||||
|                 break; |                 break; | ||||||
|             } |             } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner