GeGetEscTestThread Safeness

On 21/11/2017 at 09:38, xxxxxxxx wrote:

User Information:
Cinema 4D Version:    
Language(s) :     C++  ;

Hello I'm currently doing some stuff with thread, and I would like to break on escape key so I do (and it's work pretty well)

Bool PolyThread::TestDBreak(void)
	BaseThread* const escThread = GeGetEscTestThread();
	if (!escThread)
		return false;
	return (escThread->TestBreak());

But I'm asking myself, if it's safe to get the return thread of GeGetEscTestThread() while the init of my thread and then just checking the escThread->TestBreak() in my TestDBreak method?
Which would avoid variable init within a pretty intensive loop (since I call TestDBreak in this loop and I would ideally avoid any variable init from it for performance reason.)

Thanks in advance !

On 22/11/2017 at 09:04, xxxxxxxx wrote:


I think, there is a slight misunderstanding.

Why would you want to use the "Escape Test Thread" from within another thread? Seems kind of redundant to me. The "Escape Test Thread" returned from GeGetEscTestThread() is thought to be used as parameter to longer running functions, which you want to interrupt via the escape key.
When implementing your own thread, you'd rather test for the break condition (escape key pressed) yourself in TestDBreak().

To your last question, generally there's no problem with storing the thread pointer during initialization and using it later on.

On 22/11/2017 at 14:23, xxxxxxxx wrote:

To be sure, PolyThread inherite from C4dThread.

So doing as you said, (and what I did first)

Bool PolyThread::TestDBreak(void)
	BaseContainer msg;
	if (GetInputState(BFM_INPUT_KEYBOARD, KEY_ESC, msg))
		return msg.GetBool(BFM_INPUT_VALUE);
	return false;

Make c4d crash on GetInputState, so I guess GetInputState can't be used in a C4DThread? So it's why I used the GeGetEscTestThread

On 24/11/2017 at 09:08, xxxxxxxx wrote:

I need to ask for a bit more patience, it's not as easy as our documentation suggests...

As an explanation: The docs state, you could use TestDBreak() to test for escape key. But this seems to be a comment from ancient times, because nowadays (as you experienced) GetInputState() and GetInputEvent() may only be used from the main thread... And actually you are not experiencing a crash, but a CriticalStop, because of this. I'm currently in the process of finding another solution to test for the escape key.

On 24/11/2017 at 09:43, xxxxxxxx wrote:

No problem, I've fix it by catching message on the main thread, then set a member variable within my C4DThread and check if I must leave of not. But it's ask for a GeRWSpinLock so it's kind of big things for not so much.

But anyway I would still like to know why this failed.

On 24/11/2017 at 09:45, xxxxxxxx wrote:

Sorry, I probably was to late editing my post above... at least there you have an explanation. And yes, I thought of a similar solution, as you came up with. But I am still hoping for something simpler.

On 24/11/2017 at 09:53, xxxxxxxx wrote:

Thanks for the explanation (I have to read more about CriticalStop). Is there a way to know if a function is thread safe or should I understand if it's not explicitly written, that mean is not?

I know it's one of the UI functions and all UI stuffs didn't allow to be called from thread. But for other function.

Anyway take your time, happy week end ! ;)

On 28/11/2017 at 09:29, xxxxxxxx wrote:

Well, well, it was naive to just repeat from our docs.

As you already figured out, no UI functions may be called in a threaded context.
Basically the list under Forbidden Functions in Important Threading Information. Probably we should be more precise there and add "user input" functions to "GUI functionality". Otherwise you can consider our API thread safe unless explicitly mentioned otherwise.

Unfortunately this also means, the comment in C4DThread::TestDBreak() documentation is a bit misleading. As you only have the two options you already found and described in this thread. The one I discouraged in the first place (sorry!), using GeGetEscTestThread(). And your second one catching escape key in main thread and forwarding this information to the thread.
We will fix the documentation of TestDBreak().

Lastly one more thought from our development, when discussing this issue: Depending on your design, you may want to correlate the check for the escape key to some kind of user focus. So your thread does not get interrupt, just because the user presses escape to interrupt a viewport render for example.