Follow-up Comment #6, bug #35263 (project gnustep): Here a mail from David that comments on a mail from Richard in reply to this bug report. Most likely this will get completely unreadable, but I don't want that information to get lost.
> On 11 Jan 2012, at 09:16, Fred Kiefer wrote: > >> To Richard's comment that we could adopt the GCC runtime solution: > I don't think I actually advocated that. > >> I wrote the >> patch that did that in the GCC runtime originally, and it's what the GNUstep >> runtime used to do. > Not sure what he's talking about here ... the current GCC behavior was written by me and then improved by Nicola ... so perhaps he's talking about the earlier version of the +initialize code which wasn't thread-safe? No, I wrote the code in the version of GCC libobjc in GNUstep svn that implemented this. I assumed that had been ported upstream to GCC, I hadn't realised that you reinvented the wheel. >> I fixed this behaviour because people rely on the Apple >> behaviour - there are lots of fun deadlock scenarios you can get into from >> only being able to enter one +initialize method at once in each thread. > Not clear on this either ... the Apple behavior? In the GCC runtime there's a global lock so, once one thread enters a +initialize *no* other thread can do so until the first thread exits again, but the first thread can enter +initialize in any/all classes. That means that, as long as your +initialize implementation doesn't wait for any other thread (directly or indirectly), the GCC runtime avoids deadlocks. That's why I (slightly) prefer the GCC runtime behavior ... it 's relatively easy to avoid deadlock. I initially implemented the single-lock version in GNUstep libobjc. The reason that I implemented the Apple-compatible behaviour was that I got reports of deadlocks with the single-lock version. This is because there are existing applications that do things like spawn a new thread in +initialize and send messages from that thread and exit the +initialize once the thread returned. These then hit the global lock and deadlock. They only deadlocked on GNUstep, so from the user perspective this is a bug: my code works on Cocoa, doesn't work on GNUstep = GNUstep sucks. People notified me of a bug, which was also an Apple incompatibility, and I fixed it. Now other people are complaining that their code - which uses a GCC-specific, undocumented, behaviour - does not work. >> Reverting to the old behaviour would just mean getting a different set of >> potential deadlocks, and they would be deadlocks that a) only showed up on >> GNUstep and not Cocoa, and b) made it hard to write code that was >> deadlock-free on both Cocoa and GNUstep. > Valid point ... but these deadlocks are rare (so far we have one bug report for the apple behavior, and have not had any for the gcc behavior). So I don't think it makes sense to change the GCC runtime to copy an undocumented behavior of the Apple runtime which is rarely relevant and doesn't actually improve things. What we do need to be aware of is that existing initialization code which is fine with the GCC runtime might deadlock with the Apple runtime. > > It sounds like David is saying he won't fix libobjc2 and wants libobc to reproduce the apple bug instead. No, I'm saying that I won't reintroduce a bug that I already fixed. > I'd rather not bother trying to get GCC libobjc changed until/unless we can find a fix which cures both deadlocks (it's a hard argument to say to a FSF project they should change something to fix one by replacing it with a worse one which is Apple compatible). Fixing the GCC runtime is the correct fix, because it is buggy. +initialize is supposed to block all messages to that class until it completes. There are two buggy behaviours: - Not blocking (GCC used to do this) - Blocking all unrelated +initialize methods (GCC and GNUstep used to do this) Apple does not document that it does not block other classes receiving +initialize methods any more than NSLock's -lock method doesn't block any other locks. It is implicit. The exact phrase in the documentation is: > The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.) The runtime sends the initialize message to classes in a thread-safe manner. Nowhere in this does it say that the +initialize method will block anything else, only that it will complete before any other messages sent to *that class* or its subclasses (other than ones sent from within the +initialize method). The GCC runtime (and old versions of the GNUstep runtime) introduced undocumented serialisation constraints. This was / is a bug. _______________________________________________________ Reply to this item at: <http://savannah.gnu.org/bugs/?35263> _______________________________________________ Nachricht geschickt von/durch Savannah http://savannah.gnu.org/ _______________________________________________ Bug-gnustep mailing list Bug-gnustep@gnu.org https://lists.gnu.org/mailman/listinfo/bug-gnustep