?? pthread.c
字號:
/***************************************************************************** @(#) pthread.c,v openss7-0_9_2_E(0.9.2.2) 2006/10/13 00:09:13 ----------------------------------------------------------------------------- Copyright (c) 2001-2006 OpenSS7 Corporation <http://www.openss7.com/> Copyright (c) 1997-2000 Brian F. G. Bidulock <bidulock@openss7.org> All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ----------------------------------------------------------------------------- U.S. GOVERNMENT RESTRICTED RIGHTS. If you are licensing this Software on behalf of the U.S. Government ("Government"), the following provisions apply to you. If the Software is supplied by the Department of Defense ("DoD"), it is classified as "Commercial Computer Software" under paragraph 252.227-7014 of the DoD Supplement to the Federal Acquisition Regulations ("DFARS") (or any successor regulations) and the Government is acquiring only the license rights granted herein (the license rights customarily provided to non-Government users). If the Software is supplied to any unit or agency of the Government other than DoD, it is classified as "Restricted Computer Software" and the Government's rights in the Software are defined in paragraph 52.227-19 of the Federal Acquisition Regulations ("FAR") (or any successor regulations) or, in the cases of NASA, in paragraph 18.52.227-86 of the NASA Supplement to the FAR (or any successor regulations). ----------------------------------------------------------------------------- Commercial licensing and support of this software is available from OpenSS7 Corporation at a fee. See http://www.openss7.com/ ----------------------------------------------------------------------------- Last Modified 2006/10/13 00:09:13 by brian ----------------------------------------------------------------------------- pthread.c,v Revision 0.9.2.2 2006/10/13 00:09:13 brian - fixed segfault in pthread_setcanceltype Revision 0.9.2.1 2006/09/25 20:15:46 brian - rationalized to strinet and strxnet Revision 0.9.2.4 2006/09/24 21:57:23 brian - documentation and library updates Revision 0.9.2.3 2006/09/22 20:54:27 brian - tweaked source file for use with doxygen Revision 0.9.2.2 2006/09/18 13:52:56 brian - added doxygen markers to sources Revision 0.9.2.1 2006/09/18 00:03:15 brian - added libxnsl source files *****************************************************************************/#ident "@(#) pthread.c,v openss7-0_9_2_E(0.9.2.2) 2006/10/13 00:09:13"static char const ident[] = "pthread.c,v openss7-0_9_2_E(0.9.2.2) 2006/10/13 00:09:13";/* This file can be processed with doxygen(1). *//** @weakgroup pthread OpenSS7 Library Thread Safety * @{ *//** @file * Thread-safety implementation file. * This file provide implementation of functions used for thread-safety as * well as for non-recursive versions of the library. This file is shared by * a number of libraries. *//** @page threadsafety Discussion on Thread-Safety * * This is a lightweight pthreads replacement for the non-recursive * environment. This module defines a number of POSIX thread functions that in * the implementations of the second set. are used by library code. They are * defined as weak aliases. This file provides replacement dummy functions for * POSIX thread functions to be used when there is no need for thread-safety. * When the libpthread library is loaded against a library containing this * package, the POSIX thread definitions from libpthread will be used instead. * Both defined and undefined weak symbols are used so that it does not matter * whether the libpthread library is loaded before or after the library * containing this package. * * The magic of weak functions is a black art. This one works currently, don't * mess with it. * * When linked to this object, a library can pretty much use whatever * cancellation mechanisms, read-write locks and thread specific data they like * using the normal POSIX thread function calls as defined in in <pthread.h> * and not worry about non-recursive versions. *//** @todo What really needs to be done for these functions is to also set a * pthread_atfork() routine to reinitialize all static areas used by the * library when fork(2) is called. */#include <limits.h>#include <errno.h>#include <pthread.h>#ifdef DEBUG#include <unistd.h>#include <stdio.h>#include <string.h>#endif/** @name Asynchronous Thread Cancellation Functions * @brief Functions for asynchronous thread cancellation. * * These functions are declared in <pthread.h>, but are also declared here as * verification against the system headers. These symbols are declared as weak * undefined symbols in glibc and provide thread safety capabilities to glibc * from an add-on pthread library. They are used in the OpenSS7 libraries to * detect whether a suitable pthread library is present (loaded). * * The first set of symbols: __pthread_cleanup_push(), __pthread_cleanup_pop(), * __pthread_cleanup_push_defer(), __pthread_cleanup_pop_restore() and * __pthread_testcancel(), are weak @e undefined symbols in the glibc library. * These symbols are provided when libpthread loads before glibc. * * The second set of symbols: _pthread_cleanup_push(), _pthread_cleanup_pop(), * _pthread_cleanup_push_defer(), _pthread_cleanup_pop_restore(), * pthread_testcancel() and pthread_setcanceltype(), are weak @e defined * symbols that are overriden when libpthread loads after glibc. The first * four of these are non-portable and that is why they begin with a single * underscore. * * The proper approach in implementation is to implement the second set as weak * @e defined symbols that override glibc's symbols and are still overridden by * libpthread strong symbols, and to test the presence of the first set in the * implementations of the second set. * * @{ */#pragma weak __pthread_cleanup_pushextern void __pthread_cleanup_push(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg);#pragma weak __pthread_cleanup_popextern void __pthread_cleanup_pop(struct _pthread_cleanup_buffer *buffer, int execute);#pragma weak __pthread_cleanup_push_deferextern void __pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg);#pragma weak __pthread_cleanup_pop_restoreextern void __pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *buffer, int execute);#pragma weak __pthread_testcancelextern void __pthread_testcancel(void);#pragma weak __pthread_setcanceltypeextern int __pthread_setcanceltype(int type, int *oldtype);#pragma weak _pthread_cleanup_pushextern void _pthread_cleanup_push(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg);#pragma weak _pthread_cleanup_popextern void _pthread_cleanup_pop(struct _pthread_cleanup_buffer *buffer, int execute);#pragma weak _pthread_cleanup_push_deferextern void _pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg);#pragma weak _pthread_cleanup_pop_restoreextern void _pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *buffer, int execute);#pragma weak pthread_testcancelextern void pthread_testcancel(void);#pragma weak pthread_setcanceltypeextern int pthread_setcanceltype(int type, int *oldtype);/** @} *//** @name Read/Write Thread Locking Functions * @brief Functions for reader/writer thread mutual exclusion. * * These functions are declared in <pthread.h>, but are also declared here as * verification against the system headers. These symbols are declared as weak * undefined symbols in glibc and provide thread safety capabilities to glibc * from an add-on pthread library. They are used in the OpenSS7 libraries to * detect whether a suitable pthread library is present (loaded). * * The first set of symbols: __pthread_rwlock_init(), * __pthread_rwlock_rdlock(), __pthread_rwlock_wrlock(), * __pthread_rwlock_unlock() and __pthread_rwlock_destroy(), are weak @e * undefined symbols in the glibc library. These symbols are provided when * libpthread loads before glibc. * * The second set of symbols: pthread_rwlock_init(), pthread_rwlock_rdlock(), * pthread_rwlock_wrlock(), pthread_rwlock_unlock() and * pthread_rwlock_destroy(), are weak @e defined symbols that are overriden * when libpthread loads after glibc. The first four of these are non-portable * and that is why they begin with a single underscore. * * The proper approach in implementation is to implement the second set as weak * @e defined symbols that override glibc's symbols and are still overridden by * libpthread strong symbols, and to test the presence of the first set in the * implementations of the second set. * * @{ */#pragma weak __pthread_rwlock_initextern int __pthread_rwlock_init(pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr);#pragma weak __pthread_rwlock_rdlockextern int __pthread_rwlock_rdlock(pthread_rwlock_t * rwlock);#pragma weak __pthread_rwlock_wrlockextern int __pthread_rwlock_wrlock(pthread_rwlock_t * rwlock);#pragma weak __pthread_rwlock_unlockextern int __pthread_rwlock_unlock(pthread_rwlock_t * rwlock);#pragma weak __pthread_rwlock_destroyextern int __pthread_rwlock_destroy(pthread_rwlock_t * rwlock);#pragma weak pthread_rwlock_initextern int pthread_rwlock_init(pthread_rwlock_t * rwlock, const pthread_rwlockattr_t * attr);#pragma weak pthread_rwlock_rdlockextern int pthread_rwlock_rdlock(pthread_rwlock_t * rwlock);#pragma weak pthread_rwlock_wrlockextern int pthread_rwlock_wrlock(pthread_rwlock_t * rwlock);#pragma weak pthread_rwlock_unlockextern int pthread_rwlock_unlock(pthread_rwlock_t * rwlock);#pragma weak pthread_rwlock_destroyextern int pthread_rwlock_destroy(pthread_rwlock_t * rwlock);/** @} *//** @name Thread Specific Data * @brief Functions for thread specific data. * * These functions are declared in <pthread.h>, but are also declared here as * verification against the system headers. These symbols are declared as weak * undefined symbols in glibc and provide thread safety capabilities to glibc * from an add-on pthread library. They are used in the OpenSS7 libraries to * detect whether a suitable pthread library is present (loaded). * * The first set of symbols: __pthread_once(), __pthread_key_create(), * __pthread_setspecific(), __pthread_getspecific() and __pthread_key_delete(), * are weak @e undefined symbols in the glibc library. These symbols are * provided when libpthread loads before glibc. * * The second set of symbols: pthread_once(), pthread_key_create(), * pthread_setspecific(), pthread_getspecific() and pthread_key_delete(), are * weak @e defined symbols that are overriden when libpthread loads after * glibc. The first four of these are non-portable and that is why they begin * with a single underscore. * * The proper approach in implementation is to implement the second set as weak * @e defined symbols that override glibc's symbols and are still overridden by * libpthread strong symbols, and to test the presence of the first set in the * implementations of the second set. * * @{ */#pragma weak __pthread_onceextern int __pthread_once(pthread_once_t * once_control, void (*init_routine) (void));#pragma weak __pthread_key_createextern int __pthread_key_create(pthread_key_t * key, void (*destr_function) (void *));#pragma weak __pthread_setspecificextern int __pthread_setspecific(pthread_key_t key, const void *pointer);#pragma weak __pthread_getspecificextern void *__pthread_getspecific(pthread_key_t key);#pragma weak __pthread_key_deleteextern int __pthread_key_delete(pthread_key_t key);#pragma weak pthread_onceextern int pthread_once(pthread_once_t * once_control, void (*init_routine) (void));#pragma weak pthread_key_createextern int pthread_key_create(pthread_key_t * key, void (*destr_function) (void *));#pragma weak pthread_setspecificextern int pthread_setspecific(pthread_key_t key, const void *pointer);#pragma weak pthread_getspecificextern void *pthread_getspecific(pthread_key_t key);#pragma weak pthread_key_deleteextern int pthread_key_delete(pthread_key_t key);/** @} *//** Push a cleanup function. * @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(). 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(struct _pthread_cleanup_buffer *buffer, void (*routine) (void *), void *arg){ /** If the weak undefined symbol, __pthread_cleanup_push() is loaded, a * suitable threads library exists, and the library symbol is called. */ if (__pthread_cleanup_push) return __pthread_cleanup_push(buffer, routine, arg); /** Otherwise, The function must initialize the cleanup buffer pointed * to by buffer that was pushed onto the stack by glibc. */ buffer->__routine = routine; buffer->__arg = arg; buffer->__canceltype = 0; buffer->__prev = NULL;}/** Pop, and possibly execute, a cleanup function. * @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>. * * The function must deinitialize the cleanup buffer pointerd to by buffer * that will be popped from the stack by glibc. */void_pthread_cleanup_pop(struct _pthread_cleanup_buffer *buffer, int execute){ if (__pthread_cleanup_pop) return __pthread_cleanup_pop(buffer, execute); if (execute) (*buffer->__routine) (buffer->__arg);}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -