From f51faeb168840a62cee5baae1b150f0175f473d1 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Sun, 27 Feb 2005 21:58:21 +0000 Subject: [PATCH] - Added more semaphore locking around the basic stdio, memory, locale and dirent data operations. That should do it! While the library is not reentrant (this is not ixemul.library) it should be thread-safe now. Thread-safe in the sense of POSIX 1003.1c-1995. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@14842 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 3 +- library/GNUmakefile.os4 | 3 +- library/changes | 5 ++ library/ctype_isalnum.c | 6 +- library/ctype_isalpha.c | 6 +- library/ctype_iscntrl.c | 6 +- library/ctype_isdigit.c | 6 +- library/ctype_isgraph.c | 6 +- library/ctype_islower.c | 6 +- library/ctype_isprint.c | 6 +- library/ctype_ispunct.c | 6 +- library/ctype_isspace.c | 6 +- library/ctype_isupper.c | 6 +- library/ctype_isxdigit.c | 6 +- library/ctype_tolower.c | 6 +- library/ctype_toupper.c | 6 +- library/dirent_closedir.c | 6 +- library/dirent_data.c | 47 +++++++++++++- library/dirent_headers.h | 7 ++- library/dirent_opendir.c | 6 +- library/fcntl_fcntl.c | 14 ++++- library/fcntl_open.c | 6 +- library/locale_headers.h | 4 +- library/locale_init_exit.c | 58 +++++++++++++++-- library/locale_localeconv.c | 13 +++- library/locale_setlocale.c | 6 +- library/smakefile | 3 +- library/socket_accept.c | 6 +- library/socket_select.c | 6 +- library/socket_socket.c | 6 +- library/stdio_fflush.c | 15 ++++- library/stdio_fgetc.c | 5 +- library/stdio_filliobreadbuffer.c | 18 ++++-- library/stdio_findvacantfdentry.c | 6 +- library/stdio_findvacantiobentry.c | 6 +- library/stdio_fopen.c | 6 +- library/stdio_fwrite.c | 6 +- library/stdio_get_file_descriptor.c | 6 +- library/stdio_init_exit.c | 7 ++- library/stdio_lock.c | 96 +++++++++++++++++++++++++++++ library/stdio_openiob.c | 12 ++-- library/stdio_protos.h | 10 ++- library/stdio_vfscanf.c | 6 +- library/stdlib_free.c | 17 ++++- library/stdlib_headers.h | 9 +-- library/stdlib_init_exit.c | 10 +-- library/stdlib_malloc.c | 44 +++++++++++-- library/stdlib_protos.h | 6 +- library/stdlib_stackextension.c | 18 +++++- library/stdlib_strtod.c | 7 ++- library/string_strcoll.c | 6 +- library/string_strxfrm.c | 6 +- library/time_convert_datestamp.c | 6 +- library/time_convert_time.c | 6 +- library/time_gettimeofday.c | 6 +- library/time_localtime_r.c | 6 +- library/time_mktime.c | 6 +- library/time_strftime.c | 10 ++- library/unistd_dup2.c | 6 +- library/unistd_fdopen.c | 12 ++-- library/usergroup_init_exit.c | 10 +-- 61 files changed, 576 insertions(+), 91 deletions(-) create mode 100644 library/stdio_lock.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index 88d2e52..2593d23 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.30 2005-02-27 18:09:07 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.31 2005-02-27 21:58:20 obarthel Exp $ # # :ts=8 # @@ -223,6 +223,7 @@ C_LIB = \ stdio_initializeiob.o \ stdio_init_exit.o \ stdio_iobhookentry.o \ + stdio_lock.o \ stdio_locksemaphorename.o \ stdio_nostdio.o \ stdio_openiob.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index 06cdbc7..6b343d6 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.30 2005-02-27 18:09:10 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.31 2005-02-27 21:58:21 obarthel Exp $ # # :ts=8 # @@ -227,6 +227,7 @@ C_LIB = \ stdio_initializeiob.o \ stdio_init_exit.o \ stdio_iobhookentry.o \ + stdio_lock.o \ stdio_locksemaphorename.o \ stdio_nostdio.o \ stdio_openiob.o \ diff --git a/library/changes b/library/changes index 7eabf62..bc3a679 100644 --- a/library/changes +++ b/library/changes @@ -62,6 +62,11 @@ - Added flockfile()/funlockfile() wrappers around all stdio functions. +- Added more semaphore locking around the basic stdio, memory, locale + and dirent data operations. That should do it! While the library is + not reentrant (this is not ixemul.library) it should be thread-safe + now. Thread-safe in the sense of POSIX 1003.1c-1995. + c.lib 1.188 (7.2.2005) diff --git a/library/ctype_isalnum.c b/library/ctype_isalnum.c index 04d9149..61ba6c3 100644 --- a/library/ctype_isalnum.c +++ b/library/ctype_isalnum.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isalnum.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isalnum.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -49,6 +49,8 @@ isalnum(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -60,5 +62,7 @@ isalnum(int c) result = isalpha(c) || isdigit(c); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_isalpha.c b/library/ctype_isalpha.c index 088d24b..4ffd11f 100644 --- a/library/ctype_isalpha.c +++ b/library/ctype_isalpha.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isalpha.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isalpha.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ isalpha(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -59,5 +61,7 @@ isalpha(int c) ('A' <= c && c <= 'Z')); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_iscntrl.c b/library/ctype_iscntrl.c index 3392cbe..33965fb 100644 --- a/library/ctype_iscntrl.c +++ b/library/ctype_iscntrl.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_iscntrl.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_iscntrl.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ iscntrl(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -58,5 +60,7 @@ iscntrl(int c) result = (('\0' <= c && c < ' ') || (c == 127)); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_isdigit.c b/library/ctype_isdigit.c index 2859e37..db22bb0 100644 --- a/library/ctype_isdigit.c +++ b/library/ctype_isdigit.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isdigit.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isdigit.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ isdigit(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -58,5 +60,7 @@ isdigit(int c) result = ('0' <= c && c <= '9'); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_isgraph.c b/library/ctype_isgraph.c index cfb15a5..06aaa0a 100644 --- a/library/ctype_isgraph.c +++ b/library/ctype_isgraph.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isgraph.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isgraph.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ isgraph(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -58,5 +60,7 @@ isgraph(int c) result = (' ' < c && c < 127); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_islower.c b/library/ctype_islower.c index 1ddc3e3..684bf84 100644 --- a/library/ctype_islower.c +++ b/library/ctype_islower.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_islower.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_islower.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ islower(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -58,5 +60,7 @@ islower(int c) result = ('a' <= c && c <= 'z'); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_isprint.c b/library/ctype_isprint.c index 735ed5e..647e60e 100644 --- a/library/ctype_isprint.c +++ b/library/ctype_isprint.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isprint.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isprint.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ isprint(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -58,5 +60,7 @@ isprint(int c) result = (' ' <= c && c <= '~'); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_ispunct.c b/library/ctype_ispunct.c index 77c92ce..371af72 100644 --- a/library/ctype_ispunct.c +++ b/library/ctype_ispunct.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_ispunct.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_ispunct.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ ispunct(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -61,5 +63,7 @@ ispunct(int c) ('{' <= c && c <= '~')); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_isspace.c b/library/ctype_isspace.c index 6154bb7..43111cf 100644 --- a/library/ctype_isspace.c +++ b/library/ctype_isspace.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isspace.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isspace.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ isspace(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -63,5 +65,7 @@ isspace(int c) c == ' '); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_isupper.c b/library/ctype_isupper.c index 6d7c8b6..5a32a60 100644 --- a/library/ctype_isupper.c +++ b/library/ctype_isupper.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isupper.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isupper.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ isupper(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -58,5 +60,7 @@ isupper(int c) result = ('A' <= c && c <= 'Z'); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_isxdigit.c b/library/ctype_isxdigit.c index 21d9f0b..414b77f 100644 --- a/library/ctype_isxdigit.c +++ b/library/ctype_isxdigit.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_isxdigit.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_isxdigit.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -47,6 +47,8 @@ isxdigit(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -60,5 +62,7 @@ isxdigit(int c) ('A' <= c && c <= 'F')); } + __locale_unlock(); + return(result); } diff --git a/library/ctype_tolower.c b/library/ctype_tolower.c index 921d991..0cc9476 100644 --- a/library/ctype_tolower.c +++ b/library/ctype_tolower.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_tolower.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_tolower.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -43,6 +43,8 @@ tolower(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -54,5 +56,7 @@ tolower(int c) result = ('A' <= c && c <= 'Z') ? (c + ('a' - 'A')) : c; } + __locale_unlock(); + return(result); } diff --git a/library/ctype_toupper.c b/library/ctype_toupper.c index 85d2a3e..9f09e5e 100644 --- a/library/ctype_toupper.c +++ b/library/ctype_toupper.c @@ -1,5 +1,5 @@ /* - * $Id: ctype_toupper.c,v 1.2 2005-01-02 09:07:07 obarthel Exp $ + * $Id: ctype_toupper.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -43,6 +43,8 @@ toupper(int c) DECLARE_LOCALEBASE(); int result; + __locale_lock(); + if(__locale_table[LC_CTYPE] != NULL) { assert( LocaleBase != NULL ); @@ -54,5 +56,7 @@ toupper(int c) result = ('a' <= c && c <= 'z') ? (c - ('a' - 'A')) : c; } + __locale_unlock(); + return(result); } diff --git a/library/dirent_closedir.c b/library/dirent_closedir.c index 697b45f..4c12cf3 100644 --- a/library/dirent_closedir.c +++ b/library/dirent_closedir.c @@ -1,5 +1,5 @@ /* - * $Id: dirent_closedir.c,v 1.6 2005-02-21 16:09:28 obarthel Exp $ + * $Id: dirent_closedir.c,v 1.7 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -60,6 +60,8 @@ closedir(DIR * directory_pointer) if(__check_abort_enabled) __check_abort(); + __dirent_lock(); + if(directory_pointer == NULL) { __set_errno(EBADF); @@ -112,6 +114,8 @@ closedir(DIR * directory_pointer) out: + __dirent_unlock(); + RETURN(result); return(result); } diff --git a/library/dirent_data.c b/library/dirent_data.c index 7ba3d6d..e4d4659 100644 --- a/library/dirent_data.c +++ b/library/dirent_data.c @@ -1,5 +1,5 @@ /* - * $Id: dirent_data.c,v 1.5 2005-01-02 09:07:07 obarthel Exp $ + * $Id: dirent_data.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -42,14 +42,52 @@ struct MinList NOCOMMON __directory_list; /****************************************************************************/ +static struct SignalSemaphore * dirent_lock; + +/****************************************************************************/ + +void +__dirent_lock(void) +{ + if(dirent_lock != NULL) + ObtainSemaphore(dirent_lock); +} + +/****************************************************************************/ + +void +__dirent_unlock(void) +{ + if(dirent_lock != NULL) + ReleaseSemaphore(dirent_lock); +} + +/****************************************************************************/ + CLIB_CONSTRUCTOR(__dirent_init) { + BOOL success = FALSE; + ENTER(); NewList((struct List *)&__directory_list); - RETURN(OK); - CONSTRUCTOR_SUCCEED(); + dirent_lock = AllocVec(sizeof(*dirent_lock),MEMF_ANY|MEMF_PUBLIC); + if(dirent_lock == NULL) + goto out; + + InitSemaphore(dirent_lock); + + success = TRUE; + + out: + + RETURN(success); + + if(success) + CONSTRUCTOR_SUCCEED(); + else + CONSTRUCTOR_FAIL(); } /****************************************************************************/ @@ -64,5 +102,8 @@ CLIB_DESTRUCTOR(__dirent_exit) closedir((DIR *)__directory_list.mlh_Head); } + FreeVec(dirent_lock); + dirent_lock = NULL; + LEAVE(); } diff --git a/library/dirent_headers.h b/library/dirent_headers.h index df7abe2..71c1e63 100644 --- a/library/dirent_headers.h +++ b/library/dirent_headers.h @@ -1,5 +1,5 @@ /* - * $Id: dirent_headers.h,v 1.5 2005-02-03 16:56:15 obarthel Exp $ + * $Id: dirent_headers.h,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -73,4 +73,9 @@ extern struct MinList NOCOMMON __directory_list; /****************************************************************************/ +extern void __dirent_lock(void); +extern void __dirent_unlock(void); + +/****************************************************************************/ + #endif /* _DIRENT_HEADERS_H */ diff --git a/library/dirent_opendir.c b/library/dirent_opendir.c index 79569f0..0848752 100644 --- a/library/dirent_opendir.c +++ b/library/dirent_opendir.c @@ -1,5 +1,5 @@ /* - * $Id: dirent_opendir.c,v 1.7 2005-02-25 10:14:21 obarthel Exp $ + * $Id: dirent_opendir.c,v 1.8 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -244,8 +244,12 @@ opendir(const char * path_name) assert( __directory_list.mlh_Head != NULL ); + __dirent_lock(); + AddTail((struct List *)&__directory_list,(struct Node *)dh); + __dirent_unlock(); + result = (DIR *)dh; dh = NULL; diff --git a/library/fcntl_fcntl.c b/library/fcntl_fcntl.c index 8555bb9..eee8bf5 100644 --- a/library/fcntl_fcntl.c +++ b/library/fcntl_fcntl.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_fcntl.c,v 1.9 2005-02-20 13:19:40 obarthel Exp $ + * $Id: fcntl_fcntl.c,v 1.10 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -214,17 +214,25 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) goto out; } + __stdio_lock(); + /* Check if we have that many fd's already */ while(fdbase >= __num_fd) { + __stdio_unlock(); + if(__check_abort_enabled) __check_abort(); /* No; enlarge it */ if(__grow_fd_table() < 0) goto out; + + __stdio_lock(); } + __stdio_unlock(); + vacant_slot = -1; /* Guaranteed to have enough here */ @@ -233,6 +241,8 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + for(i = fdbase ; i < __num_fd ; i++) { if(FLAG_IS_CLEAR(__fd[i]->fd_Flags,FDF_IN_USE)) @@ -242,6 +252,8 @@ fcntl(int file_descriptor, int cmd, ... /* int arg */ ) } } + __stdio_unlock(); + /* Didn't really find any, grow the table further */ if(vacant_slot < 0 && __grow_fd_table() < 0) goto out; diff --git a/library/fcntl_open.c b/library/fcntl_open.c index 088c892..483fbd5 100644 --- a/library/fcntl_open.c +++ b/library/fcntl_open.c @@ -1,5 +1,5 @@ /* - * $Id: fcntl_open.c,v 1.10 2005-02-25 10:14:21 obarthel Exp $ + * $Id: fcntl_open.c,v 1.11 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -117,6 +117,8 @@ open(const char *path_name, int open_flag, ... /* mode_t mode */ ) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(path_name == NULL) @@ -449,6 +451,8 @@ open(const char *path_name, int open_flag, ... /* mode_t mode */ ) UnLock(lock); + __stdio_unlock(); + PROFILE_ON(); RETURN(result); diff --git a/library/locale_headers.h b/library/locale_headers.h index e82e665..336a321 100644 --- a/library/locale_headers.h +++ b/library/locale_headers.h @@ -1,5 +1,5 @@ /* - * $Id: locale_headers.h,v 1.4 2005-02-03 16:56:15 obarthel Exp $ + * $Id: locale_headers.h,v 1.5 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -78,6 +78,8 @@ extern char NOCOMMON __locale_name_table[NUM_LOCALES][MAX_LOCALE_NAME_LEN]; /****************************************************************************/ +extern void __locale_lock(void); +extern void __locale_unlock(void); extern void __close_all_locales(void); /****************************************************************************/ diff --git a/library/locale_init_exit.c b/library/locale_init_exit.c index 67db427..520de7d 100644 --- a/library/locale_init_exit.c +++ b/library/locale_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: locale_init_exit.c,v 1.5 2005-02-25 10:14:21 obarthel Exp $ + * $Id: locale_init_exit.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -41,6 +41,10 @@ /****************************************************************************/ +static struct SignalSemaphore * locale_lock; + +/****************************************************************************/ + struct Library * NOCOMMON __LocaleBase; /****************************************************************************/ @@ -63,6 +67,8 @@ char NOCOMMON __locale_name_table[NUM_LOCALES][MAX_LOCALE_NAME_LEN]; void __close_all_locales(void) { + __locale_lock(); + if(__LocaleBase != NULL) { DECLARE_LOCALEBASE(); @@ -86,8 +92,9 @@ __close_all_locales(void) CloseLocale(__locale_table[LC_ALL]); __locale_table[LC_ALL] = NULL; } -} + __locale_unlock(); +} /****************************************************************************/ @@ -96,6 +103,8 @@ __locale_exit(void) { ENTER(); + __locale_lock(); + if(__LocaleBase != NULL) { DECLARE_LOCALEBASE(); @@ -122,6 +131,8 @@ __locale_exit(void) __LocaleBase = NULL; } + __locale_unlock(); + LEAVE(); } @@ -136,6 +147,8 @@ __locale_init(void) PROFILE_OFF(); + __locale_lock(); + if(__LocaleBase == NULL) { __LocaleBase = OpenLibrary("locale.library",38); @@ -165,6 +178,8 @@ __locale_init(void) if(__default_locale != NULL) result = 0; + __locale_unlock(); + PROFILE_ON(); RETURN(result); @@ -173,12 +188,33 @@ __locale_init(void) /****************************************************************************/ +void +__locale_lock(void) +{ + if(locale_lock != NULL) + ObtainSemaphore(locale_lock); +} + +/****************************************************************************/ + +void +__locale_unlock(void) +{ + if(locale_lock != NULL) + ReleaseSemaphore(locale_lock); +} + +/****************************************************************************/ + CLIB_DESTRUCTOR(__locale_exit_destructor) { ENTER(); __locale_exit(); + FreeVec(locale_lock); + locale_lock = NULL; + LEAVE(); } @@ -186,17 +222,31 @@ CLIB_DESTRUCTOR(__locale_exit_destructor) CLIB_CONSTRUCTOR(__locale_init_constructor) { + BOOL success = FALSE; int i; ENTER(); + locale_lock = AllocVec(sizeof(*locale_lock),MEMF_ANY|MEMF_PUBLIC); + if(locale_lock == NULL) + goto out; + + InitSemaphore(locale_lock); + for(i = 0 ; i < NUM_LOCALES ; i++) strcpy(__locale_name_table[i],"C"); if(__open_locale) __locale_init(); - RETURN(OK); + success = TRUE; - CONSTRUCTOR_SUCCEED(); + out: + + RETURN(success); + + if(success) + CONSTRUCTOR_SUCCEED(); + else + CONSTRUCTOR_FAIL(); } diff --git a/library/locale_localeconv.c b/library/locale_localeconv.c index b9d6818..a11ef52 100644 --- a/library/locale_localeconv.c +++ b/library/locale_localeconv.c @@ -1,5 +1,5 @@ /* - * $Id: locale_localeconv.c,v 1.3 2005-02-25 10:14:21 obarthel Exp $ + * $Id: locale_localeconv.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -42,12 +42,17 @@ localeconv(void) { static struct lconv loc; - struct Locale * numeric_locale = __locale_table[LC_NUMERIC]; - struct Locale * monetary_locale = __locale_table[LC_MONETARY]; + struct Locale * numeric_locale; + struct Locale * monetary_locale; struct lconv * result; ENTER(); + __locale_lock(); + + numeric_locale = __locale_table[LC_NUMERIC]; + monetary_locale = __locale_table[LC_MONETARY]; + /* This makes up the current locale settings from the various * components in use. */ @@ -72,6 +77,8 @@ localeconv(void) result = &loc; + __locale_unlock(); + RETURN(result); return(result); } diff --git a/library/locale_setlocale.c b/library/locale_setlocale.c index 755a698..70afc97 100644 --- a/library/locale_setlocale.c +++ b/library/locale_setlocale.c @@ -1,5 +1,5 @@ /* - * $Id: locale_setlocale.c,v 1.3 2005-02-03 16:56:15 obarthel Exp $ + * $Id: locale_setlocale.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -52,6 +52,8 @@ setlocale(int category, const char *locale) else SHOWSTRING(locale); + __locale_lock(); + if(category < LC_ALL || category > LC_TIME) { SHOWMSG("invalid category"); @@ -155,6 +157,8 @@ setlocale(int category, const char *locale) out: + __locale_unlock(); + RETURN(result); return(result); } diff --git a/library/smakefile b/library/smakefile index 34c0f3e..423d239 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ _# -# $Id: smakefile,v 1.24 2005-02-27 18:09:10 obarthel Exp $ +# $Id: smakefile,v 1.25 2005-02-27 21:58:21 obarthel Exp $ # # :ts=8 # @@ -330,6 +330,7 @@ STDIO_OBJ = \ stdio_initializeiob.o \ stdio_init_exit.o \ stdio_iobhookentry.o \ + stdio_lock.o \ stdio_locksemaphorename.o \ stdio_nostdio.o \ stdio_openiob.o \ diff --git a/library/socket_accept.c b/library/socket_accept.c index b6e8c95..e169dd3 100644 --- a/library/socket_accept.c +++ b/library/socket_accept.c @@ -1,5 +1,5 @@ /* - * $Id: socket_accept.c,v 1.5 2005-02-20 13:19:40 obarthel Exp $ + * $Id: socket_accept.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -65,6 +65,8 @@ accept(int sockfd,struct sockaddr *cliaddr,int *addrlen) assert( cliaddr != NULL && addrlen != NULL ); assert(__SocketBase != NULL); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(cliaddr == NULL || addrlen == NULL) @@ -117,6 +119,8 @@ accept(int sockfd,struct sockaddr *cliaddr,int *addrlen) out: + __stdio_unlock(); + if(__check_abort_enabled) __check_abort(); diff --git a/library/socket_select.c b/library/socket_select.c index 566f34b..245deaa 100644 --- a/library/socket_select.c +++ b/library/socket_select.c @@ -1,5 +1,5 @@ /* - * $Id: socket_select.c,v 1.5 2005-02-25 10:14:21 obarthel Exp $ + * $Id: socket_select.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -145,6 +145,8 @@ get_file_descriptor(int file_descriptor) struct fd * result = NULL; struct fd * fd; + __stdio_lock(); + if(file_descriptor < 0 || file_descriptor >= __num_fd) goto out; @@ -161,6 +163,8 @@ get_file_descriptor(int file_descriptor) out: + __stdio_unlock(); + return(result); } diff --git a/library/socket_socket.c b/library/socket_socket.c index 18ddef9..b2bd0be 100644 --- a/library/socket_socket.c +++ b/library/socket_socket.c @@ -1,5 +1,5 @@ /* - * $Id: socket_socket.c,v 1.3 2005-02-20 13:19:40 obarthel Exp $ + * $Id: socket_socket.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -55,6 +55,8 @@ socket(int domain,int type,int protocol) SHOWVALUE(type); SHOWVALUE(protocol); + __stdio_lock(); + fd_slot_number = __find_vacant_fd_entry(); if(fd_slot_number < 0) { @@ -86,6 +88,8 @@ socket(int domain,int type,int protocol) out: + __stdio_unlock(); + if(__check_abort_enabled) __check_abort(); diff --git a/library/stdio_fflush.c b/library/stdio_fflush.c index 4dc66b1..00276e2 100644 --- a/library/stdio_fflush.c +++ b/library/stdio_fflush.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fflush.c,v 1.5 2005-02-27 18:09:10 obarthel Exp $ + * $Id: stdio_fflush.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -71,8 +71,11 @@ fflush(FILE *stream) } else { + int failed_iob = -1; int i; + __stdio_lock(); + /* Flush all streams which still have unwritten data in the buffer. */ for(i = 0 ; i < __num_iob ; i++) { @@ -82,9 +85,17 @@ fflush(FILE *stream) __iob_write_buffer_is_valid(__iob[i])) { if(__flush_iob_write_buffer(__iob[i]) < 0) - goto out; + { + failed_iob = i; + break; + } } } + + __stdio_unlock(); + + if(failed_iob >= 0) + goto out; } } #else diff --git a/library/stdio_fgetc.c b/library/stdio_fgetc.c index 582b17d..3e69e82 100644 --- a/library/stdio_fgetc.c +++ b/library/stdio_fgetc.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fgetc.c,v 1.5 2005-02-27 18:09:10 obarthel Exp $ + * $Id: stdio_fgetc.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -57,6 +57,9 @@ __fgetc(FILE *stream) if(__iob_read_buffer_is_empty(file)) { + if(__check_abort_enabled) + __check_abort(); + if(__fill_iob_read_buffer(file) < 0) goto out; diff --git a/library/stdio_filliobreadbuffer.c b/library/stdio_filliobreadbuffer.c index 155a7bb..5b42c62 100644 --- a/library/stdio_filliobreadbuffer.c +++ b/library/stdio_filliobreadbuffer.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_filliobreadbuffer.c,v 1.7 2005-02-21 10:21:48 obarthel Exp $ + * $Id: stdio_filliobreadbuffer.c,v 1.8 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -53,14 +53,14 @@ __fill_iob_read_buffer(struct iob * file) assert( FLAG_IS_SET(file->iob_Flags,IOBF_READ) ); assert( file->iob_BufferSize > 0 ); - if(__check_abort_enabled) - __check_abort(); - /* Flush all line buffered streams before we proceed to fill this buffer. */ if((file->iob_Flags & IOBF_BUFFER_MODE) == IOBF_BUFFER_MODE_LINE) { + int failed_iob = -1; int i; + __stdio_lock(); + for(i = 0 ; i < __num_iob ; i++) { if(__iob[i] != NULL && @@ -70,9 +70,17 @@ __fill_iob_read_buffer(struct iob * file) __iob_write_buffer_is_valid(__iob[i])) { if(__flush_iob_write_buffer(__iob[i]) < 0) - goto out; + { + failed_iob = i; + break; + } } } + + __stdio_unlock(); + + if(failed_iob >= 0) + goto out; } SHOWMSG("calling the hook"); diff --git a/library/stdio_findvacantfdentry.c b/library/stdio_findvacantfdentry.c index ee035ef..12d2bc6 100644 --- a/library/stdio_findvacantfdentry.c +++ b/library/stdio_findvacantfdentry.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_findvacantfdentry.c,v 1.2 2005-01-02 09:07:08 obarthel Exp $ + * $Id: stdio_findvacantfdentry.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -46,6 +46,8 @@ __is_valid_fd(struct fd * fd) { BOOL result = FALSE; + __stdio_lock(); + if(__fd != NULL && __num_fd > 0) { int i; @@ -60,6 +62,8 @@ __is_valid_fd(struct fd * fd) } } + __stdio_unlock(); + return(result); } diff --git a/library/stdio_findvacantiobentry.c b/library/stdio_findvacantiobentry.c index e6a934a..cb5132d 100644 --- a/library/stdio_findvacantiobentry.c +++ b/library/stdio_findvacantiobentry.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_findvacantiobentry.c,v 1.2 2005-01-02 09:07:08 obarthel Exp $ + * $Id: stdio_findvacantiobentry.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -53,8 +53,12 @@ __is_valid_iob(struct iob * iob) } else { + __stdio_lock(); + if(__iob != NULL && __num_iob > 0 && 0 <= iob->iob_SlotNumber && iob->iob_SlotNumber < __num_iob && __iob[iob->iob_SlotNumber] == iob) result = TRUE; + + __stdio_unlock(); } return(result); diff --git a/library/stdio_fopen.c b/library/stdio_fopen.c index 11619ac..27243f2 100644 --- a/library/stdio_fopen.c +++ b/library/stdio_fopen.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fopen.c,v 1.4 2005-02-27 18:09:10 obarthel Exp $ + * $Id: stdio_fopen.c,v 1.5 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -59,6 +59,8 @@ fopen(const char *filename, const char *mode) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(filename == NULL || mode == NULL) @@ -94,6 +96,8 @@ fopen(const char *filename, const char *mode) out: + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/stdio_fwrite.c b/library/stdio_fwrite.c index 82ab99c..2b62dba 100644 --- a/library/stdio_fwrite.c +++ b/library/stdio_fwrite.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_fwrite.c,v 1.6 2005-02-27 18:09:10 obarthel Exp $ + * $Id: stdio_fwrite.c,v 1.7 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -118,8 +118,12 @@ fwrite(const void *ptr,size_t element_size,size_t count,FILE *stream) buffer_mode = (file->iob_Flags & IOBF_BUFFER_MODE); if(buffer_mode == IOBF_BUFFER_MODE_NONE) { + __stdio_lock(); + if(FLAG_IS_SET(__fd[file->iob_Descriptor]->fd_Flags,FDF_IS_INTERACTIVE)) buffer_mode = IOBF_BUFFER_MODE_LINE; + + __stdio_unlock(); } if(buffer_mode == IOBF_BUFFER_MODE_LINE) diff --git a/library/stdio_get_file_descriptor.c b/library/stdio_get_file_descriptor.c index 27d547d..9915ab0 100644 --- a/library/stdio_get_file_descriptor.c +++ b/library/stdio_get_file_descriptor.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_get_file_descriptor.c,v 1.2 2005-01-02 09:07:08 obarthel Exp $ + * $Id: stdio_get_file_descriptor.c,v 1.3 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -43,6 +43,8 @@ __get_file_descriptor(int file_descriptor) struct fd * result = NULL; struct fd * fd; + __stdio_lock(); + if(file_descriptor < 0 || file_descriptor >= __num_fd) { SHOWMSG("invalid file descriptor"); @@ -66,5 +68,7 @@ __get_file_descriptor(int file_descriptor) out: + __stdio_unlock(); + return(result); } diff --git a/library/stdio_init_exit.c b/library/stdio_init_exit.c index 47e2bc0..85d6427 100644 --- a/library/stdio_init_exit.c +++ b/library/stdio_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_init_exit.c,v 1.18 2005-02-27 18:09:10 obarthel Exp $ + * $Id: stdio_init_exit.c,v 1.19 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -101,6 +101,8 @@ CLIB_DESTRUCTOR(__stdio_exit) __close_all_files(); + __stdio_lock_exit(); + LEAVE(); } @@ -121,6 +123,9 @@ __stdio_init(void) ENTER(); + if(__stdio_lock_init() < 0) + goto out; + __iob = malloc(sizeof(*__iob) * num_standard_files); if(__iob == NULL) goto out; diff --git a/library/stdio_lock.c b/library/stdio_lock.c new file mode 100644 index 0000000..3b33407 --- /dev/null +++ b/library/stdio_lock.c @@ -0,0 +1,96 @@ +/* + * $Id: stdio_lock.c,v 1.1 2005-02-27 21:58:21 obarthel Exp $ + * + * :ts=4 + * + * Portable ISO 'C' (1994) runtime library for the Amiga computer + * Copyright (c) 2002-2005 by Olaf Barthel + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Neither the name of Olaf Barthel nor the names of contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _STDIO_HEADERS_H +#include "stdio_headers.h" +#endif /* _STDIO_HEADERS_H */ + +/****************************************************************************/ + +static struct SignalSemaphore * stdio_lock; + +/****************************************************************************/ + +void +__stdio_lock(void) +{ + assert( stdio_lock != NULL ); + + if(stdio_lock != NULL) + ObtainSemaphore(stdio_lock); +} + +/****************************************************************************/ + +void +__stdio_unlock(void) +{ + assert( stdio_lock != NULL ); + + if(stdio_lock != NULL) + ReleaseSemaphore(stdio_lock); +} + +/****************************************************************************/ + +void +__stdio_lock_exit(void) +{ + assert( stdio_lock == NULL || stdio_lock->ss_Owner == NULL ); + + if(stdio_lock != NULL) + { + FreeVec(stdio_lock); + stdio_lock = NULL; + } +} + +/****************************************************************************/ + +int +__stdio_lock_init(void) +{ + int result = -1; + + stdio_lock = AllocVec(sizeof(*stdio_lock),MEMF_ANY|MEMF_PUBLIC); + if(stdio_lock == NULL) + goto out; + + InitSemaphore(stdio_lock); + + result = 0; + + out: + + return(result); +} diff --git a/library/stdio_openiob.c b/library/stdio_openiob.c index 8e1b560..20666e7 100644 --- a/library/stdio_openiob.c +++ b/library/stdio_openiob.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_openiob.c,v 1.8 2005-02-27 18:09:10 obarthel Exp $ + * $Id: stdio_openiob.c,v 1.9 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -61,15 +61,17 @@ __open_iob(const char *filename, const char *mode, int file_descriptor, int slot SHOWSTRING(mode); SHOWVALUE(slot_number); + if(__check_abort_enabled) + __check_abort(); + + __stdio_lock(); + assert( mode != NULL && 0 <= slot_number && slot_number < __num_iob ); file = __iob[slot_number]; assert( FLAG_IS_CLEAR(file->iob_Flags,IOBF_IN_USE) ); - if(__check_abort_enabled) - __check_abort(); - /* Figure out if the file descriptor provided is any use. */ if(file_descriptor >= 0) { @@ -197,6 +199,8 @@ __open_iob(const char *filename, const char *mode, int file_descriptor, int slot if(buffer != NULL) free(buffer); + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/stdio_protos.h b/library/stdio_protos.h index e6e0854..277afd7 100644 --- a/library/stdio_protos.h +++ b/library/stdio_protos.h @@ -1,5 +1,5 @@ /* - * $Id: stdio_protos.h,v 1.8 2005-02-27 18:09:10 obarthel Exp $ + * $Id: stdio_protos.h,v 1.9 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -215,4 +215,12 @@ extern void __remove_fd_alias(struct fd * fd); /****************************************************************************/ +/* stdio_lock.c */ +extern void __stdio_lock(void); +extern void __stdio_unlock(void); +extern void __stdio_lock_exit(void); +extern int __stdio_lock_init(void); + +/****************************************************************************/ + #endif /* _STDIO_PROTOS_H */ diff --git a/library/stdio_vfscanf.c b/library/stdio_vfscanf.c index 5a7a0e0..2003dba 100644 --- a/library/stdio_vfscanf.c +++ b/library/stdio_vfscanf.c @@ -1,5 +1,5 @@ /* - * $Id: stdio_vfscanf.c,v 1.10 2005-02-27 18:09:11 obarthel Exp $ + * $Id: stdio_vfscanf.c,v 1.11 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -616,6 +616,8 @@ __vfscanf(FILE *stream, const char *format, va_list arg) c = __getc(stream); if(c != EOF) { + __locale_lock(); + /* Did we find the decimal point? We accept both the * locale configured decimal point and the plain old * dot. @@ -651,6 +653,8 @@ __vfscanf(FILE *stream, const char *format, va_list arg) } } + __locale_unlock(); + if(decimal_point_matches) { total_num_chars_read++; diff --git a/library/stdlib_free.c b/library/stdlib_free.c index ef5050e..54216b2 100644 --- a/library/stdlib_free.c +++ b/library/stdlib_free.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_free.c,v 1.6 2005-02-25 10:14:21 obarthel Exp $ + * $Id: stdlib_free.c,v 1.7 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -261,12 +261,16 @@ __check_memory_allocations(const char * file,int line) { struct MemoryNode * mn; + __memory_lock(); + for(mn = (struct MemoryNode *)__memory_list.mlh_Head ; mn->mn_MinNode.mln_Succ != NULL ; mn = (struct MemoryNode *)mn->mn_MinNode.mln_Succ) { check_memory_node(mn,file,line); } + + __memory_unlock(); } /****************************************************************************/ @@ -278,6 +282,8 @@ __find_memory_node(void * address) assert( address != NULL ); + __memory_lock(); + #if defined(__USE_MEM_TREES) { result = __red_black_tree_find(&__memory_tree,address); @@ -301,6 +307,8 @@ __find_memory_node(void * address) } #endif /* __USE_MEM_TREES */ + __memory_unlock(); + return(result); } @@ -335,6 +343,8 @@ remove_and_free_memory_node(struct MemoryNode * mn) assert( mn != NULL ); + __memory_lock(); + Remove((struct Node *)mn); #if defined(__USE_MEM_TREES) && defined(__MEM_DEBUG) @@ -361,6 +371,8 @@ remove_and_free_memory_node(struct MemoryNode * mn) FreePooled(__memory_pool,mn,allocation_size); else FreeMem(mn,allocation_size); + + __memory_unlock(); } /****************************************************************************/ @@ -573,5 +585,8 @@ __memory_exit(void) } } + FreeVec(__memory_semaphore); + __memory_semaphore = NULL; + LEAVE(); } diff --git a/library/stdlib_headers.h b/library/stdlib_headers.h index 4940999..a4ba3bd 100644 --- a/library/stdlib_headers.h +++ b/library/stdlib_headers.h @@ -1,5 +1,5 @@ /* - * $Id: stdlib_headers.h,v 1.9 2005-02-27 18:09:11 obarthel Exp $ + * $Id: stdlib_headers.h,v 1.10 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -198,9 +198,10 @@ extern unsigned int NOCOMMON __random_seed; /****************************************************************************/ -extern struct MemoryTree NOCOMMON __memory_tree; -extern struct MinList NOCOMMON __memory_list; -extern APTR NOCOMMON __memory_pool; +extern struct SignalSemaphore * NOCOMMON __memory_semaphore; +extern struct MemoryTree NOCOMMON __memory_tree; +extern struct MinList NOCOMMON __memory_list; +extern APTR NOCOMMON __memory_pool; /****************************************************************************/ diff --git a/library/stdlib_init_exit.c b/library/stdlib_init_exit.c index 5d4c70b..bed7532 100644 --- a/library/stdlib_init_exit.c +++ b/library/stdlib_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_init_exit.c,v 1.4 2005-01-02 09:07:18 obarthel Exp $ + * $Id: stdlib_init_exit.c,v 1.5 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -64,10 +64,12 @@ __stdlib_exit(void) int __stdlib_init(void) { + int result; + ENTER(); - __memory_init(); + result = __memory_init(); - RETURN(OK); - return(OK); + RETURN(result); + return(result); } diff --git a/library/stdlib_malloc.c b/library/stdlib_malloc.c index 7c9a409..1687dac 100644 --- a/library/stdlib_malloc.c +++ b/library/stdlib_malloc.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_malloc.c,v 1.7 2005-02-03 16:56:16 obarthel Exp $ + * $Id: stdlib_malloc.c,v 1.8 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -63,8 +63,9 @@ struct MemoryTree __memory_tree; /****************************************************************************/ -APTR __memory_pool; -struct MinList __memory_list; +struct SignalSemaphore * NOCOMMON __memory_semaphore; +APTR NOCOMMON __memory_pool; +struct MinList NOCOMMON __memory_list; /****************************************************************************/ @@ -96,6 +97,8 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED file,int UNUSE assert( size > 0 ); + __memory_lock(); + if(__free_memory_threshold > 0 && AvailMem(MEMF_ANY|MEMF_LARGEST) < __free_memory_threshold) { SHOWMSG("not enough free memory available to safely proceed with allocation"); @@ -202,6 +205,8 @@ __allocate_memory(size_t size,BOOL never_free,const char * UNUSED file,int UNUSE } #endif /* __MEM_DEBUG_LOG */ + __memory_unlock(); + return(result); } @@ -263,10 +268,36 @@ malloc(size_t size) /****************************************************************************/ void +__memory_lock(void) +{ + if(__memory_semaphore != NULL) + ObtainSemaphore(__memory_semaphore); +} + +/****************************************************************************/ + +void +__memory_unlock(void) +{ + if(__memory_semaphore != NULL) + ReleaseSemaphore(__memory_semaphore); +} + +/****************************************************************************/ + +int __memory_init(void) { + int result = ERROR; + ENTER(); + __memory_semaphore = AllocVec(sizeof(*__memory_semaphore),MEMF_ANY|MEMF_PUBLIC); + if(__memory_semaphore == NULL) + goto out; + + InitSemaphore(__memory_semaphore); + #if defined(__USE_MEM_TREES) && defined(__MEM_DEBUG) { __initialize_red_black_tree(&__memory_tree); @@ -286,5 +317,10 @@ __memory_init(void) } #endif /* __amigaos4__ */ - LEAVE(); + result = OK; + + out: + + RETURN(result); + return(result); } diff --git a/library/stdlib_protos.h b/library/stdlib_protos.h index ace3018..2647bb4 100644 --- a/library/stdlib_protos.h +++ b/library/stdlib_protos.h @@ -1,5 +1,5 @@ /* - * $Id: stdlib_protos.h,v 1.7 2005-02-03 16:56:16 obarthel Exp $ + * $Id: stdlib_protos.h,v 1.8 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -138,9 +138,11 @@ extern int __startup_init(void); /****************************************************************************/ /* stdlib_malloc.c */ -extern void __memory_init(void); +extern int __memory_init(void); extern size_t __get_allocation_size(size_t size); extern void * __allocate_memory(size_t size,BOOL never_free,const char * file,int line); +extern void __memory_lock(void); +extern void __memory_unlock(void); /* stdlib_free.c */ extern void __memory_exit(void); diff --git a/library/stdlib_stackextension.c b/library/stdlib_stackextension.c index f9c916e..0a79e0e 100644 --- a/library/stdlib_stackextension.c +++ b/library/stdlib_stackextension.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_stackextension.c,v 1.5 2005-02-25 10:14:21 obarthel Exp $ + * $Id: stdlib_stackextension.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -356,9 +356,17 @@ pushframe(ULONG requiredstack, struct StackSwapStruct *sss) D(("allocating %ld bytes for a stack frame",recommendedstack + sizeof(struct stackframe))); if(__memory_pool != NULL) + { + __memory_lock(); + sf = AllocPooled(__memory_pool,recommendedstack + sizeof(struct stackframe)); + + __memory_unlock(); + } else + { sf = AllocMem(recommendedstack + sizeof(struct stackframe), MEMF_ANY); + } if (sf != NULL) break; @@ -381,9 +389,17 @@ pushframe(ULONG requiredstack, struct StackSwapStruct *sss) break; if(__memory_pool != NULL) + { + __memory_lock(); + FreePooled(__memory_pool, sf, (char *)sf->upper - (char *)sf); + + __memory_unlock(); + } else + { FreeMem(sf, (char *)sf->upper - (char *)sf); + } } /* Add stackframe to the used list */ diff --git a/library/stdlib_strtod.c b/library/stdlib_strtod.c index 6be4202..5d7a017 100644 --- a/library/stdlib_strtod.c +++ b/library/stdlib_strtod.c @@ -1,5 +1,5 @@ /* - * $Id: stdlib_strtod.c,v 1.3 2005-02-03 16:56:17 obarthel Exp $ + * $Id: stdlib_strtod.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -153,6 +153,9 @@ strtod(const char *str, char ** ptr) * dot. */ decimal_point_matches = 0; + + __locale_lock(); + if(__locale_table[LC_NUMERIC] != NULL) { char * point; @@ -167,6 +170,8 @@ strtod(const char *str, char ** ptr) } } + __locale_unlock(); + if(NOT decimal_point_matches) { if((*str) == '.') diff --git a/library/string_strcoll.c b/library/string_strcoll.c index 018b949..bb71bc7 100644 --- a/library/string_strcoll.c +++ b/library/string_strcoll.c @@ -1,5 +1,5 @@ /* - * $Id: string_strcoll.c,v 1.3 2005-02-03 16:56:17 obarthel Exp $ + * $Id: string_strcoll.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -65,6 +65,8 @@ strcoll(const char *s1, const char *s2) } #endif /* CHECK_FOR_NULL_POINTERS */ + __locale_lock(); + if(__locale_table[LC_COLLATE] != NULL) { assert( LocaleBase != NULL ); @@ -76,6 +78,8 @@ strcoll(const char *s1, const char *s2) result = strcmp(s1,s2); } + __locale_unlock(); + out: return(result); diff --git a/library/string_strxfrm.c b/library/string_strxfrm.c index f1d0388..611a242 100644 --- a/library/string_strxfrm.c +++ b/library/string_strxfrm.c @@ -1,5 +1,5 @@ /* - * $Id: string_strxfrm.c,v 1.3 2005-02-03 16:56:17 obarthel Exp $ + * $Id: string_strxfrm.c,v 1.4 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -73,6 +73,8 @@ strxfrm(char *dest, const char *src, size_t len) } #endif /* CHECK_FOR_NULL_POINTERS */ + __locale_lock(); + if(__locale_table[LC_COLLATE] != NULL) { assert( LocaleBase != NULL ); @@ -107,6 +109,8 @@ strxfrm(char *dest, const char *src, size_t len) } } + __locale_unlock(); + out: RETURN(result); diff --git a/library/time_convert_datestamp.c b/library/time_convert_datestamp.c index 0885af8..6061de2 100644 --- a/library/time_convert_datestamp.c +++ b/library/time_convert_datestamp.c @@ -1,5 +1,5 @@ /* - * $Id: time_convert_datestamp.c,v 1.1 2005-01-26 09:24:38 obarthel Exp $ + * $Id: time_convert_datestamp.c,v 1.2 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -48,6 +48,8 @@ __convert_datestamp_to_time(const struct DateStamp * ds) ENTER(); + __locale_lock(); + /* If possible, adjust for the local time zone. We do this because the AmigaOS system time is returned in local time and we want to return it in UTC. */ @@ -55,6 +57,8 @@ __convert_datestamp_to_time(const struct DateStamp * ds) if(__default_locale != NULL) result += 60 * __default_locale->loc_GMTOffset; + __locale_unlock(); + RETURN(result); return(result); } diff --git a/library/time_convert_time.c b/library/time_convert_time.c index 5b2132f..24a571b 100644 --- a/library/time_convert_time.c +++ b/library/time_convert_time.c @@ -1,5 +1,5 @@ /* - * $Id: time_convert_time.c,v 1.1 2005-01-29 18:22:19 obarthel Exp $ + * $Id: time_convert_time.c,v 1.2 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -56,10 +56,14 @@ __convert_time_to_datestamp(time_t time_value,struct DateStamp * ds) /* Adjust the time to the AmigaOS epoch. */ time_value -= UNIX_TIME_OFFSET; + __locale_lock(); + /* If possible, adjust the time to match the local time zone settings. */ if(__default_locale != NULL) time_value -= 60 * __default_locale->loc_GMTOffset; + __locale_unlock(); + ds->ds_Days = (time_value / (24 * 60 * 60)); ds->ds_Minute = (time_value % (24 * 60 * 60)) / 60; ds->ds_Tick = (time_value % 60) * TICKS_PER_SECOND; diff --git a/library/time_gettimeofday.c b/library/time_gettimeofday.c index 06ef410..a0643a0 100644 --- a/library/time_gettimeofday.c +++ b/library/time_gettimeofday.c @@ -1,5 +1,5 @@ /* - * $Id: time_gettimeofday.c,v 1.6 2005-01-30 09:37:59 obarthel Exp $ + * $Id: time_gettimeofday.c,v 1.7 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -81,6 +81,8 @@ gettimeofday(struct timeval *tp, struct timezone *tzp) seconds = tv.tv_sec + UNIX_TIME_OFFSET; microseconds = tv.tv_usec; + __locale_lock(); + /* If possible, adjust for the local time zone. We do this because the AmigaOS system time is returned in local time and we want to return it in UTC. */ @@ -111,6 +113,8 @@ gettimeofday(struct timeval *tp, struct timezone *tzp) SHOWVALUE(tzp->tz_dsttime); } + __locale_unlock(); + RETURN(0); return(0); } diff --git a/library/time_localtime_r.c b/library/time_localtime_r.c index 5358220..f898a08 100644 --- a/library/time_localtime_r.c +++ b/library/time_localtime_r.c @@ -1,5 +1,5 @@ /* - * $Id: time_localtime_r.c,v 1.4 2005-02-03 16:56:17 obarthel Exp $ + * $Id: time_localtime_r.c,v 1.5 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -67,6 +67,8 @@ localtime_r(const time_t *t,struct tm * tm_ptr) } #endif /* CHECK_FOR_NULL_POINTERS */ + __locale_lock(); + /* The time parameter given represents UTC and * must be converted to local time before we proceed. */ @@ -75,6 +77,8 @@ localtime_r(const time_t *t,struct tm * tm_ptr) else gmt_offset = 0; + __locale_unlock(); + SHOWVALUE(gmt_offset); result = __convert_time((*t), gmt_offset, tm_ptr); diff --git a/library/time_mktime.c b/library/time_mktime.c index 3ef79b0..cda7f12 100644 --- a/library/time_mktime.c +++ b/library/time_mktime.c @@ -1,5 +1,5 @@ /* - * $Id: time_mktime.c,v 1.7 2005-02-03 16:56:17 obarthel Exp $ + * $Id: time_mktime.c,v 1.8 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -182,11 +182,15 @@ mktime(struct tm *tm) tm->tm_yday = (seconds - delta) / (24 * 60 * 60); + __locale_lock(); + /* The data in 'struct tm *tm' was given in local time. We need to convert the result into UTC. */ if(__default_locale != NULL) seconds += 60 * __default_locale->loc_GMTOffset; + __locale_unlock(); + /* Finally, adjust for the difference between the Unix and the AmigaOS epochs, which differ by 8 years. */ result = seconds + UNIX_TIME_OFFSET; diff --git a/library/time_strftime.c b/library/time_strftime.c index db1688a..ebf6811 100644 --- a/library/time_strftime.c +++ b/library/time_strftime.c @@ -1,5 +1,5 @@ /* - * $Id: time_strftime.c,v 1.8 2005-02-25 10:14:21 obarthel Exp $ + * $Id: time_strftime.c,v 1.9 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -318,6 +318,8 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) store_string_via_hook("GMT",3,hook); + __locale_lock(); + if(__default_locale != NULL) { int hours_west_of_gmt; @@ -343,6 +345,8 @@ format_date(const char *format,const struct tm *tm,struct Hook * hook) } } + __locale_unlock(); + break; /* Store that character 'as is'. */ @@ -408,6 +412,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *tm) hook.h_Data = &data; + __locale_lock(); + /* Try to use the locale.library date/time conversion function. */ if(__locale_table[LC_TIME] != NULL) { @@ -455,6 +461,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *tm) format_date(format,tm,&hook); } + __locale_unlock(); + (*data.buffer) = '\0'; SHOWSTRING(s); diff --git a/library/unistd_dup2.c b/library/unistd_dup2.c index c371d1b..cf5ac0e 100644 --- a/library/unistd_dup2.c +++ b/library/unistd_dup2.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_dup2.c,v 1.6 2005-02-20 13:19:40 obarthel Exp $ + * $Id: unistd_dup2.c,v 1.7 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -55,6 +55,8 @@ dup2(int file_descriptor1, int file_descriptor2) if(__check_abort_enabled) __check_abort(); + __stdio_lock(); + assert( file_descriptor1 >= 0 && file_descriptor1 < __num_fd ); assert( __fd[file_descriptor1] != NULL ); assert( FLAG_IS_SET(__fd[file_descriptor1]->fd_Flags,FDF_IN_USE) ); @@ -126,6 +128,8 @@ dup2(int file_descriptor1, int file_descriptor2) out: + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/unistd_fdopen.c b/library/unistd_fdopen.c index a569f4b..2a7bf5c 100644 --- a/library/unistd_fdopen.c +++ b/library/unistd_fdopen.c @@ -1,5 +1,5 @@ /* - * $Id: unistd_fdopen.c,v 1.4 2005-02-03 16:56:17 obarthel Exp $ + * $Id: unistd_fdopen.c,v 1.5 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -60,6 +60,11 @@ fdopen(int file_descriptor, const char * type) assert(type != NULL); + if(__check_abort_enabled) + __check_abort(); + + __stdio_lock(); + #if defined(CHECK_FOR_NULL_POINTERS) { if(type == NULL) @@ -72,9 +77,6 @@ fdopen(int file_descriptor, const char * type) } #endif /* CHECK_FOR_NULL_POINTERS */ - if(__check_abort_enabled) - __check_abort(); - slot_number = __find_vacant_iob_entry(); if(slot_number < 0) { @@ -102,6 +104,8 @@ fdopen(int file_descriptor, const char * type) out: + __stdio_unlock(); + RETURN(result); return(result); } diff --git a/library/usergroup_init_exit.c b/library/usergroup_init_exit.c index da7c5ce..51122e6 100644 --- a/library/usergroup_init_exit.c +++ b/library/usergroup_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: usergroup_init_exit.c,v 1.5 2005-01-02 09:07:19 obarthel Exp $ + * $Id: usergroup_init_exit.c,v 1.6 2005-02-27 21:58:21 obarthel Exp $ * * :ts=4 * @@ -88,7 +88,7 @@ CLIB_DESTRUCTOR(__usergroup_exit) CLIB_CONSTRUCTOR(__usergroup_init) { struct TagItem tags[2]; - int result = ERROR; + BOOL success = FALSE; ENTER(); @@ -132,15 +132,15 @@ CLIB_CONSTRUCTOR(__usergroup_init) goto out; } - result = OK; + success = TRUE; out: PROFILE_ON(); - RETURN(result); + RETURN(success); - if(result == OK) + if(success) CONSTRUCTOR_SUCCEED(); else CONSTRUCTOR_FAIL();