lucy-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mar...@apache.org
Subject [12/16] lucy-clownfish git commit: Use atomic op for setting cached host obj.
Date Fri, 13 Feb 2015 21:46:02 GMT
Use atomic op for setting cached host obj.


Project: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/commit/52b1f981
Tree: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/tree/52b1f981
Diff: http://git-wip-us.apache.org/repos/asf/lucy-clownfish/diff/52b1f981

Branch: refs/heads/master
Commit: 52b1f981408a7820ad0384593d4c1c61a147e7bb
Parents: 2dab35a
Author: Marvin Humphrey <marvin@rectangular.com>
Authored: Sun Feb 8 21:02:15 2015 -0800
Committer: Marvin Humphrey <marvin@rectangular.com>
Committed: Sun Feb 8 21:02:15 2015 -0800

----------------------------------------------------------------------
 runtime/perl/xs/XSBind.c | 26 +++++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/52b1f981/runtime/perl/xs/XSBind.c
----------------------------------------------------------------------
diff --git a/runtime/perl/xs/XSBind.c b/runtime/perl/xs/XSBind.c
index 659ab35..d29d1ec 100644
--- a/runtime/perl/xs/XSBind.c
+++ b/runtime/perl/xs/XSBind.c
@@ -27,6 +27,7 @@
 #include "Clownfish/Method.h"
 #include "Clownfish/Test/TestThreads.h"
 #include "Clownfish/TestHarness/TestBatchRunner.h"
+#include "Clownfish/Util/Atomic.h"
 #include "Clownfish/Util/StringHelper.h"
 #include "Clownfish/Util/NumberUtils.h"
 #include "Clownfish/Util/Memory.h"
@@ -645,9 +646,28 @@ S_lazy_init_host_obj(cfish_Obj *self) {
      * will assume responsibility for maintaining the refcount.  ref.host_obj
      * starts off with a refcount of 1, so we need to transfer any refcounts
      * in excess of that. */
-    size_t old_refcount = self->ref.count;
-    self->ref.host_obj = inner_obj;
-    SvREFCNT(inner_obj) += (old_refcount >> XSBIND_REFCOUNT_SHIFT) - 1;
+    cfish_ref_t old_ref = self->ref;
+    size_t excess = (old_ref.count >> XSBIND_REFCOUNT_SHIFT) - 1;
+    SvREFCNT(inner_obj) += excess;
+
+    // Overwrite refcount with host object.
+    cfish_Class *klass = self->klass;
+    if (SI_immortal(klass) || SI_threadsafe_but_not_immortal(klass)) {
+        if (!cfish_Atomic_cas_ptr((void**)&self->ref, old_ref.host_obj, inner_obj))
{
+            // Another thread beat us to it.  Now we have a Perl object to defuse.
+            SvSTASH_set(inner_obj, NULL);
+            SvREFCNT_dec((SV*)stash);
+            SvOBJECT_off(inner_obj);
+            SvREFCNT(inner_obj) -= excess;
+            SvREFCNT_dec(inner_obj);
+#if (PERL_VERSION <= 16)
+            PL_sv_objcount--;
+#endif
+        }
+    }
+    else {
+        self->ref.host_obj = inner_obj;
+    }
 }
 
 uint32_t


Mime
View raw message