>From 6b4c64f06648b95f942d5428991979b9d8f2c69b Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Thu, 20 Jun 2019 04:30:11 +0200 Subject: [PATCH 19/26] mtx: New module. * lib/mtx.c: New file. * modules/mtx: New file. * doc/posix-functions/call_once.texi: Mention the new module. * doc/posix-functions/mtx_init.texi: Likewise. * doc/posix-functions/mtx_lock.texi: Likewise. * doc/posix-functions/mtx_trylock.texi: Likewise. * doc/posix-functions/mtx_timedlock.texi: Likewise. * doc/posix-functions/mtx_unlock.texi: Likewise. * doc/posix-functions/mtx_destroy.texi: Likewise. --- ChangeLog | 13 ++ doc/posix-functions/call_once.texi | 8 +- doc/posix-functions/mtx_destroy.texi | 8 +- doc/posix-functions/mtx_init.texi | 8 +- doc/posix-functions/mtx_lock.texi | 8 +- doc/posix-functions/mtx_timedlock.texi | 8 +- doc/posix-functions/mtx_trylock.texi | 8 +- doc/posix-functions/mtx_unlock.texi | 8 +- lib/mtx.c | 288 +++++++++++++++++++++++++++++++++ modules/mtx | 34 ++++ 10 files changed, 363 insertions(+), 28 deletions(-) create mode 100644 lib/mtx.c create mode 100644 modules/mtx diff --git a/ChangeLog b/ChangeLog index 5d96988..0e73bd6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,18 @@ 2019-06-20 Bruno Haible + mtx: New module. + * lib/mtx.c: New file. + * modules/mtx: New file. + * doc/posix-functions/call_once.texi: Mention the new module. + * doc/posix-functions/mtx_init.texi: Likewise. + * doc/posix-functions/mtx_lock.texi: Likewise. + * doc/posix-functions/mtx_trylock.texi: Likewise. + * doc/posix-functions/mtx_timedlock.texi: Likewise. + * doc/posix-functions/mtx_unlock.texi: Likewise. + * doc/posix-functions/mtx_destroy.texi: Likewise. + +2019-06-20 Bruno Haible + thrd: New module. * lib/thrd.c: New file. * m4/thrd.m4: New file. diff --git a/doc/posix-functions/call_once.texi b/doc/posix-functions/call_once.texi index c3b10fb..84b9dfe 100644 --- a/doc/posix-functions/call_once.texi +++ b/doc/posix-functions/call_once.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/Call-Once.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: mtx Portability problems fixed by Gnulib: @itemize +@item +This function is missing on many platforms: +glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on many platforms: -glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize diff --git a/doc/posix-functions/mtx_destroy.texi b/doc/posix-functions/mtx_destroy.texi index ec8fe87..fda5048 100644 --- a/doc/posix-functions/mtx_destroy.texi +++ b/doc/posix-functions/mtx_destroy.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Mutexes.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: mtx Portability problems fixed by Gnulib: @itemize +@item +This function is missing on many platforms: +glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on many platforms: -glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize diff --git a/doc/posix-functions/mtx_init.texi b/doc/posix-functions/mtx_init.texi index 867f6a2..297ad34 100644 --- a/doc/posix-functions/mtx_init.texi +++ b/doc/posix-functions/mtx_init.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Mutexes.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: mtx Portability problems fixed by Gnulib: @itemize +@item +This function is missing on many platforms: +glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on many platforms: -glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize diff --git a/doc/posix-functions/mtx_lock.texi b/doc/posix-functions/mtx_lock.texi index 8e43992..958589d 100644 --- a/doc/posix-functions/mtx_lock.texi +++ b/doc/posix-functions/mtx_lock.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Mutexes.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: mtx Portability problems fixed by Gnulib: @itemize +@item +This function is missing on many platforms: +glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on many platforms: -glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize diff --git a/doc/posix-functions/mtx_timedlock.texi b/doc/posix-functions/mtx_timedlock.texi index 31e766e..d42f1ae 100644 --- a/doc/posix-functions/mtx_timedlock.texi +++ b/doc/posix-functions/mtx_timedlock.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Mutexes.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: mtx Portability problems fixed by Gnulib: @itemize +@item +This function is missing on many platforms: +glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on many platforms: -glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize diff --git a/doc/posix-functions/mtx_trylock.texi b/doc/posix-functions/mtx_trylock.texi index 26c38d6..e5beb64 100644 --- a/doc/posix-functions/mtx_trylock.texi +++ b/doc/posix-functions/mtx_trylock.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Mutexes.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: mtx Portability problems fixed by Gnulib: @itemize +@item +This function is missing on many platforms: +glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on many platforms: -glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize diff --git a/doc/posix-functions/mtx_unlock.texi b/doc/posix-functions/mtx_unlock.texi index e7779d8..f77ea17 100644 --- a/doc/posix-functions/mtx_unlock.texi +++ b/doc/posix-functions/mtx_unlock.texi @@ -10,15 +10,15 @@ Documentation:@* @url{https://www.gnu.org/software/libc/manual/html_node/ISO-C-Mutexes.html}. @end ifnotinfo -Gnulib module: --- +Gnulib module: mtx Portability problems fixed by Gnulib: @itemize +@item +This function is missing on many platforms: +glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on many platforms: -glibc 2.27, Mac OS X 10.5, FreeBSD 9.3, NetBSD 5.0, OpenBSD 3.8, Minix 3.1.8, AIX 7.1, HP-UX 11.31, IRIX 6.5, OSF/1 5.1, Solaris 11.3, Cygwin, mingw, MSVC 14, Interix 3.5, BeOS, Android 9.0. @end itemize diff --git a/lib/mtx.c b/lib/mtx.c new file mode 100644 index 0000000..6acb8ae --- /dev/null +++ b/lib/mtx.c @@ -0,0 +1,288 @@ +/* ISO C 11 locking in multithreaded situations. + Copyright (C) 2005-2019 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see . */ + +/* Written by Bruno Haible , 2005, 2019. + Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-win32.h. */ + +#include + +#include + +#include + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Use Windows threads. */ + +# define WIN32_LEAN_AND_MEAN /* avoid including junk */ +# include + +# include + +#else +/* Use POSIX threads. */ + +# include + +#endif + +#if defined _WIN32 && ! defined __CYGWIN__ +/* Use Windows threads. */ + +int +mtx_init (mtx_t *mutex, int type) +{ + switch (type) + { + case mtx_plain: + glwthread_mutex_init (&mutex->u.u_mutex); + break; + case mtx_plain | mtx_recursive: + glwthread_recmutex_init (&mutex->u.u_recmutex); + break; + case mtx_timed: + if (glwthread_timedmutex_init (&mutex->u.u_timedmutex) != 0) + return thrd_error; + break; + case mtx_timed | mtx_recursive: + if (glwthread_timedrecmutex_init (&mutex->u.u_timedrecmutex) != 0) + return thrd_error; + break; + default: + return thrd_error; + } + mutex->type = type; + return thrd_success; +} + +int +mtx_lock (mtx_t *mutex) +{ + int err; + + switch (mutex->type) + { + case mtx_plain: + err = glwthread_mutex_lock (&mutex->u.u_mutex); + break; + case mtx_plain | mtx_recursive: + err = glwthread_recmutex_lock (&mutex->u.u_recmutex); + break; + case mtx_timed: + err = glwthread_timedmutex_lock (&mutex->u.u_timedmutex); + break; + case mtx_timed | mtx_recursive: + err = glwthread_timedrecmutex_lock (&mutex->u.u_timedrecmutex); + break; + default: + abort (); + } + return (err == 0 ? thrd_success : thrd_error); +} + +int +mtx_trylock (mtx_t *mutex) +{ + int err; + + switch (mutex->type) + { + case mtx_plain: + err = glwthread_mutex_trylock (&mutex->u.u_mutex); + break; + case mtx_plain | mtx_recursive: + err = glwthread_recmutex_trylock (&mutex->u.u_recmutex); + break; + case mtx_timed: + err = glwthread_timedmutex_trylock (&mutex->u.u_timedmutex); + break; + case mtx_timed | mtx_recursive: + err = glwthread_timedrecmutex_trylock (&mutex->u.u_timedrecmutex); + break; + default: + abort (); + } + return (err == 0 ? thrd_success : err == EBUSY ? thrd_busy : thrd_error); +} + +int +mtx_timedlock (mtx_t *mutex, const struct timespec *abstime) +{ + int err; + + switch (mutex->type) + { + case mtx_plain: + case mtx_plain | mtx_recursive: + return thrd_error; + case mtx_timed: + err = glwthread_timedmutex_timedlock (&mutex->u.u_timedmutex, abstime); + break; + case mtx_timed | mtx_recursive: + err = + glwthread_timedrecmutex_timedlock (&mutex->u.u_timedrecmutex, abstime); + break; + default: + abort (); + } + return (err == 0 ? thrd_success : err == EBUSY ? thrd_busy : thrd_error); +} + +int +mtx_unlock (mtx_t *mutex) +{ + int err; + + switch (mutex->type) + { + case mtx_plain: + err = glwthread_mutex_unlock (&mutex->u.u_mutex); + break; + case mtx_plain | mtx_recursive: + err = glwthread_recmutex_unlock (&mutex->u.u_recmutex); + break; + case mtx_timed: + err = glwthread_timedmutex_unlock (&mutex->u.u_timedmutex); + break; + case mtx_timed | mtx_recursive: + err = glwthread_timedrecmutex_unlock (&mutex->u.u_timedrecmutex); + break; + default: + abort (); + } + return (err == 0 ? thrd_success : thrd_error); +} + +void +mtx_destroy (mtx_t *mutex) +{ + switch (mutex->type) + { + case mtx_plain: + glwthread_mutex_destroy (&mutex->u.u_mutex); + break; + case mtx_plain | mtx_recursive: + glwthread_recmutex_destroy (&mutex->u.u_recmutex); + break; + case mtx_timed: + glwthread_timedmutex_destroy (&mutex->u.u_timedmutex); + break; + case mtx_timed | mtx_recursive: + glwthread_timedrecmutex_destroy (&mutex->u.u_timedrecmutex); + break; + default: + abort (); + } +} + +void +call_once (once_flag *flagp, void (*func) (void)) +{ + glwthread_once (flagp, func); +} + +#else +/* Use POSIX threads. */ + +int +mtx_init (mtx_t *mutex, int type) +{ + switch (type) + { + case mtx_plain: + case mtx_timed: + case mtx_plain | mtx_recursive: + case mtx_timed | mtx_recursive: + break; + default: + return thrd_error; + } + + if ((type & mtx_recursive) != 0) + { + pthread_mutexattr_t attributes; + int err; + + err = pthread_mutexattr_init (&attributes); + if (err != 0) + return thrd_error; + err = pthread_mutexattr_settype (&attributes, PTHREAD_MUTEX_RECURSIVE); + if (err != 0) + { + pthread_mutexattr_destroy (&attributes); + return thrd_error; + } + err = pthread_mutex_init (mutex, &attributes); + if (err != 0) + { + pthread_mutexattr_destroy (&attributes); + return thrd_error; + } + err = pthread_mutexattr_destroy (&attributes); + if (err != 0) + return thrd_error; + } + else + { + int err = pthread_mutex_init (mutex, NULL); + if (err != 0) + return thrd_error; + } + return thrd_success; +} + +int +mtx_lock (mtx_t *mutex) +{ + int err = pthread_mutex_lock (mutex); + return (err == 0 ? thrd_success : thrd_error); +} + +int +mtx_trylock (mtx_t *mutex) +{ + int err = pthread_mutex_trylock (mutex); + return (err == 0 ? thrd_success : err == EBUSY ? thrd_busy : thrd_error); +} + +int +mtx_timedlock (mtx_t *mutex, const struct timespec *abstime) +{ + int err = pthread_mutex_timedlock (mutex, abstime); + return (err == 0 ? thrd_success : + err == ETIMEDOUT ? thrd_timedout : + thrd_error); +} + +int +mtx_unlock (mtx_t *mutex) +{ + int err = pthread_mutex_unlock (mutex); + return (err == 0 ? thrd_success : thrd_error); +} + +void +mtx_destroy (mtx_t *mutex) +{ + pthread_mutex_destroy (mutex); +} + +void +call_once (once_flag *flagp, void (*func) (void)) +{ + pthread_once (flagp, func); +} + +#endif diff --git a/modules/mtx b/modules/mtx new file mode 100644 index 0000000..a1d2a8a --- /dev/null +++ b/modules/mtx @@ -0,0 +1,34 @@ +Description: +ISO C 11 mutex functions. + +Files: +lib/mtx.c + +Depends-on: +threads-h +pthread_mutex_timedlock +windows-mutex +windows-recmutex +windows-timedmutex +windows-timedrecmutex + +configure.ac: +AC_REQUIRE([gl_THREADS_H]) +if test $HAVE_THREADS_H = 0; then + AC_LIBOBJ([mtx]) +fi +gl_THREADS_MODULE_INDICATOR([mtx]) + +Makefile.am: + +Include: + + +Link: +$(LTLIBSTDTHREAD) when linking with libtool, $(LIBSTDTHREAD) otherwise + +License: +LGPLv2+ + +Maintainer: +all -- 2.7.4