const char* e;
if (!constructor) {
- GNUTLS_STATIC_MUTEX_LOCK(global_init_mutex);
+ ret = gnutls_static_mutex_lock(&global_init_mutex);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
}
_gnutls_init++;
out:
_gnutls_init_ret = ret;
if (!constructor) {
- GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
+ (void)gnutls_static_mutex_unlock(&global_init_mutex);
}
return ret;
}
static void _gnutls_global_deinit(unsigned destructor)
{
if (!destructor) {
- GNUTLS_STATIC_MUTEX_LOCK(global_init_mutex);
+ if (gnutls_static_mutex_lock(&global_init_mutex) < 0) {
+ return;
+ }
}
if (_gnutls_init == 1) {
fail:
if (!destructor) {
- GNUTLS_STATIC_MUTEX_UNLOCK(global_init_mutex);
+ (void)gnutls_static_mutex_unlock(&global_init_mutex);
}
}
char client_random_hex[2*GNUTLS_RANDOM_SIZE+1];
char secret_hex[2*MAX_HASH_SIZE+1];
- GNUTLS_STATIC_MUTEX_LOCK(keylog_mutex);
+ if (gnutls_static_mutex_lock(&keylog_mutex) < 0) {
+ return;
+ }
fprintf(keylog, "%s %s %s\n",
label,
_gnutls_bin2hex(session->security_parameters.
_gnutls_bin2hex(secret, secret_size,
secret_hex, sizeof(secret_hex), NULL));
fflush(keylog);
- GNUTLS_STATIC_MUTEX_UNLOCK(keylog_mutex);
+ (void)gnutls_static_mutex_unlock(&keylog_mutex);
}
}
if (ret < 0)
_gnutls_debug_log("error in gnutls_global_init(): %s\n", gnutls_strerror(ret));
}
+
+int
+gnutls_static_mutex_lock(gnutls_static_mutex_t lock)
+{
+ if (unlikely(glthread_lock_lock(lock))) {
+ return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
+ }
+ return 0;
+}
+
+int
+gnutls_static_mutex_unlock(gnutls_static_mutex_t lock)
+{
+ if (unlikely(glthread_lock_unlock(lock))) {
+ return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
+ }
+ return 0;
+}
#include <gnutls/gnutls.h>
#include "gnutls_int.h"
-#include <system.h>
+#include "system.h"
#include "glthread/lock.h"
-#ifdef HAVE_STDATOMIC_H
-# include <stdatomic.h>
-#endif
-
extern mutex_init_func gnutls_mutex_init;
extern mutex_deinit_func gnutls_mutex_deinit;
extern mutex_lock_func gnutls_mutex_lock;
extern mutex_unlock_func gnutls_mutex_unlock;
-#if defined(HAVE_WIN32_LOCKS)
-# include <windows.h>
-
-/* Idea based based on comment 2 at:
- * https://stackoverflow.com/questions/3555859/is-it-possible-to-do-static-initialization-of-mutexes-in-windows
+/* If a mutex is initialized with GNUTLS_STATIC_MUTEX, it must be
+ * locked/unlocked with the gnutls_static_mutex_* functions defined
+ * below instead of the above gnutls_mutex_* functions, because the
+ * latter can be replaced with gnutls_global_set_mutex().
*/
-# define GNUTLS_STATIC_MUTEX(mutex) \
- static CRITICAL_SECTION *mutex = NULL
-
-# define GNUTLS_STATIC_MUTEX_LOCK(mutex) \
- if (mutex == NULL) { \
- CRITICAL_SECTION *mutex##tmp = malloc(sizeof(CRITICAL_SECTION)); \
- InitializeCriticalSection(mutex##tmp); \
- if (InterlockedCompareExchangePointer((PVOID*)&mutex, (PVOID)mutex##tmp, NULL) != NULL) { \
- DeleteCriticalSection(mutex##tmp); \
- free(mutex##tmp); \
- } \
- } \
- EnterCriticalSection(mutex)
-
-# define GNUTLS_STATIC_MUTEX_UNLOCK(mutex) \
- LeaveCriticalSection(mutex)
-
-#elif defined(HAVE_PTHREAD_LOCKS)
-# include <pthread.h>
-# define GNUTLS_STATIC_MUTEX(mutex) \
- static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER
-
-# define GNUTLS_STATIC_MUTEX_LOCK(mutex) \
- pthread_mutex_lock(&mutex)
-
-# define GNUTLS_STATIC_MUTEX_UNLOCK(mutex) \
- pthread_mutex_unlock(&mutex)
-
-#else
-# define GNUTLS_STATIC_MUTEX(mutex)
-# define GNUTLS_STATIC_MUTEX_LOCK(mutex)
-# define GNUTLS_STATIC_MUTEX_UNLOCK(mutex)
-#endif
+#define GNUTLS_STATIC_MUTEX(lock) gl_lock_define_initialized(static, lock)
+typedef gl_lock_t *gnutls_static_mutex_t;
+int gnutls_static_mutex_lock(gnutls_static_mutex_t lock);
+int gnutls_static_mutex_unlock(gnutls_static_mutex_t lock);
#define GNUTLS_STATIC_RWLOCK(rwlock) gl_rwlock_define_initialized(static, rwlock)
#define GNUTLS_STATIC_RWLOCK_RDLOCK gl_rwlock_rdlock
return GNUTLS_E_RANDOM_FAILED;
}
- GNUTLS_STATIC_MUTEX_LOCK(gnutls_rnd_ctx_list_mutex);
+ ret = gnutls_static_mutex_lock(&gnutls_rnd_ctx_list_mutex);
+ if (ret < 0) {
+ return gnutls_assert_val(ret);
+ }
ret = append(gnutls_rnd_ctx);
- GNUTLS_STATIC_MUTEX_UNLOCK(gnutls_rnd_ctx_list_mutex);
+ (void)gnutls_static_mutex_unlock(&gnutls_rnd_ctx_list_mutex);
if (ret < 0) {
gnutls_assert();
_gnutls_rnd_ops.deinit(gnutls_rnd_ctx);
#include <sys/stat.h>
#include <sys/types.h>
-#ifdef _WIN32
-# include <windows.h>
-# include <wincrypt.h>
-
-#else /* !_WIN32 */
-
-# ifdef HAVE_PTHREAD_LOCKS
-# include <pthread.h>
-# endif
-
-#endif
+#include "glthread/lock.h"
/* System specific lock function wrappers.
*/
/* Thread stuff */
-#ifdef HAVE_WIN32_LOCKS
static int gnutls_system_mutex_init(void **priv)
{
- CRITICAL_SECTION *lock = malloc(sizeof(CRITICAL_SECTION));
+ gl_lock_t *lock = malloc(sizeof(gl_lock_t));
- if (lock == NULL)
- return GNUTLS_E_MEMORY_ERROR;
-
- InitializeCriticalSection(lock);
-
- *priv = lock;
-
- return 0;
-}
-
-static int gnutls_system_mutex_deinit(void **priv)
-{
- DeleteCriticalSection((CRITICAL_SECTION *) * priv);
- free(*priv);
-
- return 0;
-}
-
-static int gnutls_system_mutex_lock(void **priv)
-{
- EnterCriticalSection((CRITICAL_SECTION *) * priv);
- return 0;
-}
-
-static int gnutls_system_mutex_unlock(void **priv)
-{
- LeaveCriticalSection((CRITICAL_SECTION *) * priv);
- return 0;
-}
-
-#endif /* WIN32_LOCKS */
-
-#ifdef HAVE_PTHREAD_LOCKS
-
-static int gnutls_system_mutex_init(void **priv)
-{
- pthread_mutex_t *lock = malloc(sizeof(pthread_mutex_t));
- int ret;
-
- if (lock == NULL)
+ if (!lock) {
return GNUTLS_E_MEMORY_ERROR;
+ }
- ret = pthread_mutex_init(lock, NULL);
- if (ret) {
+ if (glthread_lock_init(lock)) {
free(lock);
- gnutls_assert();
- return GNUTLS_E_LOCKING_ERROR;
+ return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
}
*priv = lock;
-
return 0;
}
static int gnutls_system_mutex_deinit(void **priv)
{
- pthread_mutex_destroy((pthread_mutex_t *) * priv);
+ if (glthread_lock_destroy((gl_lock_t *) * priv)) {
+ return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
+ }
free(*priv);
return 0;
}
static int gnutls_system_mutex_lock(void **priv)
{
- if (pthread_mutex_lock((pthread_mutex_t *) * priv)) {
- gnutls_assert();
- return GNUTLS_E_LOCKING_ERROR;
+ if (glthread_lock_lock((gl_lock_t *) * priv)) {
+ return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
}
-
return 0;
}
static int gnutls_system_mutex_unlock(void **priv)
{
- if (pthread_mutex_unlock((pthread_mutex_t *) * priv)) {
- gnutls_assert();
- return GNUTLS_E_LOCKING_ERROR;
+ if (glthread_lock_unlock((gl_lock_t *) * priv)) {
+ return gnutls_assert_val(GNUTLS_E_LOCKING_ERROR);
}
-
- return 0;
-}
-
-#endif /* PTHREAD_LOCKS */
-
-#ifdef HAVE_NO_LOCKS
-
-static int gnutls_system_mutex_init(void **priv)
-{
- return 0;
-}
-
-static int gnutls_system_mutex_deinit(void **priv)
-{
return 0;
}
-static int gnutls_system_mutex_lock(void **priv)
-{
- return 0;
-}
-
-static int gnutls_system_mutex_unlock(void **priv)
-{
- return 0;
-}
-
-#endif /* NO_LOCKS */
-
mutex_init_func gnutls_mutex_init = gnutls_system_mutex_init;
mutex_deinit_func gnutls_mutex_deinit = gnutls_system_mutex_deinit;
mutex_lock_func gnutls_mutex_lock = gnutls_system_mutex_lock;