⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pthread.c

📁 OpenSS7 This the fourth public release of the OpenSS7 Master Package. See README in the release for
💻 C
📖 第 1 页 / 共 2 页
字号:
/** Cleanup thread on asynchronous exit.  * @param buffer a pointer to a stack allocated cleanup buffer.  * @param routine the cleanup routine.  * @param arg an argument for the cleanup routine.  *  * This is a replacement for the internal glibc function  * _pthread_cleanup_push_defer().  The function is declared in <pthread.h> as a  * weak undefined symbol in glibc to allow the pthreads library to override the  * function.  The struct _pthread_cleanup_buffer structure is also declared in  * <pthread.h>.  */void_pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *),			    void *arg){	/** If the weak undefined symbol, __pthread_cleanup_push_defer() is	  * loaded, a suitable threads library exists, and the library symbol is	  * called. */	if (__pthread_cleanup_push_defer)		return __pthread_cleanup_push_defer(buffer, routine, arg);	/** Otherwise, The function must initialize the cleanup buffer pointed	  * to by buffer that was pushed onto the stack by glibc as well as	  * setting the cancellation type for the current thread to deferred and	  * storing the previous thread cancellation state into the supplied	  * buffer. */	buffer->__routine = routine;	buffer->__arg = arg;	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &buffer->__canceltype);	buffer->__prev = NULL;}/** Cleanup thread on asynchronous exit.  * @param buffer a pointer to a stack allocated cleanup buffer.  * @param execute whether to execute the cleanup function.  *  * This is a replacement for the internal glibc function  * _pthread_cleanup_pop().  The function is declared in <pthread.h> as a weak  * undefined symbol in glibc to allow the pthreads library to override the  * function.  The struct _pthread_cleanup_buffer structure is also declared in  * <pthread.h>. */void_pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *buffer, int execute){	/** If the weak undefined symbol, __pthread_cleanup_pop_restore() is	  * loaded, a suitable threads library exists, and the library symbol is	  * called. */	if (__pthread_cleanup_pop_restore)		return __pthread_cleanup_pop_restore(buffer, execute);	/** Otherwise, function must deinitialize the cleanup buffer pointerd to	  * by buffer that will be popped from the stack by glibc, as well a	  * setting the thread cancellation type back to the previous value from	  * buffer.  */	if (execute)		(*buffer->__routine) (buffer->__arg);	pthread_setcanceltype(buffer->__canceltype, NULL);}/** Test for asyncrhonous thread cancellation (while deferred).  * This is a non-recursive replacement for the pthread library function, pthread_testcancel(3). */voidpthread_testcancel(void){	/** If the weak undefined symbol, __pthread_testcancel() is loaded, a	  * suitable threads library exists and the library symbol is called.	  */	if (__pthread_testcancel)		return __pthread_testcancel();	/** Otherwise, for non-threaded operation, this is a noop. */	return;}/** Thread cancellation type storage.  * @internal This is a statically allocated internal storage for holding the  * thread cancellation type when no suitable threads library is loaded  * (non-thread-safe operation).  */static int __pthread_canceltype = 0;/** Set or defer thread asynchronous cancellation.  * @param type cancellation type to set.  * @param oldtype place to return current type.  *  * This is a non-recursive replacement for the pthread library function, pthread_setcanceltype(3). */intpthread_setcanceltype(int type, int *oldtype){	/** If the weak undefined symbol, __pthread_setcanceltype() is loaded, a suitable threads	  * library exists, and the library symbol is called.  */	if (__pthread_setcanceltype)		return __pthread_setcanceltype(type, oldtype);	/** Otherwise, for non-thread operation, this function simply saves new	  * type and returns the oldtype from a static variable.  One of the	  * ramifications of this is that the cancel type might not be correct	  * after a fork(2). */	if (oldtype != NULL)		*oldtype = __pthread_canceltype;	__pthread_canceltype = type;	return (0);	/** @return Returns zero (0) on success, error number on failure. */}/** Initialize a reader/writer lock.  * @param rwlock the lock to initalize.  * @param attr a pointer to lock attributes.  *  * This is a non-recursive replacement for the pthread library function,  * pthread_rwlock_init(3). */intpthread_rwlock_init(pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr){	/** If the weak undefined symbol, __pthread_rwlock_init(), is loaded, a	  * suitable threads library exists, and the library symbol is called.	  */	if (__pthread_rwlock_init)		return __pthread_rwlock_init(rwlock, attr);	/** Otherwise, for non-threaded operation, this function simply	  * initializes the first byte of the lock structure to zero to indicate	  * that the lock is unlocked. */	*(char *) rwlock = 0;	return (0);	/** @return Returns zero (0) on success, error number on failure. */}/** Read-lock a reader/writer lock.  * @param rwlock the lock to read lock.  *  * This is a non-recursive replacement for the pthread library function,  * pthread_rwlock_rdlock(3). */intpthread_rwlock_rdlock(pthread_rwlock_t * rwlock){	/** If the weak undefined symbol, __pthread_rwlock_rdlock(), is loaded,	  * a suitablel threads library exists, and the library symbol is	  * called. */	if (__pthread_rwlock_rdlock)		return __pthread_rwlock_rdlock(rwlock);	/** Otherwise, for non-threaded operation, this function simply	  * increments the first by of the lock structure (POSIX locks are	  * recursive in that multiple reader locks can be taken by the same	  * thread).  */	*(char *) rwlock = *(char *) rwlock + 1;	return (0);	/** @return Returns zero (0) on success, error number on failure. */}/** Write-lock a reader/writer lock.  * @param rwlock the lock to write lock.  *  * This is a non-recursive replacement for the pthread library function, pthread_rwlock_wrlock(3).  * */intpthread_rwlock_wrlock(pthread_rwlock_t * rwlock){	/** If the weak undefined symbol, __pthread_rwlock_wrlock(), is loaded,	  * a suitable threads library exists, and the library symbol is called.	  */	if (__pthread_rwlock_wrlock)		return __pthread_rwlock_wrlock(rwlock);	/** Otherwise, the first byte of the lock structus is imply decremented	  * (although POSIX locks cannot recurse on write).  Note that if the	  * byte is not zero, then it is an errror that can be detected here.	  * If debugging, print an error message.  */	if (*(char *) rwlock != 0) {		errno = EDEADLK;#ifdef DEBUG		perror(__FUNCTION__);#endif		return (errno);	}	*(char *) rwlock = *(char *) rwlock - 1;	return (0);	/** @return Returns zero (0) on success, error number on failure. */	/** @retval EDEADLK Attempting to lock would cause a deadlock.  */}/** Unlock a reader/writer lock.  * This is a non-recursive replacement for the pthread library function,  * pthread_rwlock_unlock(3). */intpthread_rwlock_unlock(pthread_rwlock_t * rwlock){	/** If the weak undefined symbol, __pthread_rwlock_unlock(), is loaded,	  * a suitable threads library exists, and the library symbol is called.	  * */	if (__pthread_rwlock_unlock)		return __pthread_rwlock_unlock(rwlock);	/** Otherwise, if the value of the first byte is greater than zero (read	  * locked), decrement the value; minus one (-1) (write locked), set it	  * to zero.  Note that if the byte is already set to zero, the lock is	  * unlocked.  If debugging, print an error message. */	if (*(char *) rwlock == -2 || *(char *)rwlock == 0) {#ifdef DEBUG		errno = EINVAL;		perror(__FUNCTION__);#endif		return (EINVAL);	}	if (*(char *) rwlock > 0)		*(char *) rwlock = *(char *) rwlock - 1;	else		*(char *) rwlock = 0;	return (0);	/** @return Returns zero (0) on success, error number on failure. */}/** Destroy a reader/writer lock.  * This is a non-recursive replacement for the pthread library function,  * pthread_rwlock_destroy(3). */intpthread_rwlock_destroy(pthread_rwlock_t * rwlock){	/** If the weak undefined symbol, __pthread_rwlock_destroy(), is loaded,	  * a suitable threads library exists, and the library symbol is called.	  */	if (__pthread_rwlock_destroy)		return __pthread_rwlock_destroy(rwlock);	/** Otherwise, just set it to some illegal value. */	*(char *) rwlock = -2;	return (0);	/** @return Returns zero (0) on success, error number on failure. */}/** Perform a procedure once for all threads.  * This is a non-recursive replacement for the pthread library function,  * pthread_once(3). */intpthread_once(pthread_once_t * once_control, void (*init_routine) (void)){	/** If the weak undefined symbol, __pthread_once(), is loaded, a	  * suitable threads library exists, and the library symbol is called.	  */	if (__pthread_once)		return __pthread_once(once_control, init_routine);	/** Otherwise, if the value of the control is zero, set it to one and	  * call the init routine. */	if (*once_control == 0) {		*once_control = 1;		init_routine();	}	return (0);	/** @return Always returns zero (0). */}/** Key retention structure. */struct __pthread_key_data {	int exists;	/**< True when created, false when available. */	void *value;	/**< Value if it exists. */};/** Array of thread-specific-data keys. */static struct __pthread_key_data ___pthread_keys[PTHREAD_KEYS_MAX] = { { 0, }, };/** Create a thread-specific data key.  * This is a non-recursive replacement for the pthread library function,  * pthread_key_create(3). */intpthread_key_create(pthread_key_t * key, void (*destr_function) (void *)){	int i;	/** If the weak undefined symbol, __pthread_key_create(), is loaded, a	  * suitable threads library exists, and the library symbol is called.	  */	if (__pthread_key_create)		return __pthread_key_create(key, destr_function);	/** Otherwise, allocate a new key from the statically allocated keys	  * structure and null its value. */	for (i = 0; i < PTHREAD_KEYS_MAX; i++)		if (!___pthread_keys[i].exists)			break;	if (i == PTHREAD_KEYS_MAX)		return (ENOMEM);	___pthread_keys[i].exists = 1;	___pthread_keys[i].value = NULL;	*key = i;	return (0);	/** @return Returns zero (0) on success, error number on failure.  On	  * success, the key value is stored in the area pointed to by argument	  * key. */	/** @retval ENOMEM No keys left. */}/** Set a thread-specific data value.  * This is a non-recursive replacement for the pthread library function,  * pthread_setspecific(3). */intpthread_setspecific(pthread_key_t key, const void *pointer){	/** If the weak undefined symbol, __pthread_setspecific(), is loaded, a	  * suitable threads library exists, and the library symbol is called.	  */	if (__pthread_setspecific)		return __pthread_setspecific(key, pointer);	/** Otherwise, set the value in the statically allocated array.  */	if (key < 0 || key >= PTHREAD_KEYS_MAX || !___pthread_keys[key].exists)		return (EINVAL);	___pthread_keys[key].value = (void *) pointer;	return (0);	/** @return Returns zero (0) on success, error number on	  * failure.  On success, the thread specific data pointer	  * specified by argument key is set to the value of argument	  * pointer. */	/** @retval EINVAL Invalid key argument. */}/** Set a thread-specific data value.  * This is a non-recursive replacement for the pthread library function,  * pthread_getspecific(3). */void *pthread_getspecific(pthread_key_t key){	/** If the weak undefined symbol, __pthread_getspecific(), is loaded, a	  * suitable threads library exists, and the library symbol is called.	  */	if (__pthread_getspecific)		return __pthread_getspecific(key);	/** Otherwise, get the value from the statically allocated array.  */	if (key < 0 || key >= PTHREAD_KEYS_MAX || !___pthread_keys[key].exists) {		errno = EINVAL;		return (NULL);	}	return ___pthread_keys[key].value;	/** @return On success, returns the thread specific data associated with	  * argument key; on failure, returns NULL. */	/** @retval EINVAL Invalid key argument. */}/** Delete a thread-specific data key.  * This is a non-recursive replacement for the pthread library function,  * pthread_key_delete(3). */intpthread_key_delete(pthread_key_t key){	/** If the weak undefined symbol, __pthread_key_delete(), is loaded, a	  * suitable threads library exists, and the library symbol is called.	  */	if (__pthread_key_delete)		return __pthread_key_delete(key);	/* Otherwise, mark the key available in the statically allocated array.	 */	if (key < 0 || key >= PTHREAD_KEYS_MAX || !___pthread_keys[key].exists)		return (EINVAL);	___pthread_keys[key].exists = 0;	___pthread_keys[key].value = NULL;	return (0);	/** @return Returns zero (0) on success, error number on failure. */	/** @retval EINVAL Invalid key argument. */}/** @} */// vim: ft=c com=sr\:/**,mb\:\ *,eb\:\ */,sr\:/*,mb\:*,eb\:*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -