diff options
author | Werner Koch <wk@gnupg.org> | 2017-11-29 20:22:06 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2017-11-29 20:22:06 +0100 |
commit | adc786d034b63176b941a1ef8d996acbf8d0ea5d (patch) | |
tree | b19d82491cc7666f18cb44d2f7458f2f28fbe936 | |
parent | 1865c0ba1769b407a3c504f1ab0a4278704a9fc1 (diff) | |
download | libgpg-error-adc786d034b63176b941a1ef8d996acbf8d0ea5d.tar.gz |
core: Unify syscall_clamp functions.
* src/estream.c (_gpgrt_set_syscall_clamp)
(_gpgrt_get_syscall_clamp): Move to ...
* src/syscall-clamp.c: new file.
(_gpgrt_pre_syscall, _gpgrt_post_syscall): New.
* src/Makefile.am (libgpg_error_la_SOURCES): Add that file.
* src/estream.c: Replace the syscall wrapper with the new functions.
* src/posix-lock.c: Ditto.
* src/w32-lock.c: Ditto.
* src/posix-thread.c: Ditto.
* src/w32-thread.c: Ditto.
Signed-off-by: Werner Koch <wk@gnupg.org>
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/estream.c | 124 | ||||
-rw-r--r-- | src/gpgrt-int.h | 3 | ||||
-rw-r--r-- | src/lock.h | 2 | ||||
-rw-r--r-- | src/posix-lock.c | 37 | ||||
-rw-r--r-- | src/posix-thread.c | 35 | ||||
-rw-r--r-- | src/syscall-clamp.c | 80 | ||||
-rw-r--r-- | src/thread.h | 2 | ||||
-rw-r--r-- | src/w32-lock.c | 31 | ||||
-rw-r--r-- | src/w32-thread.c | 26 |
10 files changed, 138 insertions, 203 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index ac13e70..4446612 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -187,6 +187,7 @@ libgpg_error_la_SOURCES = gettext.h $(arch_sources) \ strsource.c strerror.c code-to-errno.c code-from-errno.c \ visibility.c visibility.h \ sysutils.c \ + syscall-clamp.c \ logging.c \ b64dec.c diff --git a/src/estream.c b/src/estream.c index 2f29cdb..dd2b289 100644 --- a/src/estream.c +++ b/src/estream.c @@ -201,14 +201,6 @@ GPGRT_LOCK_DEFINE (estream_list_lock); /* - * Functions called before and after blocking syscalls. - * gpgrt_set_syscall_clamp is used to set them. - */ -static void (*pre_syscall_func)(void); -static void (*post_syscall_func)(void); - - -/* * Error code replacements. */ #ifndef EOPNOTSUPP @@ -491,7 +483,7 @@ do_list_remove (estream_t stream, int with_locked_list) /* - * The atexit handler for this estream module. + * The atexit handler for the entire gpgrt. */ static void do_deinit (void) @@ -508,10 +500,7 @@ do_deinit (void) we keep the list and let the OS clean it up at process end. */ /* Reset the syscall clamp. */ - pre_syscall_func = NULL; - post_syscall_func = NULL; - _gpgrt_thread_set_syscall_clamp (NULL, NULL); - _gpgrt_lock_set_lock_clamp (NULL, NULL); + _gpgrt_set_syscall_clamp (NULL, NULL); } @@ -531,37 +520,6 @@ _gpgrt_estream_init (void) return 0; } -/* - * Register the syscall clamp. These two functions are called - * immediately before and after a possible blocking system call. This - * should be used before any I/O happens. The function is commonly - * used with the nPth library: - * - * gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); - * - * These functions may not modify ERRNO. - */ -void -_gpgrt_set_syscall_clamp (void (*pre)(void), void (*post)(void)) -{ - pre_syscall_func = pre; - post_syscall_func = post; - _gpgrt_thread_set_syscall_clamp (pre, post); - _gpgrt_lock_set_lock_clamp (pre, post); -} - -/* - * Return the current sycall clamp functions. This can be used by - * other libraries which have blocking functions. - */ -void -_gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void)) -{ - *r_pre = pre_syscall_func; - *r_post = post_syscall_func; -} - - /* * Implementation of memory based I/O. @@ -971,15 +929,13 @@ func_fd_read (void *cookie, void *buffer, size_t size) } else { - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); do { bytes_read = read (file_cookie->fd, buffer, size); } while (bytes_read == -1 && errno == EINTR); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); } trace_errno (bytes_read == -1, ("leave: bytes_read=%d", (int)bytes_read)); @@ -1005,15 +961,13 @@ func_fd_write (void *cookie, const void *buffer, size_t size) } else if (buffer) { - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); do { bytes_written = write (file_cookie->fd, buffer, size); } while (bytes_written == -1 && errno == EINTR); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); } else bytes_written = size; /* Note that for a flush SIZE should be 0. */ @@ -1041,11 +995,9 @@ func_fd_seek (void *cookie, gpgrt_off_t *offset, int whence) } else { - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); offset_new = lseek (file_cookie->fd, *offset, whence); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); if (offset_new == -1) err = -1; else @@ -1216,8 +1168,8 @@ func_w32_read (void *cookie, void *buffer, size_t size) } else { - if (pre_syscall_func && !w32_cookie->no_syscall_clamp) - pre_syscall_func (); + if (!w32_cookie->no_syscall_clamp) + _gpgrt_pre_syscall (); do { DWORD nread, ec; @@ -1239,8 +1191,8 @@ func_w32_read (void *cookie, void *buffer, size_t size) bytes_read = (int)nread; } while (bytes_read == -1 && errno == EINTR); - if (post_syscall_func && !w32_cookie->no_syscall_clamp) - post_syscall_func (); + if (!w32_cookie->no_syscall_clamp) + _gpgrt_post_syscall (); } trace_errno (bytes_read==-1,("leave: bytes_read=%d", (int)bytes_read)); @@ -1269,8 +1221,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size) } else if (buffer) { - if (pre_syscall_func && !w32_cookie->no_syscall_clamp) - pre_syscall_func (); + if (!w32_cookie->no_syscall_clamp) + _gpgrt_pre_syscall (); do { DWORD nwritten; @@ -1287,8 +1239,8 @@ func_w32_write (void *cookie, const void *buffer, size_t size) bytes_written = (int)nwritten; } while (bytes_written == -1 && errno == EINTR); - if (post_syscall_func && !w32_cookie->no_syscall_clamp) - post_syscall_func (); + if (!w32_cookie->no_syscall_clamp) + _gpgrt_post_syscall (); } else bytes_written = size; /* Note that for a flush SIZE should be 0. */ @@ -1338,17 +1290,16 @@ func_w32_seek (void *cookie, gpgrt_off_t *offset, int whence) #ifdef HAVE_W32CE_SYSTEM # warning need to use SetFilePointer #else - if (pre_syscall_func && !w32_cookie->no_syscall_clamp) - pre_syscall_func (); + if (!w32_cookie->no_syscall_clamp) + _gpgrt_pre_syscall (); if (!SetFilePointerEx (w32_cookie->hd, distance, &newoff, method)) { _set_errno (map_w32_to_errno (GetLastError ())); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); return -1; } - if (post_syscall_func && !w32_cookie->no_syscall_clamp) - post_syscall_func (); + if (!w32_cookie->no_syscall_clamp) + _gpgrt_post_syscall (); #endif /* Note that gpgrt_off_t is always 64 bit. */ *offset = (gpgrt_off_t)newoff.QuadPart; @@ -1473,11 +1424,9 @@ func_fp_read (void *cookie, void *buffer, size_t size) if (file_cookie->fp) { - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); bytes_read = fread (buffer, 1, size, file_cookie->fp); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); } else bytes_read = 0; @@ -1498,8 +1447,7 @@ func_fp_write (void *cookie, const void *buffer, size_t size) if (file_cookie->fp) { - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); if (buffer) { #ifdef HAVE_W32_SYSTEM @@ -1527,8 +1475,7 @@ func_fp_write (void *cookie, const void *buffer, size_t size) bytes_written = size; fflush (file_cookie->fp); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); } else bytes_written = size; /* Successfully written to the bit bucket. */ @@ -1554,20 +1501,17 @@ func_fp_seek (void *cookie, gpgrt_off_t *offset, int whence) return -1; } - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); if ( fseek (file_cookie->fp, (long int)*offset, whence) ) { /* fprintf (stderr, "\nfseek failed: errno=%d (%s)\n", */ /* errno,strerror (errno)); */ - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); return -1; } offset_new = ftell (file_cookie->fp); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); if (offset_new == -1) { /* fprintf (stderr, "\nftell failed: errno=%d (%s)\n", */ @@ -1592,11 +1536,9 @@ func_fp_destroy (void *cookie) { if (fp_cookie->fp) { - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); fflush (fp_cookie->fp); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); err = fp_cookie->no_close? 0 : fclose (fp_cookie->fp); } else @@ -4909,8 +4851,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) } } - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); do { struct timeval timeout_val; @@ -4924,8 +4865,7 @@ _gpgrt_poll (gpgrt_poll_t *fds, unsigned int nfds, int timeout) timeout == -1 ? NULL : &timeout_val); } while (ret == -1 && errno == EINTR); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); if (ret == -1) { diff --git a/src/gpgrt-int.h b/src/gpgrt-int.h index 2413257..fcce082 100644 --- a/src/gpgrt-int.h +++ b/src/gpgrt-int.h @@ -124,7 +124,8 @@ char *_gpgrt_strconcat_core (const char *s1, va_list arg_ptr); #define xtryrealloc(a,b) _gpgrt_realloc ((a),(b)) #define xtrystrdup(a) _gpgrt_strdup ((a)) - +void _gpgrt_pre_syscall (void); +void _gpgrt_post_syscall (void); const char *_gpg_error_check_version (const char *req_version); @@ -20,7 +20,5 @@ #ifndef LOCK_H #define LOCK_H -void _gpgrt_lock_set_lock_clamp (void (*pre)(void), void (*post)(void)); - #endif /*LOCK_H*/ diff --git a/src/posix-lock.c b/src/posix-lock.c index d251d2f..b5e6916 100644 --- a/src/posix-lock.c +++ b/src/posix-lock.c @@ -39,19 +39,11 @@ # include <pthread.h> #endif -#include "gpg-error.h" +#include "gpgrt-int.h" #include "lock.h" #include "posix-lock-obj.h" -/* - * Functions called before and after blocking syscalls. - * gpgrt_set_syscall_clamp is used to set them. - */ -static void (*pre_lock_func)(void); -static void (*post_lock_func)(void); - - #if USE_POSIX_THREADS # if USE_POSIX_THREADS_WEAK /* On ELF systems it is easy to use pthreads using weak @@ -111,17 +103,6 @@ use_pthread_p (void) #endif /*USE_POSIX_THREADS*/ -/* Helper to set the clamp functions. This is called as a helper from - * _gpgrt_set_syscall_clamp to keep the function pointers local. */ -void -_gpgrt_lock_set_lock_clamp (void (*pre)(void), void (*post)(void)) -{ - pre_lock_func = pre; - post_lock_func = post; -} - - - static _gpgrt_lock_t * get_lock_object (gpgrt_lock_t *lockhd) { @@ -168,7 +149,7 @@ _gpgrt_lock_init (gpgrt_lock_t *lockhd) { rc = pthread_mutex_init (&lock->u.mtx, NULL); if (rc) - rc = gpg_err_code_from_errno (rc); + rc = _gpg_err_code_from_errno (rc); } else rc = 0; /* Threads are not used. */ @@ -189,13 +170,11 @@ _gpgrt_lock_lock (gpgrt_lock_t *lockhd) #if USE_POSIX_THREADS if (use_pthread_p()) { - if (pre_lock_func) - pre_lock_func (); + _gpgrt_pre_syscall (); rc = pthread_mutex_lock (&lock->u.mtx); if (rc) - rc = gpg_err_code_from_errno (rc); - if (post_lock_func) - post_lock_func (); + rc = _gpg_err_code_from_errno (rc); + _gpgrt_post_syscall (); } else rc = 0; /* Threads are not used. */ @@ -218,7 +197,7 @@ _gpgrt_lock_trylock (gpgrt_lock_t *lockhd) { rc = pthread_mutex_trylock (&lock->u.mtx); if (rc) - rc = gpg_err_code_from_errno (rc); + rc = _gpg_err_code_from_errno (rc); } else rc = 0; /* Threads are not used. */ @@ -241,7 +220,7 @@ _gpgrt_lock_unlock (gpgrt_lock_t *lockhd) { rc = pthread_mutex_unlock (&lock->u.mtx); if (rc) - rc = gpg_err_code_from_errno (rc); + rc = _gpg_err_code_from_errno (rc); } else rc = 0; /* Threads are not used. */ @@ -266,7 +245,7 @@ _gpgrt_lock_destroy (gpgrt_lock_t *lockhd) { rc = pthread_mutex_destroy (&lock->u.mtx); if (rc) - rc = gpg_err_code_from_errno (rc); + rc = _gpg_err_code_from_errno (rc); else { /* Re-init the mutex so that it can be re-used. */ diff --git a/src/posix-thread.c b/src/posix-thread.c index 00a43e2..36c81ba 100644 --- a/src/posix-thread.c +++ b/src/posix-thread.c @@ -39,27 +39,10 @@ # include <thread.h> #endif -#include "gpg-error.h" +#include "gpgrt-int.h" #include "thread.h" -/* - * Functions called before and after blocking syscalls. - * gpgrt_set_syscall_clamp is used to set them. - */ -static void (*pre_syscall_func)(void); -static void (*post_syscall_func)(void); - - -/* Helper to set the clamp functions. This is called as a helper from - * _gpgrt_set_syscall_clamp to keep the function pointers local. */ -void -_gpgrt_thread_set_syscall_clamp (void (*pre)(void), void (*post)(void)) -{ - pre_syscall_func = pre; - post_syscall_func = post; -} - gpg_err_code_t @@ -67,20 +50,16 @@ _gpgrt_yield (void) { #if USE_POSIX_THREADS # ifdef _POSIX_PRIORITY_SCHEDULING - if (pre_syscall_func) - pre_syscall_func (); - sched_yield (); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_pre_syscall (); + sched_yield (); + _gpgrt_post_syscall (); # else - return GPG_ERR_NOT_SUPPORTED; + return GPG_ERR_NOT_SUPPORTED; # endif #elif USE_SOLARIS_THREADS - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); thr_yield (); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); #else return GPG_ERR_NOT_SUPPORTED; #endif diff --git a/src/syscall-clamp.c b/src/syscall-clamp.c new file mode 100644 index 0000000..99748f4 --- /dev/null +++ b/src/syscall-clamp.c @@ -0,0 +1,80 @@ +/* syscall-clamp.c - Syscall clamp related stuff + * Copyright (C) 2016, 2017 g10 Code GmbH + * + * This file is part of Libgpg-error. + * + * Libgpg-error is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgpg-error is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <https://www.gnu.org/licenses/>. + * SPDX-License-Identifier: LGPL-2.1+ + */ + +#include <config.h> + +#include "gpgrt-int.h" + +/* + * Functions called before and after blocking syscalls. + * gpgrt_set_syscall_clamp is used to set them. + */ +static void (*pre_syscall_func)(void); +static void (*post_syscall_func)(void); + + +/* + * Register the syscall clamp. These two functions are called + * immediately before and after a possible blocking system call. This + * should be used before any I/O happens. The function is commonly + * used with the nPth library: + * + * gpgrt_set_syscall_clamp (npth_unprotect, npth_protect); + * + * These functions may not modify ERRNO. + * + * Setting the clamp is not thread-safe and should thus be done as + * early as possible. + */ +void +_gpgrt_set_syscall_clamp (void (*pre)(void), void (*post)(void)) +{ + pre_syscall_func = pre; + post_syscall_func = post; +} + +/* + * Return the current sycall clamp functions. This can be used by + * other libraries which have blocking functions. + */ +void +_gpgrt_get_syscall_clamp (void (**r_pre)(void), void (**r_post)(void)) +{ + *r_pre = pre_syscall_func; + *r_post = post_syscall_func; +} + + +/* Call this function before a blocking system or libc call. */ +void +_gpgrt_pre_syscall (void) +{ + if (pre_syscall_func) + pre_syscall_func (); +} + + +/* Call this function after a blocking system or libc call. */ +void +_gpgrt_post_syscall (void) +{ + if (post_syscall_func) + post_syscall_func (); +} diff --git a/src/thread.h b/src/thread.h index f064cce..c650a99 100644 --- a/src/thread.h +++ b/src/thread.h @@ -20,7 +20,5 @@ #ifndef THREAD_H #define THREAD_H -void _gpgrt_thread_set_syscall_clamp (void (*pre)(void), void (*post)(void)); - #endif /*THREAD_H*/ diff --git a/src/w32-lock.c b/src/w32-lock.c index 51b13a1..a55f932 100644 --- a/src/w32-lock.c +++ b/src/w32-lock.c @@ -29,34 +29,15 @@ #include <stdio.h> #include <string.h> #include <errno.h> -#include <gpg-error.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> +#include "gpgrt-int.h" #include "lock.h" #include "w32-lock-obj.h" -/* - * Functions called before and after blocking syscalls. - * gpgrt_set_syscall_clamp is used to set them. - */ -static void (*pre_lock_func)(void); -static void (*post_lock_func)(void); - - -/* Helper to set the clamp functions. This is called as a helper from - * _gpgrt_set_syscall_clamp to keep the function pointers local. */ -void -_gpgrt_lock_set_lock_clamp (void (*pre)(void), void (*post)(void)) -{ - pre_lock_func = pre; - post_lock_func = post; -} - - - static _gpgrt_lock_t * get_lock_object (gpgrt_lock_t *lockhd) { @@ -112,7 +93,7 @@ _gpgrt_lock_lock (gpgrt_lock_t *lockhd) and thus fall into the wait loop below. We ignore that STARTED may in theory overflow if this thread starves for too long. */ - gpgrt_lock_init (lockhd); + _gpgrt_lock_init (lockhd); } else { @@ -121,11 +102,9 @@ _gpgrt_lock_lock (gpgrt_lock_t *lockhd) } } - if (pre_lock_func) - pre_lock_func (); + _gpgrt_pre_syscall (); EnterCriticalSection (&lock->csec); - if (post_lock_func) - post_lock_func (); + _gpgrt_post_syscall (); return 0; } @@ -139,7 +118,7 @@ _gpgrt_lock_trylock (gpgrt_lock_t *lockhd) { if (!InterlockedIncrement (&lock->started)) { - gpgrt_lock_init (lockhd); + _gpgrt_lock_init (lockhd); } else { diff --git a/src/w32-thread.c b/src/w32-thread.c index aef421f..c389635 100644 --- a/src/w32-thread.c +++ b/src/w32-thread.c @@ -29,38 +29,18 @@ #include <stdio.h> #include <string.h> #include <errno.h> -#include <gpg-error.h> #define WIN32_LEAN_AND_MEAN #include <windows.h> +#include "gpgrt-int.h" #include "thread.h" -/* - * Functions called before and after blocking syscalls. - * gpgrt_set_syscall_clamp is used to set them. - */ -static void (*pre_syscall_func)(void); -static void (*post_syscall_func)(void); - - -/* Helper to set the clamp functions. This is called as a helper from - * _gpgrt_set_syscall_clamp to keep the function pointers local. */ -void -_gpgrt_thread_set_syscall_clamp (void (*pre)(void), void (*post)(void)) -{ - pre_syscall_func = pre; - post_syscall_func = post; -} - - gpg_err_code_t _gpgrt_yield (void) { - if (pre_syscall_func) - pre_syscall_func (); + _gpgrt_pre_syscall (); Sleep (0); - if (post_syscall_func) - post_syscall_func (); + _gpgrt_post_syscall (); return 0; } |