mwoods
mwoods

Reputation: 255

NSThread detachNewThreadSelector executing on main thread

A small number of customers are getting hangs from my OS X app with the following hang log signature:

26 ??? [0x7fff93e87fc9]
26 ??? [0x7fff93e8372a]
  26 ??? [0x7fff93e83899]
    26 __NSThread__main__ + 1318 (Foundation) [0x7fff8be96dfb]
      26 -[AppController startClean] + 1319 (Housekeeper) [0x100007742]
        13 -[AppController trashMediaCache:] + 435 (Housekeeper) [0x100010e7a]
          13 +[MYFileManager trashFilesOfType:inFolder:] + 482 (Housekeeper) [0x100022e2a]
            13 +[MYFileManager trashFile:] + 22 (Housekeeper) [0x1000227f7]
              12 +[MYFileManager trashFile:shouldAuth:] + 226 (Housekeeper) [0x1000228de]
                12 -[NSWorkspace performFileOperation:source:destination:files:tag:] + 319 (AppKit) [0x7fff8aa72bbb]
                  12 -[NSWorkspace _fileOperation:source:destination:files:] + 917 (AppKit) [0x7fff8aa72f7e]
                    12 _FSOperateOnObjectSync + 482 (CarbonCore) [0x7fff87ab309c]
                      12 _NodeOperation + 488 (DesktopServicesPriv) [0x7fff90d6e38a]
                        4  TFSCopyOperation::DoMoveToTrash(TCountedPtr<TCFURLInfo> const&) + 330 (DesktopServicesPriv) [0x7fff90d7e28c]
                          4  TFSInfo::MoveAndRenameTo(TCountedPtr<TFSInfo> const&, TUString*, TCountedPtr<TFSInfo>&) const + 677 (DesktopServicesPriv) [0x7fff90da4ae7]
                            4  TCFURLInfo::RenameWithoutReplacing(char const*, char const*, bool) + 162 (DesktopServicesPriv) [0x7fff90d89620]
                              4  __rename + 10 (libsystem_kernel.dylib) [0x7fff861ba97a]
                                3  <Suppressed>
                        3  TFSCopyOperation::DoMoveToTrash(TCountedPtr<TCFURLInfo> const&) + 1033 (DesktopServicesPriv) [0x7fff90d7e54b]
                          3  THFSPlusPropertyStore::SetProperty(TUString const&, unsigned int, TPropertyReference const&) + 81 (DesktopServicesPriv) [0x7fff90d26bc1]
                            3  TDSMutex::Acquire() + 34 (DesktopServicesPriv) [0x7fff90ce5d00]
                              3  __psynch_mutexwait + 10 (libsystem_kernel.dylib) [0x7fff861ba746]
                                1  <Suppressed>
                        2  TFSCopyOperation::DoMoveToTrash(TCountedPtr<TCFURLInfo> const&) + 995 (DesktopServicesPriv) [0x7fff90d7e525]
                          2  THFSPlusPropertyStore::SetProperty(TUString const&, unsigned int, TPropertyReference const&) + 81 (DesktopServicesPriv) [0x7fff90d26bc1]
                            2  TDSMutex::Acquire() + 34 (DesktopServicesPriv) [0x7fff90ce5d00]
                              2  __psynch_mutexwait + 10 (libsystem_kernel.dylib) [0x7fff861ba746]
                                1  <Suppressed>

As you can see from the log, startClean is running on the main thread. But the confusing part is that there is only one call to startClean, as follows:

[NSThread detachNewThreadSelector:@selector(startClean) toTarget:self withObject:nil];

So the code should be executing on a separate thread, and indeed, that's the way it works on my system, but more than one customer has experienced this on OS X 10.9.5. There are a couple of calls to the main thread inside startClean, but these are only for updating the UI. The trashMediaCache call is executed by performSelector:withObject: but not performSelectorOnMainThread.

Has anyone seen this before? Is this an OS X bug or are there situations where the system will divert calls to the main thread by design? Or am I just misinterpreting the log?

P.S. I know I can use a dispatch call or operation queue and that might fix the issue but I'd still like to know the answer to the original question.

Upvotes: 0

Views: 428

Answers (2)

Greg Parker
Greg Parker

Reputation: 8012

__NSThread__main__ is not the main thread. It is the internal entry point for an NSThread's execution.

Upvotes: 1

Reinhard M&#228;nner
Reinhard M&#228;nner

Reputation: 15247

Obviously, your startClean method that runs in the background, triggers some code to run on the main thread, which causes a deadlock.
One possibility is that startClean uses Core Data. This is described here.
Another possibility is a completion handler that is executed on the main thread. There are many, e.g. the MKLocalSearchCompletionHandler, where the docs state explicitly that they are always executed on the main thread.

Upvotes: 1

Related Questions