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

Back to archive index

Laurent Sansonetti lsans****@apple*****
Thu Jun 14 17:02:00 JST 2007


Hi Satoshi-san,

This seems indeed better to remove the instance from the cache within  
dealloc.

# Though I wonder if it's really safe to replace the NSObject method  
like this.

But at a glance all tests seem to pass, and you wrote that the  
previous problem you discovered is also fix by this change.

I will commit the patch then, thank you!

Laurent

On Jun 13, 2007, at 7:39 AM, Satoshi Nakagawa wrote:

> 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;
>
> _______________________________________________
> Rubycocoa-devel mailing list
> Rubyc****@lists*****
> http://lists.sourceforge.jp/mailman/listinfo/rubycocoa-devel




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