mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	Patch #525532: Add support for POSIX semaphores.
This commit is contained in:
		
							parent
							
								
									8e0c82a35f
								
							
						
					
					
						commit
						cc89866b65
					
				
					 1 changed files with 119 additions and 0 deletions
				
			
		|  | @ -11,6 +11,10 @@ | |||
| #undef destructor | ||||
| #endif | ||||
| #include <signal.h> | ||||
| #ifdef _POSIX_SEMAPHORES | ||||
| #include <semaphore.h> | ||||
| #include <errno.h> | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /* try to determine what version of the Pthread Standard is installed.
 | ||||
|  | @ -76,6 +80,16 @@ | |||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /* Whether or not to use semaphores directly rather than emulating them with
 | ||||
|  * mutexes and condition variables: | ||||
|  */ | ||||
| #ifdef _POSIX_SEMAPHORES | ||||
| #  define USE_SEMAPHORES | ||||
| #else | ||||
| #  undef USE_SEMAPHORES | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| /* On platforms that don't use standard POSIX threads pthread_sigmask()
 | ||||
|  * isn't present.  DEC threads uses sigprocmask() instead as do most | ||||
|  * other UNIX International compliant systems that don't have the full | ||||
|  | @ -294,6 +308,109 @@ PyThread__exit_prog(int status) | |||
| } | ||||
| #endif /* NO_EXIT_PROG */ | ||||
| 
 | ||||
| #ifdef USE_SEMAPHORES | ||||
| 
 | ||||
| /*
 | ||||
|  * Lock support. | ||||
|  */ | ||||
| 
 | ||||
| PyThread_type_lock  | ||||
| PyThread_allocate_lock(void) | ||||
| { | ||||
| 	sem_t *lock; | ||||
| 	int status, error = 0; | ||||
| 
 | ||||
| 	dprintf(("PyThread_allocate_lock called\n")); | ||||
| 	if (!initialized) | ||||
| 		PyThread_init_thread(); | ||||
| 
 | ||||
| 	lock = (sem_t *)malloc(sizeof(sem_t)); | ||||
| 
 | ||||
| 	if (lock) { | ||||
| 		status = sem_init(lock,0,1); | ||||
| 		CHECK_STATUS("sem_init"); | ||||
| 
 | ||||
| 		if (error) { | ||||
| 			free((void *)lock); | ||||
| 			lock = NULL; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	dprintf(("PyThread_allocate_lock() -> %p\n", lock)); | ||||
| 	return (PyThread_type_lock)lock; | ||||
| } | ||||
| 
 | ||||
| void  | ||||
| PyThread_free_lock(PyThread_type_lock lock) | ||||
| { | ||||
| 	sem_t *thelock = (sem_t *)lock; | ||||
| 	int status, error = 0; | ||||
| 
 | ||||
| 	dprintf(("PyThread_free_lock(%p) called\n", lock)); | ||||
| 
 | ||||
| 	if (!thelock) | ||||
| 		return; | ||||
| 
 | ||||
| 	status = sem_destroy(thelock); | ||||
| 	CHECK_STATUS("sem_destroy"); | ||||
| 
 | ||||
| 	free((void *)thelock); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * As of February 2002, Cygwin thread implementations mistakenly report error | ||||
|  * codes in the return value of the sem_ calls (like the pthread_ functions). | ||||
|  * Correct implementations return -1 and put the code in errno. This supports | ||||
|  * either. | ||||
|  */ | ||||
| static int | ||||
| fix_status(int status) | ||||
| { | ||||
| 	return (status == -1) ? errno : status; | ||||
| } | ||||
| 
 | ||||
| int  | ||||
| PyThread_acquire_lock(PyThread_type_lock lock, int waitflag) | ||||
| { | ||||
| 	int success; | ||||
| 	sem_t *thelock = (sem_t *)lock; | ||||
| 	int status, error = 0; | ||||
| 
 | ||||
| 	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock, waitflag)); | ||||
| 
 | ||||
| 	do { | ||||
| 		if (waitflag) | ||||
| 			status = fix_status(sem_wait(thelock)); | ||||
| 		else | ||||
| 			status = fix_status(sem_trywait(thelock)); | ||||
| 	} while (status == EINTR); /* Retry if interrupted by a signal */ | ||||
| 
 | ||||
| 	if (waitflag) { | ||||
| 		CHECK_STATUS("sem_wait"); | ||||
| 	} else if (status != EAGAIN) { | ||||
| 		CHECK_STATUS("sem_trywait"); | ||||
| 	} | ||||
| 	 | ||||
| 	success = (status == 0) ? 1 : 0; | ||||
| 
 | ||||
| 	dprintf(("PyThread_acquire_lock(%p, %d) -> %d\n", lock, waitflag, success)); | ||||
| 	return success; | ||||
| } | ||||
| 
 | ||||
| void  | ||||
| PyThread_release_lock(PyThread_type_lock lock) | ||||
| { | ||||
| 	sem_t *thelock = (sem_t *)lock; | ||||
| 	int status, error = 0; | ||||
| 
 | ||||
| 	dprintf(("PyThread_release_lock(%p) called\n", lock)); | ||||
| 
 | ||||
| 	status = sem_post(thelock); | ||||
| 	CHECK_STATUS("sem_post"); | ||||
| } | ||||
| 
 | ||||
| #else /* USE_SEMAPHORES */ | ||||
| 
 | ||||
| /*
 | ||||
|  * Lock support. | ||||
|  */ | ||||
|  | @ -405,3 +522,5 @@ PyThread_release_lock(PyThread_type_lock lock) | |||
| 	status = pthread_cond_signal( &thelock->lock_released ); | ||||
| 	CHECK_STATUS("pthread_cond_signal"); | ||||
| } | ||||
| 
 | ||||
| #endif /* USE_SEMAPHORES */ | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Martin v. Löwis
						Martin v. Löwis