mirror of git://sourceware.org/git/glibc.git
				
				
				
			* sysdeps/mach/hurd/bits/libc-lock.h: New file, initially copied from
sysdeps/mach version.  Implement counting ("recursive") mutexes
	on top of cthreads mutexes.
	* sysdeps/mach/hurd/bits/stdio-lock.h: File removed; generic now works.
	* sysdeps/generic/bits/stdio-lock.h (_IO_lock_initializer): Define to
	_LIBC_LOCK_RECURSIVE_INITIALIZER if defined, else do an #error.
	(__libc_cleanup_region_start, __libc_cleanup_region_end,
	__libc_clean_end): Define these to call the cleanup function after
	normal exit when they're supposed to.
	* sysdeps/mach/bits/libc-lock.h (__libc_cleanup_region_start):
	Take new first arg DOIT, a boolean saying whether to really install
	any cleanup handler.
	(__libc_cleanup_region_end): Do nothing if start's DOIT arg was zero.
	(__libc_cleanup_end): Likewise.
	* stdio-common/vfscanf.c (LOCK_STREAM): Pass new arg.
	* stdio-common/vfprintf.c (buffered_vfprintf, vfprintf): Likewise.
	* sysdeps/mach/hurd/bits/stdio-lock.h (_IO_cleanup_region_start):
	Likewise.
	* misc/syslog.c (vsyslog, openlog, closelog): Likewise.
	* sysdeps/generic/bits/stdio-lock.h
	(_IO_cleanup_region_start, _IO_cleanup_region_start_noarg): Likewise.
			
			
This commit is contained in:
		
							parent
							
								
									28cb929572
								
							
						
					
					
						commit
						0dce3d154c
					
				
							
								
								
									
										26
									
								
								ChangeLog
								
								
								
								
							
							
						
						
									
										26
									
								
								ChangeLog
								
								
								
								
							|  | @ -1,3 +1,29 @@ | |||
| 2001-08-23  Roland McGrath  <roland@frob.com> | ||||
| 
 | ||||
| 	* sysdeps/mach/hurd/bits/libc-lock.h: New file, initially copied from | ||||
| 	sysdeps/mach version.  Implement counting ("recursive") mutexes | ||||
| 	on top of cthreads mutexes. | ||||
| 	* sysdeps/mach/hurd/bits/stdio-lock.h: File removed; generic now works. | ||||
| 
 | ||||
| 	* sysdeps/generic/bits/stdio-lock.h (_IO_lock_initializer): Define to | ||||
| 	_LIBC_LOCK_RECURSIVE_INITIALIZER if defined, else do an #error. | ||||
| 	(__libc_cleanup_region_start, __libc_cleanup_region_end, | ||||
| 	__libc_clean_end): Define these to call the cleanup function after | ||||
| 	normal exit when they're supposed to. | ||||
| 
 | ||||
| 	* sysdeps/mach/bits/libc-lock.h (__libc_cleanup_region_start): | ||||
| 	Take new first arg DOIT, a boolean saying whether to really install | ||||
| 	any cleanup handler. | ||||
| 	(__libc_cleanup_region_end): Do nothing if start's DOIT arg was zero. | ||||
| 	(__libc_cleanup_end): Likewise. | ||||
| 	* stdio-common/vfscanf.c (LOCK_STREAM): Pass new arg. | ||||
| 	* stdio-common/vfprintf.c (buffered_vfprintf, vfprintf): Likewise. | ||||
| 	* sysdeps/mach/hurd/bits/stdio-lock.h (_IO_cleanup_region_start): | ||||
| 	Likewise. | ||||
| 	* misc/syslog.c (vsyslog, openlog, closelog): Likewise. | ||||
| 	* sysdeps/generic/bits/stdio-lock.h | ||||
| 	(_IO_cleanup_region_start, _IO_cleanup_region_start_noarg): Likewise. | ||||
| 
 | ||||
| 2001-08-23  Jakub Jelinek  <jakub@redhat.com> | ||||
| 
 | ||||
| 	* elf/ldconfig.c (search_dir): Remove stale symlinks. | ||||
|  |  | |||
|  | @ -216,7 +216,7 @@ vsyslog(pri, fmt, ap) | |||
| 
 | ||||
| 	/* Prepare for multiple users.  We have to take care: open and
 | ||||
| 	   write are cancellation points.  */ | ||||
| 	__libc_cleanup_region_start ((void (*) (void *)) cancel_handler, | ||||
| 	__libc_cleanup_region_start (1, (void (*) (void *)) cancel_handler, | ||||
| 				     &oldaction_ptr); | ||||
| 	__libc_lock_lock (syslog_lock); | ||||
| 
 | ||||
|  | @ -315,7 +315,8 @@ void | |||
| openlog (const char *ident, int logstat, int logfac) | ||||
| { | ||||
|   /* Protect against multiple users.  */ | ||||
|   __libc_cleanup_region_start ((void (*) __P ((void *))) __libc_mutex_unlock, | ||||
|   __libc_cleanup_region_start (1, | ||||
| 			       (void (*) __P ((void *))) __libc_mutex_unlock, | ||||
| 			       &syslog_lock); | ||||
|   __libc_lock_lock (syslog_lock); | ||||
| 
 | ||||
|  | @ -346,7 +347,8 @@ void | |||
| closelog () | ||||
| { | ||||
|   /* Protect against multiple users.  */ | ||||
|   __libc_cleanup_region_start ((void (*) __P ((void *))) __libc_mutex_unlock, | ||||
|   __libc_cleanup_region_start (1, | ||||
| 			       (void (*) __P ((void *))) __libc_mutex_unlock, | ||||
| 			       &syslog_lock); | ||||
|   __libc_lock_lock (syslog_lock); | ||||
| 
 | ||||
|  |  | |||
|  | @ -1296,10 +1296,10 @@ vfprintf (FILE *s, const CHAR_T *format, va_list ap) | |||
| 
 | ||||
|   /* Lock stream.  */ | ||||
| #ifdef USE_IN_LIBIO | ||||
|   __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, s); | ||||
|   __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, s); | ||||
|   _IO_flockfile (s); | ||||
| #else | ||||
|   __libc_cleanup_region_start ((void (*) (void *)) &__funlockfile, s); | ||||
|   __libc_cleanup_region_start (1, (void (*) (void *)) &__funlockfile, s); | ||||
|   __flockfile (s); | ||||
| #endif | ||||
| 
 | ||||
|  | @ -2086,7 +2086,7 @@ buffered_vfprintf (register _IO_FILE *s, const CHAR_T *format, | |||
|   result = vfprintf (hp, format, args); | ||||
| 
 | ||||
|   /* Lock stream.  */ | ||||
|   __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, s); | ||||
|   __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, s); | ||||
|   _IO_flockfile (s); | ||||
| 
 | ||||
|   /* Now flush anything from the helper to the S. */ | ||||
|  |  | |||
|  | @ -168,7 +168,7 @@ | |||
| 	}								      \ | ||||
|     } while (0) | ||||
| # define LOCK_STREAM(S)							      \ | ||||
|   __libc_cleanup_region_start ((void (*) (void *)) &_IO_funlockfile, (S));    \ | ||||
|   __libc_cleanup_region_start (1, (void (*) (void *)) &_IO_funlockfile, (S)); \ | ||||
|   _IO_flockfile (S) | ||||
| # define UNLOCK_STREAM(S)						      \ | ||||
|   _IO_funlockfile (S);							      \ | ||||
|  |  | |||
|  | @ -76,21 +76,21 @@ typedef cthread_key_t __libc_key_t; | |||
| 
 | ||||
| 
 | ||||
| /* Start a critical region with a cleanup function */ | ||||
| #define __libc_cleanup_region_start(FCT, ARG)				    \ | ||||
| #define __libc_cleanup_region_start(DOIT, FCT, ARG)			    \ | ||||
| {									    \ | ||||
|   typeof (***(FCT)) *__save_FCT = FCT;					    \ | ||||
|   typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0;			    \ | ||||
|   typeof (ARG) __save_ARG = ARG;					    \ | ||||
|   /* close brace is in __libc_cleanup_region_end below. */ | ||||
| 
 | ||||
| /* End a critical region started with __libc_cleanup_region_start. */ | ||||
| #define __libc_cleanup_region_end(DOIT)					    \ | ||||
|   if (DOIT)								    \ | ||||
|   if ((DOIT) && __save_FCT != 0)					    \ | ||||
|     (*__save_FCT)(__save_ARG);						    \ | ||||
| } | ||||
| 
 | ||||
