This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA: Objective-C patch fixing libobjc/9969


Ok to apply (tested, no regressions, and gnustep-base seems to be still
working fine with this change) ?

Wed May 14 11:25:41 2003  Nicola Pero  <n.pero@mi.flashnet.it>

        libobjc/9969
        * sendmsg.c (get_imp): Fixed threading problem which might cause
        in extremely rare cases to return the forward method
        implementation instead of the actual method when the dispatch
        table was being installed by a concurrent thread.  Fixed threading
        problem which might cause in extremely rare cases the dispatch
        table to be installed twice - with a small memory leak - in
        similar situations.  This change adds some overhead to messaging
        whenever a forward implementation is returned.
        (__objc_responds_to): Similar fixes.
        (objc_msg_lookup): Similar fixes.

Index: sendmsg.c
===================================================================
RCS file: /cvs/gcc/gcc/libobjc/sendmsg.c,v
retrieving revision 1.10
diff -u -r1.10 sendmsg.c
--- sendmsg.c   16 Dec 2002 18:22:54 -0000      1.10
+++ sendmsg.c   14 May 2003 11:30:41 -0000
@@ -127,7 +127,14 @@
        {
          /* The dispatch table needs to be installed. */
          objc_mutex_lock (__objc_runtime_mutex);
-         __objc_install_dispatch_table_for_class (class);
+
+         /* Check __objc_uninstalled_dtable again in case another
+            thread installed the dtable while we were waiting for the
+            lock to be released.  */
+         if (class->dtable == __objc_uninstalled_dtable)
+           {
+             __objc_install_dispatch_table_for_class (class);
+           }
          objc_mutex_unlock (__objc_runtime_mutex);
          /* Call ourselves with the installed dispatch table
             and get the real method */
@@ -138,7 +145,16 @@
          /* The dispatch table has been installed so the
             method just doesn't exist for the class.
             Return the forwarding implementation. */
-         res = __objc_get_forward_imp (sel);
+
+         /* First check again if the method exists in case another
+            thread has installed the dtable just between we checked
+            res == 0 and class->dtable == __objc_uninstalled_dtable.
+         */
+         res = sarray_get_safe (class->dtable, (size_t) sel->sel_id);
+         if (res == 0)
+           {
+             res = __objc_get_forward_imp (sel);
+           }
        }
     }
   return res;
@@ -157,7 +173,10 @@
   if (object->class_pointer->dtable == __objc_uninstalled_dtable)
     {
       objc_mutex_lock (__objc_runtime_mutex);
-      __objc_install_dispatch_table_for_class (object->class_pointer);
+      if (object->class_pointer->dtable == __objc_uninstalled_dtable)
+       {
+         __objc_install_dispatch_table_for_class (object->class_pointer);
+       }
       objc_mutex_unlock (__objc_runtime_mutex);
     }
 
@@ -192,10 +211,19 @@
            }
          else
            {
-             /* The dispatch table has been installed so the
-                method just doesn't exist for the class.
-                Attempt to forward the method. */
-             result = __objc_get_forward_imp (op);
+             /* The dispatch table has been installed.  Check again
+                if the method exists (just in case the dispatch table
+                has been installed by another thread after we did the
+                previous check that the method exists).
+             */
+             result = sarray_get_safe (receiver->class_pointer->dtable,
+                                       (sidx)op->sel_id);
+             if (result == 0)
+               {
+                 /* If the method still just doesn't exist for the
+                    class, attempt to forward the method. */
+                 result = __objc_get_forward_imp (op);
+               }
            }
        }
       return result;



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]