[Rubycocoa-devel 983] A patch for caching problem

Back to archive index

Satoshi Nakagawa snaka****@infot*****
Wed Jun 13 21:44:04 JST 2007


Hi.

In

[Rubycocoa-devel 939] parameters in callback are different from original objects
[Rubycocoa-devel 890] NSObject.alloc.init doesn't return NSObject sometimes

I reported the caching problem.

In RubyKaigi 2007, Hisa-san and I talked about it,
and I realized it is not solved fundamentally.
I hit on a idea. We can clear cache when objects are being dealloc-ed.

I have wrote a patch to implement it.
It is a fundamental solution and works good for the problems I reported.
But I don't have any idea where to insert the code.

--
Satoshi Nakagawa


Index: framework/src/objc/RBRuntime.m
===================================================================
--- framework/src/objc/RBRuntime.m      (revision 1837)
+++ framework/src/objc/RBRuntime.m      (working copy)
@@ -228,6 +228,27 @@
   return RBNotifyException(api_name, err);
}
+ at implementation NSObject (__DeallocHook)
+- (void)__clearCacheAndDealloc
+{
+  remove_from_oc2rb_cache(self);
+  [self __clearCacheAndDealloc];
+}
+ at end
+
+static void install_dealloc_hook()
+{
+  Method original_method, new_method;
+  IMP tmp;
+
+  original_method = class_getInstanceMethod([NSObject class], @selector(dealloc));
+  new_method = class_getInstanceMethod([NSObject class], @selector(__clearCacheAndDealloc));
+
+  tmp = original_method->method_imp;
+  original_method->method_imp = new_method->method_imp;
+  new_method->method_imp = tmp;
+}
+
static int rubycocoa_initialized_flag = 0;
static int rubycocoa_initialized_p()
@@ -243,6 +264,7 @@
   if (! rubycocoa_initialized_flag) {
     init_rb2oc_cache();    // initialize the Ruby->ObjC internal cache
     init_oc2rb_cache();    // initialize the ObjC->Ruby internal cache
+    install_dealloc_hook();
     initialize_mdl_osxobjc();  // initialize an objc part of rubycocoa
     initialize_mdl_bundle_support();
     init_ovmix();
Index: framework/src/objc/ocdata_conv.m
===================================================================
--- framework/src/objc/ocdata_conv.m    (revision 1837)
+++ framework/src/objc/ocdata_conv.m    (working copy)
@@ -709,13 +709,11 @@
         result = rbobj_get_ocid(context_obj) == ocid ? context_obj : ocobj_s_new(ocid);
     }
-    if (context_obj != Qfalse) {
-      CACHE_LOCK(&oc2rbCacheLock);
-      // Check out that the hash is still empty for us, to avoid a race condition.
-      if (!st_lookup(oc2rbCache, (st_data_t)ocid, (st_data_t *)&result))
-        st_insert(oc2rbCache, (st_data_t)ocid, (st_data_t)result);
-      CACHE_UNLOCK(&oc2rbCacheLock);
-    }
+    CACHE_LOCK(&oc2rbCacheLock);
+    // Check out that the hash is still empty for us, to avoid a race condition.
+    if (!st_lookup(oc2rbCache, (st_data_t)ocid, (st_data_t *)&result))
+      st_insert(oc2rbCache, (st_data_t)ocid, (st_data_t)result);
+    CACHE_UNLOCK(&oc2rbCacheLock);
   }
   return result;




More information about the Rubycocoa-devel mailing list
Back to archive index