| /* Sometimes we have to exit the block in the middle.  */ | ||||
| #define __libc_cleanup_end(DOIT)					    \ | ||||
|   if (DOIT)								    \ | ||||
|   if ((DOIT) && __save_FCT != 0)					    \ | ||||
|     (*__save_FCT)(__save_ARG);						    \ | ||||
| 
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -0,0 +1,183 @@ | |||
| /* libc-internal interface for mutex locks.  Hurd version using Mach cthreads.
 | ||||
|    Copyright (C) 1996,97,98,2000,01 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
| 
 | ||||
|    The GNU C Library is free software; you can redistribute it and/or | ||||
|    modify it under the terms of the GNU Lesser General Public | ||||
|    License as published by the Free Software Foundation; either | ||||
|    version 2.1 of the License, or (at your option) any later version. | ||||
| 
 | ||||
|    The GNU C Library 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 | ||||
|    Lesser General Public License for more details. | ||||
| 
 | ||||
|    You should have received a copy of the GNU Lesser General Public | ||||
|    License along with the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
| 
 | ||||
| #ifndef _BITS_LIBC_LOCK_H | ||||
| #define _BITS_LIBC_LOCK_H 1 | ||||
| 
 | ||||
| #if (_LIBC - 0) || (_CTHREADS_ - 0) | ||||
| #include <cthreads.h> | ||||
| #include <hurd/threadvar.h> | ||||
| 
 | ||||
| typedef struct mutex __libc_lock_t; | ||||
| typedef struct | ||||
| { | ||||
|   struct mutex mutex; | ||||
|   void *owner; | ||||
|   int count; | ||||
| } __libc_lock_recursive_t; | ||||
| 
 | ||||
| #define __libc_lock_owner_self() ((void *) __hurd_threadvar_location (0)) | ||||
| 
 | ||||
| #else | ||||
| typedef struct __libc_lock_opaque__ __libc_lock_t; | ||||
| typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t; | ||||
| #endif | ||||
| 
 | ||||
| /* Define a lock variable NAME with storage class CLASS.  The lock must be
 | ||||
|    initialized with __libc_lock_init before it can be used (or define it | ||||
|    with __libc_lock_define_initialized, below).  Use `extern' for CLASS to | ||||
|    declare a lock defined in another module.  In public structure | ||||
|    definitions you must use a pointer to the lock structure (i.e., NAME | ||||
|    begins with a `*'), because its storage size will not be known outside | ||||
|    of libc.  */ | ||||
| #define __libc_lock_define(CLASS,NAME) \ | ||||
|   CLASS __libc_lock_t NAME; | ||||
| 
 | ||||
| /* Define an initialized lock variable NAME with storage class CLASS.  */ | ||||
| #define __libc_lock_define_initialized(CLASS,NAME) \ | ||||
|   CLASS __libc_lock_t NAME = MUTEX_INITIALIZER; | ||||
| 
 | ||||
| /* Initialize the named lock variable, leaving it in a consistent, unlocked
 | ||||
|    state.  */ | ||||
| #define __libc_lock_init(NAME) __mutex_init (&(NAME)) | ||||
| 
 | ||||
| /* Finalize the named lock variable, which must be locked.  It cannot be
 | ||||
|    used again until __libc_lock_init is called again on it.  This must be | ||||
|    called on a lock variable before the containing storage is reused.  */ | ||||
| #define __libc_lock_fini(NAME) __mutex_unlock (&(NAME)) | ||||
| #define __libc_lock_fini_recursive(NAME) __mutex_unlock (&(NAME).mutex) | ||||
| 
 | ||||
| 
 | ||||
| /* Lock the named lock variable.  */ | ||||
| #define __libc_lock_lock(NAME) __mutex_lock (&(NAME)) | ||||
| 
 | ||||
| /* Lock the named lock variable.  */ | ||||
| #define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME))) | ||||
| 
 | ||||
| /* Unlock the named lock variable.  */ | ||||
| #define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME)) | ||||
| 
 | ||||
| 
 | ||||
| #define __libc_lock_define_recursive(CLASS,NAME) \ | ||||
|   CLASS __libc_lock_recursive_t NAME; | ||||
| #define _LIBC_LOCK_RECURSIVE_INITIALIZER { MUTEX_INITIALIZER, 0, 0 } | ||||
| #define __libc_lock_define_initialized_recursive(CLASS,NAME) \ | ||||
|   CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER; | ||||
| 
 | ||||
| #define __libc_lock_init_recursive(NAME) \ | ||||
|   ({ __libc_lock_recursive_t *const __lock = &(NAME); \ | ||||
|      __lock->owner = 0; mutex_init (&__lock->mutex); }) | ||||
| 
 | ||||
