From 090753282b41cd229411e4d46c85e35e6a4c2c98 Mon Sep 17 00:00:00 2001 From: Olaf Barthel Date: Mon, 17 Oct 2005 13:54:25 +0000 Subject: [PATCH] - Added __set_h_errno() and __get_h_errno() functions. - The thread-safe library now tries to enable bsdsocket.library base sharing and attempts to make the TCP/IP stack call the local __set_errno() and __set_h_errno(), so that any Process calling the library functions will get a chance to see proper error codes. Whether any of these features could be enabled can be tested through two global variables __can_share_socket_library_base and __thread_safe_errno_h_errno which are defined in . Note that for both features to work you will need the Roadshow bsdsocket.library version 4.275 or higher. git-svn-id: file:///Users/olsen/Code/migration-svn-zu-git/logical-line-staging/clib2/trunk@15048 87f5fb63-7c3d-0410-a384-fd976d0f7a62 --- library/GNUmakefile.68k | 4 +- library/GNUmakefile.os4 | 4 +- library/changes | 12 ++++ library/include/dos.h | 28 ++++++++- library/smakefile | 6 +- library/socket_get_h_errno.c | 44 ++++++++++++++ library/socket_headers.h | 4 +- library/socket_init_exit.c | 110 ++++++++++++++++++++++++++++++----- library/socket_set_h_errno.c | 44 ++++++++++++++ 9 files changed, 235 insertions(+), 21 deletions(-) create mode 100644 library/socket_get_h_errno.c create mode 100644 library/socket_set_h_errno.c diff --git a/library/GNUmakefile.68k b/library/GNUmakefile.68k index f628241..05cd611 100644 --- a/library/GNUmakefile.68k +++ b/library/GNUmakefile.68k @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.68k,v 1.70 2005-10-16 09:14:28 obarthel Exp $ +# $Id: GNUmakefile.68k,v 1.71 2005-10-17 13:54:25 obarthel Exp $ # # :ts=8 # @@ -766,6 +766,8 @@ NET_LIB = \ socket_socket.o \ socket_hook_entry.o \ socket_hstrerror.o \ + socket_get_h_errno.o \ + socket_set_h_errno.o \ stat_umask.o \ usergroup_crypt.o \ usergroup_data.o \ diff --git a/library/GNUmakefile.os4 b/library/GNUmakefile.os4 index b14a8f9..c689e93 100644 --- a/library/GNUmakefile.os4 +++ b/library/GNUmakefile.os4 @@ -1,5 +1,5 @@ # -# $Id: GNUmakefile.os4,v 1.79 2005-10-16 09:14:28 obarthel Exp $ +# $Id: GNUmakefile.os4,v 1.80 2005-10-17 13:54:25 obarthel Exp $ # # :ts=8 # @@ -737,6 +737,8 @@ NET_LIB = \ socket_socket.o \ socket_hook_entry.o \ socket_hstrerror.o \ + socket_get_h_errno.o \ + socket_set_h_errno.o \ stat_umask.o \ usergroup_crypt.o \ usergroup_data.o \ diff --git a/library/changes b/library/changes index 91fc3be..cccb908 100644 --- a/library/changes +++ b/library/changes @@ -11,6 +11,18 @@ - Replaced ldexp() and modf(). +- Added __set_h_errno() and __get_h_errno() functions. + +- The thread-safe library now tries to enable bsdsocket.library base + sharing and attempts to make the TCP/IP stack call the local + __set_errno() and __set_h_errno(), so that any Process calling + the library functions will get a chance to see proper error + codes. Whether any of these features could be enabled can be tested + through two global variables __can_share_socket_library_base and + __thread_safe_errno_h_errno which are defined in . Note that + for both features to work you will need the Roadshow bsdsocket.library + version 4.275 or higher. + c.lib 1.196 (11.10.2005) diff --git a/library/include/dos.h b/library/include/dos.h index 54f85f4..8b04d26 100644 --- a/library/include/dos.h +++ b/library/include/dos.h @@ -1,5 +1,5 @@ /* - * $Id: dos.h,v 1.11 2005-10-09 12:32:18 obarthel Exp $ + * $Id: dos.h,v 1.12 2005-10-17 13:54:25 obarthel Exp $ * * :ts=4 * @@ -364,6 +364,32 @@ extern BOOL __lib_init(struct Library * SysBase); /****************************************************************************/ +/* + * The following variables are part of libnet.a, which provides for + * a BSD-Unix-like socket networking API. Traditionally, only one process + * at a time may use the underlying bsdsocket.library base, but with a + * multithreaded application you may want all of them to share the same + * library base. As of this writing there is one single TCP/IP stack which + * supports this feature (Roadshow) and it must be enabled early on. If + * this worked out well you can test through the following variable which + * will be set to TRUE: + */ +extern BOOL __can_share_socket_library_base; + +/* + * The next global variable is also part of the thread-safe libnet.a and + * indicates that the TCP/IP stack will call the functions __set_errno() + * and __set_h_errno() when it modifies the global errno and h_errno + * variables, respectively. If you want to save the error codes for each + * of the Processes in your multithreaded application then you should + * override these functions with your. The following variable will be + * set to TRUE if the __set_errno() and __set_h_errno() functions will + * be used to change the corresponding variables: + */ +extern BOOL __thread_safe_errno_h_errno; + +/****************************************************************************/ + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/library/smakefile b/library/smakefile index 0ff3201..dc083c0 100644 --- a/library/smakefile +++ b/library/smakefile @@ -1,5 +1,5 @@ # -# $Id: smakefile,v 1.52 2005-10-16 09:14:28 obarthel Exp $ +# $Id: smakefile,v 1.53 2005-10-17 13:54:25 obarthel Exp $ # # :ts=8 # @@ -353,7 +353,9 @@ SOCKET_OBJ = \ socket_shutdown.o \ socket_socket.o \ socket_hook_entry.o \ - socket_hstrerror.o + socket_hstrerror.o \ + socket_get_h_errno.o \ + socket_set_h_errno.o STAT_OBJ = \ stat_chmod.o \ diff --git a/library/socket_get_h_errno.c b/library/socket_get_h_errno.c new file mode 100644 index 0000000..d109e29 --- /dev/null +++ b/library/socket_get_h_errno.c @@ -0,0 +1,44 @@ +/* + * $Id: socket_get_h_errno.c,v 1.1 2005-10-17 13:54:25 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 _SOCKET_HEADERS_H +#include "socket_headers.h" +#endif /* _SOCKET_HEADERS_H */ + +/****************************************************************************/ + +int +__get_h_errno(void) +{ + return(h_errno); +} diff --git a/library/socket_headers.h b/library/socket_headers.h index 4fcf7fe..b6110ec 100644 --- a/library/socket_headers.h +++ b/library/socket_headers.h @@ -1,5 +1,5 @@ /* - * $Id: socket_headers.h,v 1.9 2005-10-09 12:32:18 obarthel Exp $ + * $Id: socket_headers.h,v 1.10 2005-10-17 13:54:25 obarthel Exp $ * * :ts=4 * @@ -94,6 +94,8 @@ extern int NOCOMMON h_errno; extern struct fd * __get_file_descriptor_socket(int socket_descriptor); extern int __socket_hook_entry(struct fd * fd,struct file_action_message * fam); +extern int __get_h_errno(void); +extern void __set_h_errno(int new_h_errno); /****************************************************************************/ diff --git a/library/socket_init_exit.c b/library/socket_init_exit.c index 28aa4bb..ee01f85 100644 --- a/library/socket_init_exit.c +++ b/library/socket_init_exit.c @@ -1,5 +1,5 @@ /* - * $Id: socket_init_exit.c,v 1.20 2005-07-03 10:36:47 obarthel Exp $ + * $Id: socket_init_exit.c,v 1.21 2005-10-17 13:54:25 obarthel Exp $ * * :ts=4 * @@ -60,10 +60,30 @@ #define SBTM_SETVAL(code) (TAG_USER | (((code) & SBTS_CODE) << SBTB_CODE) | 1) #endif /* SBTM_SETVAL */ -#define SBTC_BREAKMASK 1 /* Interrupt signal mask */ -#define SBTC_LOGTAGPTR 11 /* Under which name log entries are filed */ -#define SBTC_ERRNOLONGPTR 24 /* Pointer to errno, length == sizeof(errno) */ -#define SBTC_HERRNOLONGPTR 25 /* 'h_errno' pointer (with sizeof(h_errno) == sizeof(long)) */ +#define SBTC_BREAKMASK 1 /* Interrupt signal mask */ +#define SBTC_LOGTAGPTR 11 /* Under which name log entries are filed */ +#define SBTC_ERRNOLONGPTR 24 /* Pointer to errno, length == sizeof(errno) */ +#define SBTC_HERRNOLONGPTR 25 /* 'h_errno' pointer (with sizeof(h_errno) == sizeof(long)) */ +#define SBTC_CAN_SHARE_LIBRARY_BASES 51 /* Enable library base sharing among Processes */ +#define SBTC_ERROR_HOOK 68 /* Error hook pointer */ + +/****************************************************************************/ + +/* Call-back hook for use with SBTC_ERROR_HOOK */ +struct ErrorHookMsg +{ + ULONG ehm_Size; /* Size of this data structure; this + must be >= 12 */ + ULONG ehm_Action; /* See below for a list of definitions */ + + LONG ehm_Code; /* The error code to use */ +}; + +/* Which action the hook is to perform */ +#define EHMA_Set_errno 1 /* Set the local 'errno' to what is + found in ehm_Code */ +#define EHMA_Set_h_errno 2 /* Set the local 'h_errno' to what is + found in ehm_Code */ /****************************************************************************/ @@ -94,6 +114,48 @@ int NOCOMMON h_errno; /****************************************************************************/ +#if defined(__THREAD_SAFE) + +/****************************************************************************/ + +BOOL NOCOMMON __can_share_socket_library_base; +BOOL NOCOMMON __thread_safe_errno_h_errno; + +/****************************************************************************/ + +STATIC LONG ASM +error_hook_function( + REG(a0, struct Hook * unused_hook), + REG(a2, APTR unused_reserved), + REG(a1, struct ErrorHookMsg * ehm)) +{ + if(ehm != NULL && ehm->ehm_Size >= 12) + { + if (ehm->ehm_Action == EHMA_Set_errno) + __set_errno(ehm->ehm_Code); + else if (ehm->ehm_Action == EHMA_Set_h_errno) + __set_h_errno(ehm->ehm_Code); + } + + return(0); +} + +/****************************************************************************/ + +STATIC struct Hook error_hook = +{ + { NULL, NULL }, + (HOOKFUNC)error_hook_function, + (HOOKFUNC)NULL, + NULL +}; + +/****************************************************************************/ + +#endif /* __THREAD_SAFE */ + +/****************************************************************************/ + SOCKET_DESTRUCTOR(socket_exit) { ENTER(); @@ -212,14 +274,14 @@ SOCKET_CONSTRUCTOR(socket_init) goto out; } - /* If this library is built with the Roadshow SDK header files, and - * it should be thread-safe, then we'll try to allow multiple - * concurred processes to share the bsdsocket.library base opened - * above. This only works for Roadshow, though, and has the - * drawback that error reporting through 'errno' and 'h_errno' - * is no longer safe. - */ - #if defined(__THREAD_SAFE) && defined(SBTC_CAN_SHARE_LIBRARY_BASES) + /* In the thread-safe library we try to enable two features which so + far only the Roadshow TCP/IP stack supports: allow more than one + Process to use the same bsdsocket.library base and to propagate + changes to the errno and h_errno variable through a call-back + hook. If either of these features are supported can be checked + by looking at the global __can_share_socket_library_base and + __thread_safe_errno_h_errno variables. */ + #if defined(__THREAD_SAFE) { if(__SocketBase->lib_Version >= 4) { @@ -229,11 +291,29 @@ SOCKET_CONSTRUCTOR(socket_init) tags[1].ti_Tag = TAG_END; PROFILE_OFF(); - __SocketBaseTagList(tags); + + if(__SocketBaseTagList(tags) == 0) + __can_share_socket_library_base = TRUE; + PROFILE_ON(); + + if(__can_share_socket_library_base) + { + tags[0].ti_Tag = SBTM_SETVAL(SBTC_ERROR_HOOK); + tags[0].ti_Data = (ULONG)&error_hook; + + tags[1].ti_Tag = TAG_END; + + PROFILE_OFF(); + + if(__SocketBaseTagList(tags) == 0) + __thread_safe_errno_h_errno = TRUE; + + PROFILE_ON(); + } } } - #endif /* __THREAD_SAFE && SBTC_CAN_SHARE_LIBRARY_BASES */ + #endif /* __THREAD_SAFE */ /* Check if this program was launched as a server by the Internet * superserver. diff --git a/library/socket_set_h_errno.c b/library/socket_set_h_errno.c new file mode 100644 index 0000000..bd5834f --- /dev/null +++ b/library/socket_set_h_errno.c @@ -0,0 +1,44 @@ +/* + * $Id: socket_set_h_errno.c,v 1.1 2005-10-17 13:54:25 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 _SOCKET_HEADERS_H +#include "socket_headers.h" +#endif /* _SOCKET_HEADERS_H */ + +/****************************************************************************/ + +void +__set_h_errno(int new_h_errno) +{ + h_errno = new_h_errno; +}