Thursday, April 1, 2010

Thread Safety in Channel Ports Suite

Hi,



I cannot find a lot of mentions on threads is the api documentation.



I've got the sentence on page 99 of the API documentation, which advocate the use of tiles for multi-processors. But I don't know who is responsible as for synchronizing the datas.



Is the ReadPixelsProc re-entrant ?



Is the WriteBasePixelsProc re-entrant if the destinations rectangles intersections are null ?



Or should I always resync the data from the entry point thread (read and/or write) ?



Thanks,



Raphael
Thread Safety in Channel Ports Suite
From my experience, I would recommend avoiding any threading with the Photoshop API whatsoever. I had endless troubles trying to do background processing in a separate thread, and ended up giving up completely. You might be able to get stuff to work, but it probably won't be stable. I'm pretty sure the API is not thread-safe; I expect this is one of the reasons they supply the progress bar routines. (I suspect it may have to do with Photoshop's own virtual memory system with the scratch disk and so on.)



YMMV.



Matthew.
Thread Safety in Channel Ports Suite
Oh well I won't give up (octo processors from apple really deserve it !), but I'm definitely going to resynchronise every thing in the same thread as the entry point thread.



From what you say, it looks like there is at least no locking in the host part of the API implementation.

Then I guess that writing, even with distinct aera would fail. From what I remember, photoshop tweak layer saving by tracking the real enclosing bounds of a layer. With no locking on this bounds (and actual image memory reallocation), a concurrent write might fail.



However, and even without locking, read of pixels might work as soon as there is not a caching mechanism. The only caching scheme I might think of is the layer pyramid if you use scaling. As long as you ask for pixels in the base level, no write should be done.



But this is only speculation... an official point on this in the documentation would be welcome, as having a tread safe read for base level pixels would be a little easier to feed the threads.



Thanks for you reply,



Raphael

Sorry to dig up an old thread, but the following seems to work for OS X (I haven't done my windows version yet):



Don't have your threads call the Photoshop API. Let your main process grab the pixel data and stick it into your own buffers. Make these buffers via BufferProcs (i.e. the normal way) from your main process.



Now suppose you want to handle the progress bar updating correctly. To do this, don't run 1 of your threads and instead perform the same actions from within your main process. You would call the Photoshop API from your main process, and then join your threads. Make a function that calls gFilterRecord-%26gt;progressProc and abortProc() and have that set a global in your plugin to true if the user canceled operation. This way your threads can check that global and abort when necessary. The way I'm doing this is that my image processing function will call a progressUpdate() function (my creation) often and set it a thread/process ID (I send this as a parameter into each thread or the main process). If the ID is the main process, then it will call the Photoshop API. Otherwise it will just check the global and return whether or not the thread should abort.



Seems to work for me.

No comments:

Post a Comment