summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Canciani <ranma42@gmail.com>2013-06-28 19:35:08 +0200
committerAndrea Canciani <ranma42@gmail.com>2013-06-28 19:37:43 +0200
commit262d6c86a3802c2120a11620b348038966a6dc1e (patch)
treec681247e9bce2923c269ff04285ec31dff6dbf24
parentf5c51d4eb781f118bc7bf3250dcbc76d9c956ad4 (diff)
tss: Fix win32 implementationc11
The win32 implementation was broken in multiple ways: it did not compile, it contained bugs, it was missing proper initialization and termination functions.
-rw-r--r--initfini/impl/_common.h2
-rw-r--r--initfini/impl/msvc.h2
-rw-r--r--tss/impl/win32.h48
-rw-r--r--tss/internal/_dispatch.h10
-rw-r--r--tss/internal/win32.h35
5 files changed, 69 insertions, 28 deletions
diff --git a/initfini/impl/_common.h b/initfini/impl/_common.h
index f98937a..1b818b9 100644
--- a/initfini/impl/_common.h
+++ b/initfini/impl/_common.h
@@ -39,11 +39,13 @@ static void
_simpleops_init_internals (void)
{
_simpleops_atomic_init ();
+ _simpleops_tss_init ();
}
static void
_simpleops_fini_internals (void)
{
+ _simpleops_tss_fini ();
_simpleops_atomic_fini ();
}
diff --git a/initfini/impl/msvc.h b/initfini/impl/msvc.h
index b040576..1505ebe 100644
--- a/initfini/impl/msvc.h
+++ b/initfini/impl/msvc.h
@@ -52,7 +52,7 @@ _simpleops_msvc_tss (HINSTANCE h,
PVOID pv)
{
if (dwReason == DLL_THREAD_DETACH)
- _simpleops_tss_destoy ();
+ _simpleops_tss_destroy ();
}
static int
diff --git a/tss/impl/win32.h b/tss/impl/win32.h
index f73588a..6adc02c 100644
--- a/tss/impl/win32.h
+++ b/tss/impl/win32.h
@@ -40,9 +40,12 @@
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+#include <stdlib.h>
+
+#include "simpleops/mtx.h"
typedef struct _simpleops_tss {
- struct _simpleops_tss *prev;
+ struct _simpleops_tss **prev;
struct _simpleops_tss *next;
DWORD idx;
simpleops_tss_dtor_t dtor;
@@ -52,46 +55,53 @@ typedef struct _simpleops_tss {
#define _SIMPLEOPS_TSS_HEAD SIMPLEOPS_ADD_PREFIX (_simpleops_tss_head)
extern simpleops_mtx_t _SIMPLEOPS_TSS_MTX;
-extern simpleops_tss_t *_SIMPLEOPS_TSS_HEAD;
+extern simpleops_tss_t _SIMPLEOPS_TSS_HEAD;
static simpleops_always_inline int
simpleops_tss_create (simpleops_tss_t *key, simpleops_tss_dtor_t dtor)
{
- *key = malloc (sizeof (*key));
- if (SIMPLEOPS_UNLIKELY (key == NULL))
+ simpleops_tss_t tss;
+
+ *key = NULL;
+ tss = malloc (sizeof (*tss));
+ if (SIMPLEOPS_UNLIKELY (tss == NULL))
return simpleops_thrd_error;
- simpleops_mtx_lock (&SIMPLEOPS_TSS_MTX);
+ simpleops_mtx_lock (&_SIMPLEOPS_TSS_MTX);
- key->link = &SIMPLEOPS_TSS_HEAD;
- key->next = SIMPLEOPS_TSS_HEAD;
- key->idx = TlsAlloc ();
- key->dtor = dtor;
+ tss->prev = &_SIMPLEOPS_TSS_HEAD;
+ tss->next = _SIMPLEOPS_TSS_HEAD;
+ tss->idx = TlsAlloc ();
+ tss->dtor = dtor;
- if (SIMPLEOPS_UNLIKELY (key->idx == TLS_OUT_OF_INDEXES)) {
- simpleops_mtx_unlock (&SIMPLEOPS_TSS_MTX);
- free (key);
- *key = NULL;
+ if (SIMPLEOPS_UNLIKELY (tss->idx == TLS_OUT_OF_INDEXES)) {
+ simpleops_mtx_unlock (&_SIMPLEOPS_TSS_MTX);
+ free (tss);
return simpleops_thrd_error;
}
- SIMPLEOPS_TSS_HEAD->link = &key->next;
- SIMPLEOPS_TSS_HEAD = key;
+ if (tss->next != NULL)
+ tss->next->prev = &tss->next;
+ *tss->prev = tss;
- simpleops_mtx_unlock (&SIMPLEOPS_TSS_MTX);
+ simpleops_mtx_unlock (&_SIMPLEOPS_TSS_MTX);
+ *key = tss;
return simpleops_thrd_success;
}
static simpleops_always_inline void
simpleops_tss_delete (simpleops_tss_t key)
{
- simpleops_mtx_lock (&SIMPLEOPS_TSS_MTX);
+ simpleops_mtx_lock (&_SIMPLEOPS_TSS_MTX);
+
+ if (key->next != NULL)
+ key->next->prev = key->prev;
+ *key->prev = key->next;
- *key->link = key->next;
TlsFree (key->idx);
- simpleops_mtx_unlock (&SIMPLEOPS_TSS_MTX);
+ simpleops_mtx_unlock (&_SIMPLEOPS_TSS_MTX);
free (key);
}
diff --git a/tss/internal/_dispatch.h b/tss/internal/_dispatch.h
index 22e3919..12fc5a9 100644
--- a/tss/internal/_dispatch.h
+++ b/tss/internal/_dispatch.h
@@ -41,7 +41,15 @@
#if ! SIMPLEOPS_HAVE_TSS_INTERNAL
-/* Just for consistency */
+static simpleops_always_inline void
+_simpleops_tss_init (void)
+{
+}
+
+static simpleops_always_inline void
+_simpleops_tss_fini (void)
+{
+}
#endif
diff --git a/tss/internal/win32.h b/tss/internal/win32.h
index 89e5a04..20de99c 100644
--- a/tss/internal/win32.h
+++ b/tss/internal/win32.h
@@ -25,8 +25,8 @@
* Author(s): Andrea Canciani <ranma42@gmail.com>
*/
-#ifndef SIMPLEOPS_TSS_INTERNAL_H
-#define SIMPLEOPS_TSS_INTERNAL_H
+#ifndef SIMPLEOPS_TSS_INTERNAL_WIN32_H
+#define SIMPLEOPS_TSS_INTERNAL_WIN32_H
#ifndef SIMPLEOPS_TSS_INTERNAL_H
#error Private header used directly
@@ -37,26 +37,37 @@
#define SIMPLEOPS_HAVE_TSS_INTERNAL 1
-#if ! SIMPLEOPS_HAVE_TSS_DESTRUCTOR
+#if ! SIMPLEOPS_HAVE_TSS_DESTROY
#error "The TSS implementation requires a destruction callback"
#endif
+#ifndef SIMPLEOPS_TSS_DTOR_ITERATIONS
+#define SIMPLEOPS_TSS_DTOR_ITERATIONS 16
+#endif
+
+simpleops_private simpleops_mtx_t _SIMPLEOPS_TSS_MTX;
+simpleops_private simpleops_tss_t _SIMPLEOPS_TSS_HEAD;
+
static simpleops_always_inline void
_simpleops_tss_destroy (void)
{
simpleops_tss_t key;
void *val;
+ int i;
+ simpleops_bool_t ran_dtor;
- simpleops_mtx_lock (&SIMPLEOPS_TSS_MTX);
+ simpleops_mtx_lock (&_SIMPLEOPS_TSS_MTX);
for (i = 0; i < SIMPLEOPS_TSS_DTOR_ITERATIONS; i++) {
- for (key = SIMPLEOPS_TSS_HEAD; key != NULL; key = key->next) {
+ ran_dtor = FALSE;
+
+ for (key = _SIMPLEOPS_TSS_HEAD; key != NULL; key = key->next) {
val = simpleops_tss_get (key);
if (val != NULL) {
simpleops_tss_set (key, NULL);
if (key->dtor != NULL) {
key->dtor (val);
- ran_dtor = SIMPLEOPS_TRUE;
+ ran_dtor = TRUE;
}
}
}
@@ -65,10 +76,20 @@ _simpleops_tss_destroy (void)
break;
}
- simpleops_mtx_unlock (&SIMPLEOPS_TSS_MTX);
+ simpleops_mtx_unlock (&_SIMPLEOPS_TSS_MTX);
}
+static simpleops_always_inline void
+_simpleops_tss_init (void)
+{
+ simpleops_mtx_init (&_SIMPLEOPS_TSS_MTX, simpleops_mtx_plain);
+}
+static simpleops_always_inline void
+_simpleops_tss_fini (void)
+{
+ simpleops_mtx_destroy (&_SIMPLEOPS_TSS_MTX);
+}
#endif