Make cfish_init_parcel thread-safe Initialize globals with compare-and-swap.
Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/7528af45 Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/7528af45 Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/7528af45 Branch: refs/heads/master Commit: 7528af4514e1ddea3c99bf9f6dcc4392c1f1b8e2 Parents: d7c863b Author: Nick Wellnhofer <[email protected]> Authored: Thu Mar 10 19:33:51 2016 +0100 Committer: Nick Wellnhofer <[email protected]> Committed: Thu Mar 10 21:45:10 2016 +0100 ---------------------------------------------------------------------- runtime/c/src/tls.c | 9 +++++++-- runtime/core/Clownfish/Boolean.c | 21 +++++++++++++++------ runtime/core/Clownfish/Hash.c | 6 +++++- runtime/perl/xs/XSBind.c | 5 ++++- 4 files changed, 31 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/c/src/tls.c ---------------------------------------------------------------------- diff --git a/runtime/c/src/tls.c b/runtime/c/src/tls.c index b550f13..a7fda40 100644 --- a/runtime/c/src/tls.c +++ b/runtime/c/src/tls.c @@ -49,11 +49,16 @@ static DWORD err_context_tls_index; void Tls_init() { - err_context_tls_index = TlsAlloc(); - if (err_context_tls_index == TLS_OUT_OF_INDEXES) { + DWORD tls_index = TlsAlloc(); + if (tls_index == TLS_OUT_OF_INDEXES) { fprintf(stderr, "TlsAlloc failed (TLS_OUT_OF_INDEXES)\n"); abort(); } + LONG old_index = InterlockedCompareExchange((LONG*)&err_context_tls_index, + tls_index, 0); + if (old_index != 0) { + TlsFree(tls_index); + } } ErrContext* http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/core/Clownfish/Boolean.c ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/Boolean.c b/runtime/core/Clownfish/Boolean.c index fd7c6d9..44a7c48 100644 --- a/runtime/core/Clownfish/Boolean.c +++ b/runtime/core/Clownfish/Boolean.c @@ -22,18 +22,26 @@ #include "Clownfish/Class.h" #include "Clownfish/String.h" +#include "Clownfish/Util/Atomic.h" Boolean *Bool_true_singleton; Boolean *Bool_false_singleton; void Bool_init_class() { - Bool_true_singleton = (Boolean*)Class_Make_Obj(BOOLEAN); - Bool_true_singleton->value = true; - Bool_true_singleton->string = Str_newf("true"); - Bool_false_singleton = (Boolean*)Class_Make_Obj(BOOLEAN); - Bool_false_singleton->value = false; - Bool_false_singleton->string = Str_newf("false"); + Boolean *true_obj = (Boolean*)Class_Make_Obj(BOOLEAN); + true_obj->value = true; + true_obj->string = Str_newf("true"); + if (!Atomic_cas_ptr((void**)&Bool_true_singleton, NULL, true_obj)) { + Bool_Destroy(true_obj); + } + + Boolean *false_obj = (Boolean*)Class_Make_Obj(BOOLEAN); + false_obj->value = false; + false_obj->string = Str_newf("false"); + if (!Atomic_cas_ptr((void**)&Bool_false_singleton, NULL, false_obj)) { + Bool_Destroy(false_obj); + } } Boolean* @@ -44,6 +52,7 @@ Bool_singleton(bool value) { void Bool_Destroy_IMP(Boolean *self) { if (self && self != CFISH_TRUE && self != CFISH_FALSE) { + DECREF(self->string); SUPER_DESTROY(self, BOOLEAN); } } http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/core/Clownfish/Hash.c ---------------------------------------------------------------------- diff --git a/runtime/core/Clownfish/Hash.c b/runtime/core/Clownfish/Hash.c index e0e5d80..174cc11 100644 --- a/runtime/core/Clownfish/Hash.c +++ b/runtime/core/Clownfish/Hash.c @@ -26,6 +26,7 @@ #include "Clownfish/String.h" #include "Clownfish/Err.h" #include "Clownfish/Vector.h" +#include "Clownfish/Util/Atomic.h" #include "Clownfish/Util/Memory.h" // TOMBSTONE is shared across threads, so it must never be incref'd or @@ -50,7 +51,10 @@ SI_rebuild_hash(Hash *self); void Hash_init_class() { - TOMBSTONE = Str_newf("[HASHTOMBSTONE]"); + String *tombstone = Str_newf("[HASHTOMBSTONE]"); + if (!Atomic_cas_ptr((void**)&TOMBSTONE, NULL, tombstone)) { + DECREF(tombstone); + } } Hash* http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/7528af45/runtime/perl/xs/XSBind.c ---------------------------------------------------------------------- diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c index 85bd85b..b6dd944 100644 --- a/runtime/perl/xs/XSBind.c +++ b/runtime/perl/xs/XSBind.c @@ -738,7 +738,10 @@ void cfish_Err_init_class(void) { dTHX; char *file = (char*)__FILE__; - attempt_xsub = (SV*)newXS(NULL, cfish_Err_attempt_via_xs, file); + SV *xsub = (SV*)newXS(NULL, cfish_Err_attempt_via_xs, file); + if (!cfish_Atomic_cas_ptr((void**)&attempt_xsub, NULL, xsub)) { + SvREFCNT_dec(xsub); + } } cfish_Err*
