Interrupting waiting thread
On 12/03/2015 at 09:51, xxxxxxxx wrote:
Cinema 4D Version: R15
Platform: Windows ;
Language(s) : C++ ;
during the development of few plugins, I came to 2 very similar problems:
1. I have a C4DThread (lets call it thread A), which has to wait for some other work to be done by other thread (thread B). To do synchronization, I can simply use GeSignal and its Wait() method.
Now let say I want to interrupt thread A from somewhere else (e. g. from main thread). If I use TestBreak correcty in the implementation of thread A, it is simple. But I cannot check TestBreak during GeSignal::Wait() method (and the method is not interrupted by calling the Break() of thread its called from, at least it was not in the test plugin I made).
Is there some way to allow interruption during GeSignal::Wait() other than giving it a small timeout, checking TestBreak and repeating it?
2. Similar situation with GeSleep - I want to suspend the thread from its Main method for specific time, but I want to be abble to interrupt the thread even if its suspended. Is there a solution other than repeated calls to GeSleep with smaller times and checking TestBreak inbetween?
Thanks for any answer.
On 13/03/2015 at 07:38, xxxxxxxx wrote:
I suggest to use GeSignal::Wait(timeout) instead of GeSleep(). In this way you can use GeSignal::Set() to interrupt your sleep.
Similarly I suggest to simply use GeSignal::Set() to wake the thread A (so it can use TestBreak()) from anywhere you like.
On 13/03/2015 at 11:08, xxxxxxxx wrote:
thanks for advice. I will simply call Set() of all GeSignal after calling Break().
But I forgot to mention the situation with GeSleep is a little more complex than the first one - I have only BaseThread and do not call Break() myself.
To give more detail, I need to wait for specific amount of time inside VideoPostData::Execute, but there I have only BaseThread (vps->thread) I can check for TestBreak and interruption of the thread is done by C4D (user break). Maybe there is some message recieved in VideoPostData that would tell me about interruption and I could use GeSignal::Set() to stop waiting? Or is there some more general solution?
On 13/03/2015 at 11:31, xxxxxxxx wrote:
I will discuss this with a colleague on Monday.
Actually sleeping in VPD::Execute() sounds horrible to me and I'm not sure one is supposed to do so at all.
Can you explain in a bit more detail, why you have to do this?
On 13/03/2015 at 14:03, xxxxxxxx wrote:
Yes, I understand why waiting in VP sounds horrible :-)
The VP is in fact an external renderer and the actual rendering of the image is done outside of VP in another thread. It is rendered to memory object (not BaseBitmap; code in another closed-source library so cannot be changed) and during the rendering, I am refreshing the result stored in VP (to allow user see the visual progress). Because the conversion of image data from memory to BaseBitmap/VPBuffer can be quite expensive (includes color conversion), the refreshing is done in intervals, e. g. 5 seconds, untill the rendering in other thread completes.
On 13/03/2015 at 14:38, xxxxxxxx wrote:
there should be a better workaround.
create an event "which checks a flag" , this flag is sent to your Renderer DLL, update this flag as needed from the DLL, and the event system will read the flag change automatically to update the Bitmap draw
On 13/03/2015 at 18:55, xxxxxxxx wrote:
Do you mean updating on change instead in interval? Unfortunatelly, that is not possible in my situation - the data from renderer DLL are actually updated very frequently - if I used a flag to determine change in the data, it would be the same as simply updating bitmap in a loop (and wasting compute time usable by renderer DLL).
On 14/03/2015 at 05:43, xxxxxxxx wrote:
actually no , for example the Renderer has rendered 10 samples, update, don't update every 1 sample, but the control will be from inside the DLL, the DLL determines when the flag will be true for a redraw.