From 37b09d7dc2c5956fbd70c211ed164a9ee1f7e349 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Tue, 16 Aug 2005 11:18:22 +0000 Subject: [PATCH] New module 'tls'. --- ChangeLog | 5 + MODULES.html.sh | 1 + lib/ChangeLog | 5 + lib/tls.c | 65 +++++++++++++ lib/tls.h | 286 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ m4/ChangeLog | 8 ++ m4/tls.m4 | 12 +++ modules/tls | 26 ++++++ 8 files changed, 408 insertions(+) create mode 100644 lib/tls.c create mode 100644 lib/tls.h create mode 100644 m4/tls.m4 create mode 100644 modules/tls diff --git a/ChangeLog b/ChangeLog index b97571926..56c00bea7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-16 Bruno Haible + + * modules/tls: New file. + * MODULES.html.sh (Multithreading): Add tls. + 2005-08-15 Simon Josefsson * modules/ssize_t (License): Change to 'unlimited'. diff --git a/MODULES.html.sh b/MODULES.html.sh index c3c3a7bc2..d66ecd9c8 100755 --- a/MODULES.html.sh +++ b/MODULES.html.sh @@ -1914,6 +1914,7 @@ func_all_modules () func_begin_table func_module lock + func_module tls func_end_table element="Internationalization functions" diff --git a/lib/ChangeLog b/lib/ChangeLog index c3126d394..a253a9391 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,8 @@ +2005-08-16 Bruno Haible + + * tls.h: New file, from GNU gettext. + * tls.c: New file, from GNU gettext. + 2005-08-15 Bruno Haible * regex.h (__restrict_arr): Don't define to __restrict if __cplusplus diff --git a/lib/tls.c b/lib/tls.c new file mode 100644 index 000000000..d7097d261 --- /dev/null +++ b/lib/tls.c @@ -0,0 +1,65 @@ +/* Thread-local storage in multithreaded situations. + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* Written by Bruno Haible , 2005. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "tls.h" + +/* ========================================================================= */ + +#if USE_POSIX_THREADS + +#endif + +/* ========================================================================= */ + +#if USE_PTH_THREADS + +#endif + +/* ========================================================================= */ + +#if USE_SOLARIS_THREADS + +/* Use the old Solaris threads library. */ + +/* ------------------------- gl_tls_key_t datatype ------------------------- */ + +void +glthread_tls_get (thread_key_t key) +{ + void *value; + + if (thr_getspecific (key, &value) != 0) + abort (); + return value; +} + +#endif + +/* ========================================================================= */ + +#if USE_WIN32_THREADS + +#endif + +/* ========================================================================= */ diff --git a/lib/tls.h b/lib/tls.h new file mode 100644 index 000000000..ff36155c2 --- /dev/null +++ b/lib/tls.h @@ -0,0 +1,286 @@ +/* Thread-local storage in multithreaded situations. + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* Written by Bruno Haible , 2005. */ + +/* This file contains thread-local storage primitives for use with a given + thread library. It does not contain primitives for creating threads or + for other multithreading primitives. + + Type: gl_tls_key_t + Initialization: gl_tls_key_init (name, destructor); + Getting per-thread value: gl_tls_get (name) + Setting per-thread value: gl_tls_set (name, pointer); + De-initialization: gl_tls_key_destroy (name); + + A per-thread value is of type 'void *'. + + A destructor is a function pointer of type 'void (*) (void *)', called + when a thread exits, and taking the last per-thread value as argument. It + is unspecified whether the destructor function is called when the last + per-thread value is NULL. On some platforms, the destructor function is + not called at all. +*/ + + +/* ========================================================================= */ + +#if USE_POSIX_THREADS + +/* Use the POSIX threads library. */ + +# include +# include + +# if PTHREAD_IN_USE_DETECTION_HARD + +/* The pthread_in_use() detection needs to be done at runtime. */ +# define pthread_in_use() \ + glthread_in_use () +extern int glthread_in_use (void); + +# endif + +# if USE_POSIX_THREADS_WEAK + +/* Use weak references to the POSIX threads library. */ + +# pragma weak pthread_key_create +# pragma weak pthread_getspecific +# pragma weak pthread_setspecific +# pragma weak pthread_key_delete +# ifndef pthread_self +# pragma weak pthread_self +# endif + +# if !PTHREAD_IN_USE_DETECTION_HARD +# pragma weak pthread_cancel +# define pthread_in_use() (pthread_cancel != NULL) +# endif + +# else + +# if !PTHREAD_IN_USE_DETECTION_HARD +# define pthread_in_use() 1 +# endif + +# endif + +/* ------------------------- gl_tls_key_t datatype ------------------------- */ + +typedef union + { + void *singlethread_value; + pthread_key_t key; + } + gl_tls_key_t; +# define gl_tls_key_init(NAME, DESTRUCTOR) \ + if (pthread_in_use ()) \ + { \ + if (pthread_key_create (&(NAME).key, DESTRUCTOR) != 0) \ + abort (); \ + } \ + else \ + (NAME).singlethread_value = NULL +# define gl_tls_get(NAME) \ + (pthread_in_use () \ + ? pthread_getspecific ((NAME).key) \ + : (NAME).singlethread_value) +# define gl_tls_set(NAME, POINTER) \ + if (pthread_in_use ()) \ + { \ + if (pthread_setspecific ((NAME).key, (POINTER)) != 0) \ + abort (); \ + } \ + else \ + (NAME).singlethread_value = (POINTER) +# define gl_tls_key_destroy(NAME) \ + if (pthread_in_use () && pthread_key_delete ((NAME).key) != 0) \ + abort () + +#endif + +/* ========================================================================= */ + +#if USE_PTH_THREADS + +/* Use the GNU Pth threads library. */ + +# include +# include + +# if USE_PTH_THREADS_WEAK + +/* Use weak references to the GNU Pth threads library. */ + +# pragma weak pth_key_create +# pragma weak pth_key_getdata +# pragma weak pth_key_setdata +# pragma weak pth_key_delete + +# pragma weak pth_cancel +# define pth_in_use() (pth_cancel != NULL) + +# else + +# define pth_in_use() 1 + +# endif + +/* ------------------------- gl_tls_key_t datatype ------------------------- */ + +typedef union + { + void *singlethread_value; + pth_key_t key; + } + gl_tls_key_t; +# define gl_tls_key_init(NAME, DESTRUCTOR) \ + if (pth_in_use ()) \ + { \ + if (!pth_key_create (&(NAME).key, DESTRUCTOR)) \ + abort (); \ + } \ + else \ + (NAME).singlethread_value = NULL +# define gl_tls_get(NAME) \ + (pth_in_use () \ + ? pth_key_getdata ((NAME).key) \ + : (NAME).singlethread_value) +# define gl_tls_set(NAME, POINTER) \ + if (pth_in_use ()) \ + { \ + if (!pth_key_setdata ((NAME).key, (POINTER))) \ + abort (); \ + } \ + else \ + (NAME).singlethread_value = (POINTER) +# define gl_tls_key_destroy(NAME) \ + if (pth_in_use () && !pth_key_delete ((NAME).key)) \ + abort () + +#endif + +/* ========================================================================= */ + +#if USE_SOLARIS_THREADS + +/* Use the old Solaris threads library. */ + +# include +# include + +# if USE_SOLARIS_THREADS_WEAK + +/* Use weak references to the old Solaris threads library. */ + +# pragma weak thr_keycreate +# pragma weak thr_getspecific +# pragma weak thr_setspecific + +# pragma weak thr_suspend +# define thread_in_use() (thr_suspend != NULL) + +# else + +# define thread_in_use() 1 + +# endif + +/* ------------------------- gl_tls_key_t datatype ------------------------- */ + +typedef union + { + void *singlethread_value; + thread_key_t key; + } + gl_tls_key_t; +# define gl_tls_key_init(NAME, DESTRUCTOR) \ + if (thread_in_use ()) \ + { \ + if (thr_keycreate (&(NAME).key, DESTRUCTOR) != 0) \ + abort (); \ + } \ + else \ + (NAME).singlethread_value = NULL +# define gl_tls_get(NAME) \ + (thread_in_use () \ + ? glthread_tls_get ((NAME).key) \ + : (NAME).singlethread_value) +extern void *glthread_tls_get (thread_key_t key); +# define gl_tls_set(NAME, POINTER) \ + if (thread_in_use ()) \ + { \ + if (thr_setspecific ((NAME).key, (POINTER)) != 0) \ + abort (); \ + } \ + else \ + (NAME).singlethread_value = (POINTER) +# define gl_tls_key_destroy(NAME) \ + /* Unsupported. */ \ + (void)0 + +#endif + +/* ========================================================================= */ + +#if USE_WIN32_THREADS + +# include + +/* ------------------------- gl_tls_key_t datatype ------------------------- */ + +typedef DWORD gl_tls_key_t; +# define gl_tls_key_init(NAME, DESTRUCTOR) \ + /* The destructor is unsupported. */ \ + if (((NAME) = TlsAlloc ()) == (DWORD)-1) \ + abort () +# define gl_tls_get(NAME) \ + TlsGetValue (NAME) +# define gl_tls_set(NAME, POINTER) \ + if (!TlsSetValue (NAME, POINTER)) \ + abort () +# define gl_tls_key_destroy(NAME) \ + if (!TlsFree (NAME)) \ + abort () + +#endif + +/* ========================================================================= */ + +#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS) + +/* Provide dummy implementation if threads are not supported. */ + +/* ------------------------- gl_tls_key_t datatype ------------------------- */ + +typedef struct + { + void *singlethread_value; + } + gl_tls_key_t; +# define gl_tls_key_init(NAME, DESTRUCTOR) \ + (NAME).singlethread_value = NULL +# define gl_tls_get(NAME) \ + (NAME).singlethread_value +# define gl_tls_set(NAME, POINTER) \ + (NAME).singlethread_value = (POINTER) +# define gl_tls_key_destroy(NAME) \ + (void)0 + +#endif diff --git a/m4/ChangeLog b/m4/ChangeLog index 84e623a5b..019eedee7 100644 --- a/m4/ChangeLog +++ b/m4/ChangeLog @@ -1,3 +1,11 @@ +2005-08-16 Bruno Haible + + * tls.m4: New file, from GNU gettext. + +2005-08-12 Bruno Haible + + * readline.m4 (gl_FUNC_READLINE): Look for ncurses first. + 2005-08-12 Simon Josefsson * readline.m4: Look for termcap, curses or ncurses if required. diff --git a/m4/tls.m4 b/m4/tls.m4 new file mode 100644 index 000000000..fdf65fc1c --- /dev/null +++ b/m4/tls.m4 @@ -0,0 +1,12 @@ +# tls.m4 serial 1 (gettext-0.15) +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([gl_TLS], +[ + AC_REQUIRE([gl_LOCK]) +]) diff --git a/modules/tls b/modules/tls new file mode 100644 index 000000000..d83fe37ec --- /dev/null +++ b/modules/tls @@ -0,0 +1,26 @@ +Description: +Thread-local storage in multithreaded situations. + +Files: +lib/tls.h +lib/tls.c +m4/tls.m4 + +Depends-on: +lock + +configure.ac: +gl_TLS + +Makefile.am: +lib_SOURCES += tls.h tls.c + +Include: +"tls.h" + +License: +LGPL + +Maintainer: +Bruno Haible + -- 2.11.0