FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Assertion in NSUndoManager when spawning a new thread

 
Post new topic   Reply to topic     Forum Index -> Derelict
View previous topic :: View next topic  
Author Message
Poita_



Joined: 23 Jul 2010
Posts: 8

PostPosted: Fri Feb 04, 2011 2:58 pm    Post subject: Assertion in NSUndoManager when spawning a new thread Reply with quote

The following code produces an assertion on Mac OS X. This is tested on OSX 10.6.6 with DMD 2.051 and the latest version of Derelict2 (rev 525).

Code:
import derelict.sdl.sdl;
import derelict.util.compat;

import std.concurrency;

pragma(lib, "derelict/Derelict2/lib/libDerelictSDL.a");
pragma(lib, "derelict/Derelict2/lib/libDerelictUtil.a");

void foo() {}

void main()
{
  spawn(&foo);
}


The error is:

Code:
2011-02-04 20:45:11.577 test[10214:440b] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /SourceCache/Foundation/Foundation-751.42/Misc.subproj/NSUndoManager.m:271
2011-02-04 20:45:11.581 test[10214:440b] +[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.
2011-02-04 20:45:11.584 test[10214:440b] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /SourceCache/Foundation/Foundation-751.42/Misc.subproj/NSUndoManager.m:271
2011-02-04 20:45:11.586 test[10214:440b] An uncaught exception was raised
2011-02-04 20:45:11.587 test[10214:440b] +[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.
2011-02-04 20:45:11.588 test[10214:440b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.'
*** Call stack at first throw:
(
        0   CoreFoundation                      0x98bdb6ba __raiseError + 410
        1   libobjc.A.dylib                     0x94f93509 objc_exception_throw + 56
        2   CoreFoundation                      0x98bdb3e8 +[NSException raise:format:arguments:] + 136
        3   Foundation                          0x90146bb3 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
        4   Foundation                          0x90092e11 +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 160
        5   AppKit                              0x969a5153 -[NSApplication run] + 577
        6   test                                0x0000293c D8derelict3sdl7macinit13NSApplication13NSApplication3runMFZv + 56
        7   test                                0x000061c5 D8derelict3sdl7macinit7SDLMain12_staticCtor3FZv + 7281
        8   test                                0x0000448b _D8derelict3sdl7macinit7SDLMain9__modctorFZv + 11
        9   test                                0x00010758 _moduleTlsCtor + 68
        10  test                                0x00010813 rt_moduleTlsCtor + 11
        11  test                                0x00014be0 thread_entryPoint + 196
        12  libSystem.B.dylib                   0x90be885d _pthread_start + 345
        13  libSystem.B.dylib                   0x90be86e2 thread_start + 34
)
Trace/BPT trap


I'm trying a few things to get around it, but haven't figured anything out yet. Anyone know how to get around this?
Back to top
View user's profile Send private message
Poita_



Joined: 23 Jul 2010
Posts: 8

PostPosted: Fri Feb 04, 2011 4:27 pm    Post subject: Reply with quote

Update:

I've partially solved this problem by making all of Derelict's static constructors shared, and marking all global variables as __gshared.

This solved the immediate issue, but apparently you need an NSAutoReleasePool per thread, so I left that in TLS in the TLS static constructor.

But this caused more problems. Seemingly at random, I would get a bus error when trying to allocate memory in a thread other than the main thread. This didn't happen deterministically.

I've managed to get around this problem by disabling the GC in the new thread, then re-enabling it just as that thread ends. This is good enough for my needs, but I don't think that's a practical long-term solution.

I'll have to do more tests to figure out whether this is an issue with the druntime GC, or if it is to do with the NSAutoReleasePools. It's hard to tell at the moment...
Back to top
View user's profile Send private message
doob



Joined: 06 Jan 2007
Posts: 367

PostPosted: Sun Feb 06, 2011 5:35 am    Post subject: Reply with quote

I'll see if I can find time for this and look into what's going on. BTW you do know that Cocoa (which is used under the hood in SDL) is not thread safe? Meaning that basically all manipulations of the GUI needs to be done in the main thread. The NSObject class (the root class in Objective-C) has a method were you can call another method on the main thread. Maybe this method can be made available and used in the library.

http://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSObject_Class/Reference/Reference.html#//apple_ref/occ/instm/NSObject/performSelectorOnMainThread:withObject:waitUntilDone:
Back to top
View user's profile Send private message
doob



Joined: 06 Jan 2007
Posts: 367

PostPosted: Sun Feb 06, 2011 5:40 am    Post subject: Reply with quote

Please report a ticket as well so it's not forgotten: http://dsource.org/projects/derelict/newticket
Back to top
View user's profile Send private message
Poita_



Joined: 23 Jul 2010
Posts: 8

PostPosted: Mon Feb 07, 2011 6:53 am    Post subject: Reply with quote

Done: http://dsource.org/projects/derelict/ticket/67
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic     Forum Index -> Derelict All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group