Search for NSImage here:

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html#//apple_ref/doc/uid/10000057i-CH12-126728

It sounds like you may need to do this serially, or try setting the cache mode 
to NSImageCacheNever right after you create the new NSImage to see if you can 
avoid hitting the shared cache.

Alternatively, you might want to look into using NSBitmapImageRep or 
CGImageSourceCreateThumbnailAtIndex.

-aaron


> On Aug 8, 2016, at 11:05 AM, Andrew Keller <and...@kellerfarm.com> wrote:
> 
> Hi all,
> 
> In my app, I’m creating thumbnails of images.  To do this in parallel, I’m 
> using the global background dispatch queue:
> 
> dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 
> 0), ^{
>    @autoreleasepool {
>        NSSize *thumbnailSize = // calculate thumbnail size
>        NSImage *thumbnail = [img imageByResizingTo:thumbnailSize];
>        // Do stuff with result
>    }
> });
> 
> I have this in a category extension on NSImage:
> 
> - (NSImage *)imageByResizingTo:(NSSize)newSize {
>    NSImage *newImage = [[NSImage alloc] initWithSize:newSize];
>    NSSize currentSize = [self size];
>    NSRect currentRect = NSMakeRect(0, 0, currentSize.width, 
> currentSize.height);
>    NSRect newRect = NSMakeRect(0, 0, newSize.width, newSize.height);
> 
>    [newImage lockFocus];
>    [self drawInRect:newRect fromRect:currentRect operation:NSCompositeCopy 
> fraction:1.0f];
>    [newImage unlockFocus];
> 
>    return newImage;
> }
> 
> However, when enough images are being processed simultaneously, the 
> background threads servicing the queue appear to all lock up with this stack 
> trace:
> 
> #0    0x00007fff93d2951a in semaphore_wait_trap ()
> #1    0x00007fff8b75ac5b in _os_semaphore_wait ()
> #2    0x0000000100074e12 in _dispatch_barrier_sync_f_slow ()
> #3    0x00007fff89315182 in ___lldb_unnamed_function872$$RawCamera ()
> #4    0x00007fff86a98e26 in ImageProviderCopyImageBlockSetCallback ()
> #5    0x00007fff877d5279 in img_blocks_create ()
> #6    0x00007fff87804598 in img_blocks_extent ()
> #7    0x00007fff877c55b0 in img_data_lock ()
> #8    0x00007fff877c25a6 in CGSImageDataLock ()
> #9    0x00007fff8be62a02 in ripc_AcquireImage ()
> #10   0x00007fff8be61525 in ripc_DrawImage ()
> #11   0x00007fff877c21b0 in CGContextDrawImage ()
> #12   0x00007fff8ee9627d in __75-[NSBitmapImageRep 
> _withoutChangingBackingPerformBlockUsingBackingCGImage:]_block_invoke ()
> #13   0x00007fff8ee95969 in -[NSBitmapImageRep 
> _withoutChangingBackingPerformBlockUsingBackingCGImage:] ()
> #14   0x00007fff8ee958f5 in __53-[NSBitmapImageRep 
> _performBlockUsingBackingCGImage:]_block_invoke ()
> #15   0x00007fff8ee95859 in -[NSBitmapImageRep 
> _performBlockUsingBackingCGImage:] ()
> #16   0x00007fff8ee957b4 in -[NSBitmapImageRep CGImage] ()
> #17   0x00007fff8ee95719 in -[NSBitmapImageRep 
> CGImageForProposedRect:context:hints:] ()
> #18   0x00007fff8ee4e6af in __74-[NSImageRep 
> drawInRect:fromRect:operation:fraction:respectFlipped:hints:]_block_invoke ()
> #19   0x00007fff8ee4e195 in -[NSImageRep 
> drawInRect:fromRect:operation:fraction:respectFlipped:hints:] ()
> #20   0x00007fff8f33e656 in __71-[NSImage 
> drawInRect:fromRect:operation:fraction:respectFlipped:hints:]_block_invoke1012
>  ()
> #21   0x00007fff8edf4dc6 in -[NSImage 
> _usingBestRepresentationForRect:context:hints:body:] ()
> #22   0x00007fff8ee4d9d7 in -[NSImage 
> drawInRect:fromRect:operation:fraction:respectFlipped:hints:] ()
> #23   0x0000000100008aa5 in -[NSImage(AppKitHelpers) imageByResizingTo:] at 
> /Users/kelleran/Documents/Example/Example/AppKitHelpers.m:43
> [ snip ]
> 
> Then, if I try to do anything in the app such as click a button or quit the 
> app, the main thread locks up too, with this stack trace:
> 
> #0    0x00007fff93d2951a in semaphore_wait_trap ()
> #1    0x000000010006d2d5 in _dispatch_semaphore_wait_slow ()
> #2    0x00007fff908f4da9 in xpc_connection_send_message_with_reply_sync ()
> #3    0x00007fff90b1fe99 in _LSCopyApplicationInformation ()
> #4    0x00007fff90b29a6c in _LSCopyApplicationInformationItem ()
> #5    0x00007fff8ef8d08d in -[NSApplication _copyPublicPersistentUIInfo] ()
> #6    0x00007fff8ef8b570 in recursivelyEncodeInvalidPersistentState ()
> #7    0x00007fff8ef8a13a in -[NSPersistentUIManager 
> flushAllChangesOptionallyWaitingUntilDone:updatingSnapshots:] ()
> #8    0x00007fff8ef89c6b in -[NSPersistentUIManager 
> flushPersistentStateAndClose:waitingUntilDone:] ()
> #9    0x00007fff8ed5c466 in run_cocoa_block ()
> #10   0x00007fff8ef89b8e in __42-[NSPersistentUIManager 
> acquireDirtyState]_block_invoke ()
> #11   0x0000000100062fc3 in _dispatch_client_callout ()
> [ snip ]
> 
> Experimentally, it seems that I need at least 10 to 20-ish threads actively 
> performing work from the queue simultaneously for the deadlock to occur.  
> However, just because more threads reproduces the issue faster doesn’t mean 
> that fewer threads makes the problem go away entirely — it could just be a 
> matter of probability and luck.  To guarantee that nothing deadlocks, must I 
> perform this work serially, or is there something I’m doing wrong?
> 
> Thanks,
> - Andrew Keller
> 
> _______________________________________________
> 
> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
> 
> Please do not post admin requests or moderator comments to the list.
> Contact the moderators at cocoa-dev-admins(at)lists.apple.com
> 
> Help/Unsubscribe/Update your Subscription:
> https://lists.apple.com/mailman/options/cocoa-dev/mandelbaum%40mac.com
> 
> This email sent to mandelb...@mac.com


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to