]> err.no Git - yubikey-personalization.old/commitdiff
Make the errno location functions thread safe.
authorRichard Levitte <levitte@lp.se>
Thu, 7 May 2009 23:22:30 +0000 (23:22 +0000)
committerRichard Levitte <levitte@lp.se>
Thu, 7 May 2009 23:22:30 +0000 (23:22 +0000)
Add yktsd.h, which is a heavily pruned copy of Levitte Programming's LPlib file LPthread.h

configure.ac
ykcore/ykcore.c
ykcore/yktsd.h [new file with mode: 0644]
ykpers.c

index 58019334ae219230e6ddbf8c1868e1a7c9054213..cb65e929608e7f31ed5afd65f4a688a0814a63cc 100644 (file)
@@ -42,6 +42,12 @@ AC_SUBST(LT_AGE, 0)
 
 AM_INIT_AUTOMAKE([-Wall -Werror])
 AC_PROG_CC
+
+ACX_PTHREAD
+LIBS="$PTHREAD_LIBS $LIBS"
+CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+CC="$PTHREAD_CC"
+
 AC_LIBTOOL_WIN32_DLL
 AC_PROG_LIBTOOL
 
index ebcf1de0a0b1a194ca4c08dde1ba691a07a22cec..77f2f33937f8205fe65c2922a59bdfbcea1b8b4c 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "ykcore_lcl.h"
 #include "ykcore_backend.h"
+#include "yktsd.h"
 
 /* To get modhex and crc16 */
 #include <yubikey.h>
@@ -146,14 +147,25 @@ int yk_write_config(YK_KEY *yk, YK_CONFIG *cfg, unsigned char *acc_code)
 
 }
 
-/* As soon as we find a way to safely detect if we're in a threaded environment
-   or not, this should be changed to support per-thread locations.  Until then,
-   we only support non-threaded applications. */
-static int _yk_errno = 0;
-
 int * const _yk_errno_location(void)
 {
-       return &_yk_errno;
+       static int tsd_init = 0;
+       static int nothread_errno = 0;
+       YK_DEFINE_TSD_METADATA(errno_key);
+       int rc = 0;
+
+       if (tsd_init == 0) {
+               if ((rc = YK_TSD_INIT(errno_key, free)) == 0) {
+                       YK_TSD_SET(errno_key, calloc(1, sizeof(int)));
+                       tsd_init = 1;
+               } else {
+                       tsd_init = -1;
+               }
+       }
+       if (tsd_init == 1) {
+               return YK_TSD_GET(int *, errno_key);
+       }
+       return &nothread_errno;
 }
 
 static const char *errtext[] = {
diff --git a/ykcore/yktsd.h b/ykcore/yktsd.h
new file mode 100644 (file)
index 0000000..834a719
--- /dev/null
@@ -0,0 +1,58 @@
+/* yktsd.h -*- mode:C; c-file-style: "gnu" -*- */
+/* Note: this file is copied from Levitte Programming's LPlib and reworked
+   for ykcore */
+/*
+ * Copyright (c) 2003, 2004 Richard Levitte <richard@levitte.org>.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * 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 YKTSD_H
+#define YKTSD_H
+
+/* Define thread-specific data primitives */
+#if defined _WIN32
+#include <windows.h>
+#define yk__TSD_TYPE                   DWORD
+#define yk__TSD_ALLOC(key)             ((key = TlsAlloc()) == TLS_OUT_OF_INDEXES ? EAGAIN : 0)
+#define yk__TSD_FREE(key)              (!TlsFree(key))
+#define yk__TSD_SET(key,value)         (!TlsSetValue(key,value))
+#define yk__TSD_GET(key)               TlsGetValue(key)
+#else
+#include <pthread.h>
+#define yk__TSD_TYPE                   pthread_key_t
+#define yk__TSD_ALLOC(key,destr)       pthread_key_create(&key, destr)
+#define yk__TSD_FREE(key)              pthread_key_delete(key)
+#define yk__TSD_SET(key,value)         pthread_setspecific(key,(void *)value)
+#define yk__TSD_GET(key)               pthread_getspecific(key)
+#endif
+
+/* Define the high-level macros that we use.  */
+#define YK_TSD_METADATA(x)             yk__tsd_##x
+#define YK_DEFINE_TSD_METADATA(x)      static yk__TSD_TYPE YK_TSD_METADATA(x)
+#define YK_TSD_INIT(x,destr)           yk__TSD_ALLOC(YK_TSD_METADATA(x),destr)
+#define YK_TSD_DESTROY(x)              yk__TSD_FREE(YK_TSD_METADATA(x))
+#define YK_TSD_SET(x,value)            yk__TSD_SET(YK_TSD_METADATA(x),value)
+#define YK_TSD_GET(type,x)             (type)yk__TSD_GET(YK_TSD_METADATA(x))
+
+#endif
index 305705c00844b802f3b4cb69b79163ddd21d916c..6c4e1f23c4a1083f51062e3bf72548e0ed32828d 100644 (file)
--- a/ykpers.c
+++ b/ykpers.c
@@ -30,6 +30,7 @@
 
 #include "ykcore_lcl.h"
 #include "ykpbkdf2.h"
+#include "yktsd.h"
 
 #include <ykpers.h>
 
@@ -357,14 +358,25 @@ int ykp_read_config(YK_CONFIG *cfg,
        return 0;
 }
 
-/* As soon as we find a way to safely detect if we're in a threaded environment
-   or not, this should be changed to support per-thread locations.  Until then,
-   we only support non-threaded applications. */
-static int _ykp_errno = 0;
-
 int * const _ykp_errno_location(void)
 {
-       return &_ykp_errno;
+       static int tsd_init = 0;
+       static int nothread_errno = 0;
+       YK_DEFINE_TSD_METADATA(errno_key);
+       int rc = 0;
+
+       if (tsd_init == 0) {
+               if ((rc = YK_TSD_INIT(errno_key, free)) == 0) {
+                       YK_TSD_SET(errno_key, calloc(1, sizeof(int)));
+                       tsd_init = 1;
+               } else {
+                       tsd_init = -1;
+               }
+       }
+       if (tsd_init == 1) {
+               return YK_TSD_GET(int *, errno_key);
+       }
+       return &nothread_errno;
 }
 
 static const char *errtext[] = {