[Rubycocoa-devel 984] Re: A patch for caching problem

Back to archive index

Satoshi Nakagawa snaka****@infot*****
Wed Jun 13 23:39:29 JST 2007


Hi.

> + at implementation NSObject (__DeallocHook)
> +- (void)__clearCacheAndDealloc
> +{
> +  remove_from_oc2rb_cache(self);
> +  [self __clearCacheAndDealloc];
> +}
> + at end

I have reconsidered this part.
It could seem to be a code of infinite recursion.
But actually [self __clearCacheAndDealloc] will invoke the original version of dealloc.
It is a bit hard to read.

I wrote another patch, more readable.

--
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,32 @@
   return RBNotifyException(api_name, err);
}
+ at implementation NSObject (__DeallocHook)
+
+- (void) __dealloc
+{
+}
+
+- (void) __clearCacheAndDealloc
+{
+  remove_from_oc2rb_cache(self);
+  [self __dealloc];
+}
+
+ at end
+
+static void install_dealloc_hook()
+{
+  Method dealloc_method, aliased_dealloc_method, cache_aware_dealloc_method;
+
+  dealloc_method = class_getInstanceMethod([NSObject class], @selector(dealloc));
+  aliased_dealloc_method = class_getInstanceMethod([NSObject class], @selector(__dealloc));
+  cache_aware_dealloc_method = class_getInstanceMethod([NSObject class], @selector(__clearCacheAndDealloc));
+
+  aliased_dealloc_method->method_imp = dealloc_method->method_imp;
+  dealloc_method->method_imp = cache_aware_dealloc_method->method_imp;
+}
+
static int rubycocoa_initialized_flag = 0;
static int rubycocoa_initialized_p()
@@ -243,6 +269,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