You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2015/02/13 22:46:05 UTC

[15/16] lucy-clownfish git commit: Use copy-on-incref Strings as immortals.

Use copy-on-incref Strings as immortals.

Members variables of Class and Method are shared and need to be
threadsafe.  Copy-on-incref Strings are effectively threadsafe, so use
those.


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

Branch: refs/heads/master
Commit: c0b90906746d3825e3fc9fd41d023aa727e07b13
Parents: 55b19f4
Author: Marvin Humphrey <ma...@rectangular.com>
Authored: Tue Feb 10 19:01:39 2015 -0800
Committer: Marvin Humphrey <ma...@rectangular.com>
Committed: Tue Feb 10 19:01:39 2015 -0800

----------------------------------------------------------------------
 runtime/core/Clownfish/Class.c    | 18 +++++++++++++-----
 runtime/core/Clownfish/Class.cfh  |  1 +
 runtime/core/Clownfish/Method.c   | 22 +++++++++++++++++++++-
 runtime/core/Clownfish/Method.cfh |  5 +++++
 4 files changed, 40 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c0b90906/runtime/core/Clownfish/Class.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.c b/runtime/core/Clownfish/Class.c
index 478bd6c..6e87e49 100644
--- a/runtime/core/Clownfish/Class.c
+++ b/runtime/core/Clownfish/Class.c
@@ -152,23 +152,30 @@ Class_bootstrap(const ClassSpec *specs, size_t num_specs)
      * Pass 3:
      * - Inititalize name and method array.
      * - Register class.
+     *
+     * We use a "wrapped" String for `name` because it's effectively
+     * threadsafe: the sole reference is owned by an immortal object and any
+     * INCREF spawns a copy.
      */
     for (size_t i = 0; i < num_specs; ++i) {
         const ClassSpec *spec = &specs[i];
         Class *klass = *spec->klass;
 
-        klass->name    = Str_newf("%s", spec->name);
+        klass->name_internal = Str_newf("%s", spec->name);
+        klass->name
+            = Str_new_wrap_trusted_utf8(Str_Get_Ptr8(klass->name_internal),
+                                        Str_Get_Size(klass->name_internal));
         klass->methods = (Method**)MALLOCATE((spec->num_novel_meths + 1)
                                              * sizeof(Method*));
 
         // Only store novel methods for now.
         for (size_t i = 0; i < spec->num_novel_meths; ++i) {
             const NovelMethSpec *mspec = &spec->novel_meth_specs[i];
-            String *name = Str_newf("%s", mspec->name);
-            Method *method = Method_new(name, mspec->callback_func,
+            StackString *name
+                = SSTR_WRAP_UTF8(mspec->name, strlen(mspec->name));
+            Method *method = Method_new((String*)name, mspec->callback_func,
                                         *mspec->offset);
             klass->methods[i] = method;
-            DECREF(name);
         }
 
         klass->methods[spec->num_novel_meths] = NULL;
@@ -363,11 +370,12 @@ void
 Class_Add_Host_Method_Alias_IMP(Class *self, const char *alias,
                              const char *meth_name) {
     Method *method = S_find_method(self, meth_name);
+    StackString *alias_cf = SSTR_WRAP_UTF8(alias, strlen(alias));
     if (!method) {
         fprintf(stderr, "Method %s not found\n", meth_name);
         abort();
     }
-    method->host_alias = Str_newf("%s", alias);
+    Method_Set_Host_Alias(method, (String*)alias_cf);
 }
 
 void

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c0b90906/runtime/core/Clownfish/Class.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Class.cfh b/runtime/core/Clownfish/Class.cfh
index 566f29f..8b966b7 100644
--- a/runtime/core/Clownfish/Class.cfh
+++ b/runtime/core/Clownfish/Class.cfh
@@ -27,6 +27,7 @@ class Clownfish::Class inherits Clownfish::Obj {
 
     Class              *parent;
     String             *name;
+    String             *name_internal;
     uint32_t            flags;
     int32_t             parcel_id;
     size_t              obj_alloc_size;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c0b90906/runtime/core/Clownfish/Method.c
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Method.c b/runtime/core/Clownfish/Method.c
index bf76313..931427b 100644
--- a/runtime/core/Clownfish/Method.c
+++ b/runtime/core/Clownfish/Method.c
@@ -31,11 +31,20 @@ Method_new(String *name, cfish_method_t callback_func, size_t offset) {
 Method*
 Method_init(Method *self, String *name, cfish_method_t callback_func,
             size_t offset) {
-    self->name          = Str_Clone(name);
+    /* The `name` member which Method exposes via the `Get_Name` accessor uses
+     * a "wrapped" string because that is effectively threadsafe: an INCREF
+     * results in a copy and the only reference is owned by an immortal
+     * object. */
+    self->name_internal = Str_Clone(name);
+    self->name
+        = Str_new_wrap_trusted_utf8(Str_Get_Ptr8(self->name_internal),
+                                    Str_Get_Size(self->name_internal));
+
     self->host_alias    = NULL;
     self->callback_func = callback_func;
     self->offset        = offset;
     self->is_excluded   = false;
+
     return self;
 }
 
@@ -49,6 +58,17 @@ Method_Get_Name_IMP(Method *self) {
     return self->name;
 }
 
+void
+Method_Set_Host_Alias_IMP(Method *self, String *name) {
+    if (self->host_alias) {
+        THROW(ERR, "Can't Set_Host_Alias more than once");
+    }
+    self->host_alias_internal = Str_Clone(name);
+    self->host_alias
+        = Str_new_wrap_trusted_utf8(Str_Get_Ptr8(self->host_alias_internal),
+                                    Str_Get_Size(self->host_alias_internal));
+}
+
 String*
 Method_Get_Host_Alias_IMP(Method *self) {
     return self->host_alias;

http://git-wip-us.apache.org/repos/asf/lucy-clownfish/blob/c0b90906/runtime/core/Clownfish/Method.cfh
----------------------------------------------------------------------
diff --git a/runtime/core/Clownfish/Method.cfh b/runtime/core/Clownfish/Method.cfh
index 57bc1ad..e71a549 100644
--- a/runtime/core/Clownfish/Method.cfh
+++ b/runtime/core/Clownfish/Method.cfh
@@ -22,7 +22,9 @@ parcel Clownfish;
 class Clownfish::Method inherits Clownfish::Obj {
 
     String         *name;
+    String         *name_internal;
     String         *host_alias;
+    String         *host_alias_internal;
     cfish_method_t  callback_func;
     size_t          offset;
     bool            is_excluded;
@@ -37,6 +39,9 @@ class Clownfish::Method inherits Clownfish::Obj {
     String*
     Get_Name(Method *self);
 
+    void
+    Set_Host_Alias(Method *self, String *name);
+
     nullable String*
     Get_Host_Alias(Method *self);