diff --git a/dispatcher.cpp b/dispatcher.cpp index 2b79b12bb..af790a990 100644 --- a/dispatcher.cpp +++ b/dispatcher.cpp @@ -673,13 +673,26 @@ rb_vm_dispatch(void *_vm, struct mcache *cache, VALUE top, VALUE self, // Does the receiver implements -forwardInvocation:? if ((opt & DISPATCH_SUPER) == 0 && rb_objc_supports_forwarding(self, sel)) { + +#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 + // In earlier versions of the Objective-C runtime, there seems + // to be a bug where class_getInstanceMethod isn't atomic, + // and might return NULL while at the exact same time another + // thread registers the related method. + // As a work-around, we double-check if the method still does + // not exist here. If he does, we can dispatch it properly. + method = class_getInstanceMethod(klass, sel); + if (method != NULL) { + goto recache2; + } +#endif fill_ocache(cache, self, klass, (IMP)objc_msgSend, sel, NULL, argc); goto dispatch; } // Let's see if are not trying to call a Ruby method that accepts - // a regular argument then a optional Hash argument, to be + // a regular argument then an optional Hash argument, to be // compatible with the Ruby specification. const char *selname = (const char *)sel; size_t selname_len = strlen(selname);