> On 23 Jul 2016, at 4:09 PM, Ken Thomases <k...@codeweavers.com> wrote:
> 
> No, because the main thread may not have started servicing the 
> performSelector request yet.  The background thread has blocked as soon as 
> the request is _queued_ for the main thread, not just once the main thread 
> has received the request.  If the main thread makes a synchronous request to 
> the background thread before it gets back to the run loop to service the 
> pending performSelector request, it will deadlock.
> 


I’m trying to get my head around this.

If -performSelectorOnMainThread is called with a waitUntilDone:YES, then that 
whole call must be surrounded by a lock (?)

The main thread may be doing other things and take its time to get around to 
this. One of the things it could do is to try to terminate the thread that is 
blocked waiting on the performSelector. OK, fair enough. But how can that call 
to terminate the thread itself block? If it synchronously waits for the thread 
to terminate, then yes, I can see that would be a bad idea. But is that a 
reasonable scenario? What if the “termination” is just setting a flag that the 
other thread checks? That would surely be safe?

What does “thread termination” mean anyway? Even at the lower levels of 
threads, isn’t the scheduler really just setting a similar flag? When the 
thread gets unblocked, the scheduler checks that flag to see if the thread 
should get further time or killed.

Seems to me *something* has to be on the outside of all the locking, blocking 
and running and that something would be the scheduler. Otherwise threads would 
deadlock all the time and that isn’t really the case - you normally have to go 
out of your way to do something silly to cause that.

Anyway, haven’t we establishd that passing YES to waitUntilDone: here isn’t 
necessary? Performing the copy should avoid the need.

Another thing:

Also, further thinking about that copy, I seem to recall that NSBitmapImageRep 
has a copy-on-write setup, so that at first that call to -copy will be quick 
and cheap - both resulting objects share the pixel buffer. If one or the other 
of those objects then calls -bitmapData, then a unique copy of its buffer will 
need to be made, on the assumption that something’s going to write to the 
buffer. If this is the worker thread, effectively it’s making a new buffer just 
as Roland suggested you could do manually. That’s provided that the worker 
thread calls -bitmapData at the start of its work, and doesn’t cache that 
pointer or assume it never changes with each outer run of the thread’s loop.

Given this, the original outline is a workable one - the worker thread never 
needs to wait or block on the main thread, it can pass the bitmap across to the 
window as an (atomic, copy) property, and as long as it calls -bitmapData as it 
starts the next chunk of work, it will be as performant as Roland’s idea of 
making a new bitmap each time, if not slightly more so.

Having said all that, the copy-on-write behaviour is something I can’t find any 
hard documentation for. I seem to recall that this came up in a discussion 
about NSImage/NSBitmapImageRep a long time ago just after the internal 
behaviour of these classes was overhauled. That may have been in the 10.5 or 
even earlier era.

—Graham



_______________________________________________

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