| #define __libc_lock_trylock_recursive(NAME)				      \ | ||||
|   ({ __libc_lock_recursive_t *const __lock = &(NAME);			      \ | ||||
|      void *__self = __libc_lock_owner_self ();				      \ | ||||
|      __mutex_trylock (&__lock->mutex)					      \ | ||||
|      ? (__lock->owner = __self, __lock->count = 1, 0)			      \ | ||||
|      : __lock->owner == __self ? (++__lock->count, 0) : 1; }) | ||||
| 
 | ||||
| #define __libc_lock_lock_recursive(NAME)				      \ | ||||
|   ({ __libc_lock_recursive_t *const __lock = &(NAME);			      \ | ||||
|      void *__self = __libc_lock_owner_self ();				      \ | ||||
|      if (__mutex_trylock (&__lock->mutex)				      \ | ||||
| 	 || (__lock->owner != __self					      \ | ||||
| 	     && (__mutex_lock (&__lock->mutex), 1)))			      \ | ||||
|        __lock->owner = __self, __lock->count = 1;			      \ | ||||
|      else								      \ | ||||
|        ++__lock->count;							      \ | ||||
|   }) | ||||
| #define __libc_lock_unlock_recursive(NAME)				      \ | ||||
|   ({ __libc_lock_recursive_t *const __lock = &(NAME);			      \ | ||||
|      if (--__lock->count == 0)						      \ | ||||
|        {								      \ | ||||
| 	 __lock->owner = 0;						      \ | ||||
| 	 __mutex_unlock (&__lock->mutex);				      \ | ||||
|        }								      \ | ||||
|   }) | ||||
| 
 | ||||
| 
 | ||||
| /* XXX for now */ | ||||
| #define __libc_rwlock_define		__libc_lock_define | ||||
| #define __libc_rwlock_define_initialized __libc_lock_define_initialized | ||||
| #define __libc_rwlock_init		__libc_lock_init | ||||
| #define __libc_rwlock_fini		__libc_lock_fini | ||||
| #define __libc_rwlock_rdlock		__libc_lock_lock | ||||
| #define __libc_rwlock_wrlock		__libc_lock_lock | ||||
| #define __libc_rwlock_tryrdlock		__libc_lock_trylock | ||||
| #define __libc_rwlock_trywrlock		__libc_lock_trylock | ||||
| #define __libc_rwlock_unlock		__libc_lock_unlock | ||||
| 
 | ||||
| 
 | ||||
| /* Start a critical region with a cleanup function */ | ||||
| #define __libc_cleanup_region_start(DOIT, FCT, ARG)			    \ | ||||
| {									    \ | ||||
|   typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0;			    \ | ||||
|   typeof (ARG) __save_ARG = ARG;					    \ | ||||
|   /* close brace is in __libc_cleanup_region_end below. */ | ||||
| 
 | ||||
| /* End a critical region started with __libc_cleanup_region_start. */ | ||||
| #define __libc_cleanup_region_end(DOIT)					    \ | ||||
|   if ((DOIT) && __save_FCT != 0)					    \ | ||||
|     (*__save_FCT)(__save_ARG);						    \ | ||||
| } | ||||
| 
 | ||||
| /* Sometimes we have to exit the block in the middle.  */ | ||||
| #define __libc_cleanup_end(DOIT)					    \ | ||||
|   if ((DOIT) && __save_FCT != 0)					    \ | ||||
|     (*__save_FCT)(__save_ARG);						    \ | ||||
| 
 | ||||
| 
 | ||||
| #if (_CTHREADS_ - 0) | ||||
| 
 | ||||
| /* Use mutexes as once control variables. */ | ||||
| 
 | ||||
| struct __libc_once | ||||
|   { | ||||
|     __libc_lock_t lock; | ||||
|     int done; | ||||
|   }; | ||||
| 
 | ||||
| #define __libc_once_define(CLASS,NAME) \ | ||||
|   CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 } | ||||
| 
 | ||||
| /* Call handler iff the first call.  */ | ||||
| #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \ | ||||
|   do {									      \ | ||||
|     __libc_lock_lock (ONCE_CONTROL.lock);				      \ | ||||
|     if (!ONCE_CONTROL.done)						      \ | ||||
|       (INIT_FUNCTION) ();						      \ | ||||
|     ONCE_CONTROL.done = 1;						      \ | ||||
|     __libc_lock_unlock (ONCE_CONTROL.lock);				      \ | ||||
|   } while (0) | ||||
| 
 | ||||
| #ifdef _LIBC | ||||
| /* We need portable names for some functions.  E.g., when they are
 | ||||
|    used as argument to __libc_cleanup_region_start.  */ | ||||
| #define __libc_mutex_unlock __mutex_unlock | ||||
| #endif | ||||
| 
 | ||||
| /* Type for key of thread specific data.  */ | ||||
| typedef cthread_key_t __libc_key_t; | ||||
| 
 | ||||
| #define __libc_key_create(KEY,DEST) cthread_keycreate (KEY) | ||||
| #define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL) | ||||
| void *__libc_getspecific (__libc_key_t key); | ||||
| 
 | ||||
| #endif /* _CTHREADS_ */ | ||||
| 
 | ||||
| #endif	/* bits/libc-lock.h */ | ||||
|  | @ -1,65 +0,0 @@ | |||
| /* Thread package specific definitions of stream lock type.  Hurd version.
 | ||||
|    Copyright (C) 2000, 2001 Free Software Foundation, Inc. | ||||
|    This file is part of the GNU C Library. | ||||
| 
 | ||||
|    The GNU C Library is free software; you can redistribute it and/or | ||||
|    modify it under the terms of the GNU Lesser General Public | ||||
|    License as published by the Free Software Foundation; either | ||||
|    version 2.1 of the License, or (at your option) any later version. | ||||
| 
 | ||||
|    The GNU C Library 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 | ||||
|    Lesser General Public License for more details. | ||||
| 
 | ||||
|    You should have received a copy of the GNU Lesser General Public | ||||
|    License along with the GNU C Library; if not, write to the Free | ||||
|    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||||
|    02111-1307 USA.  */ | ||||
| 
 | ||||
| #ifndef _BITS_STDIO_LOCK_H | ||||
| #define _BITS_STDIO_LOCK_H 1 | ||||
| 
 | ||||
| /* We need recursive (counting) mutexes.  Since cthreads doesn't really
 | ||||
|    have them, we implement them just for libio.  The implementation is | ||||
|    partially here and partially in Hurd's version of cthreads (i.e. the | ||||
|    libthreads library, libthreads/lockfile.c).  */ | ||||
| 
 | ||||
| #if (_LIBC - 0) || (_CTHREADS_ - 0) | ||||
| #include <cthreads.h> | ||||
| 
 | ||||
| struct _IO_cthreads_lock | ||||
| { | ||||
|   struct mutex mutex; | ||||
|   cthread_t owner; | ||||
|   unsigned int count; | ||||
| }; | ||||
| #else | ||||
| struct _IO_cthreads_lock; | ||||
| #endif | ||||
| typedef struct _IO_cthreads_lock _IO_lock_t; | ||||
| 
 | ||||
| #define _IO_lock_initializer	{ MUTEX_INITIALIZER, 0, 0 } | ||||
| 
 | ||||
| #define _IO_lock_init(_name) ({ (_name) = (_IO_lock_t) _IO_lock_initializer; }) | ||||
| #define _IO_lock_fini(_name) ((void) 0)	/* nothing to do */ | ||||
| 
 | ||||
| /* These are in fact only used for `list_all_lock' (libio/genops.c),
 | ||||
|    which does not need a recursive lock.  The per-FILE locks are only | ||||
|    accessed through _IO_flockfile et al, which Hurd's libthreads overrides.  */ | ||||
| #define _IO_lock_lock(_name) __libc_lock_lock ((_name).mutex) | ||||
| #define _IO_lock_unlock(_name) __libc_lock_unlock ((_name).mutex) | ||||
| 
 | ||||
| #ifdef _LIBC | ||||
| #include <bits/libc-lock.h> | ||||
| 
 | ||||
| #define _IO_cleanup_region_start(_fct, _fp) \ | ||||
|      __libc_cleanup_region_start (_fct, _fp) | ||||
| #define _IO_cleanup_region_start_noarg(_fct) \ | ||||
|      __libc_cleanup_region_start (_fct, NULL) | ||||
| #define _IO_cleanup_region_end(_doit) \ | ||||
|      __libc_cleanup_region_end (_doit) | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| #endif /* bits/stdio-lock.h */ | ||||
		Loading…
	
		Reference in New Issue