Jump to content

Difference between called via python shell and via parm callback / shelf tool?


violalyu

Recommended Posts

Hi Houdini friends,

I'm having a pretty weird issue right now and was wondering if this is something that someone else has encountered before:

When I call a function as a callback to some button on an HDA/ shelf script, the result is different from when I directly call it in the python shell of an opened Houdini session / directly in a hython shell.

More specifically, when called as a callback, it hangs; while when called from hython it went through as expected;

The function involves some general wrapping code, that execute some houdini specific code, and it seems that any call from the hou module would hang when ran as callback.

Does anyone have similar issues before / knows more about what might be different when something is executed as parm callback vs. directly from hython? Thanks soooooo much in advance!

Link to comment
Share on other sites

20 hours ago, toadstorm said:

Can you post your code, or at least relevant snippets of it? Out of context it's hard to tell exactly what could be going wrong.

Hi @toadstorm, thanks for the reply!

I've tried to understand what it was, and so far I've got some more information on it:
 

The python shell in a Houdini session is not running on the main thread, but the parm callback / shelf script is executed on the main thread (similar reason to when trying to launch any qt related stuff from that python shell it crashes Houdini);

Now I can try to spawn a new thread in the shelf script and have it target to my function, however the issue is that calling `Thread.join()` hangs it (I need to get the result from the function, trying to use a `ThreadPool` and getting back the async result hangs the same), and I haven't been able to get a workaround for this yet....

 

import hdefereval
from functools import partial
from threading import Thread

def test(result):
	result.append(hou.expandString('$HIP'))

def run():
	hdefereval.executeInMainThreadWithResult(partial(test, result))

result = []
t = Thread(target=run)

t.start()
t.join() // this hangs

// -- Similar result

def anotherTest(result):
	result.append(hou.expandString('$HIP')

t1 = Thread(target=anotherTest, args=(result,))
t1.start()
t1.join() // this also hangs

 

Edited by violalyu
Link to comment
Share on other sites

Here are a few things to know:

First, you should never use hdefereval.executeInMainThreadWithResult from the main thread, obviously, it'll always lock the session.

Now, what's going on with user's Thread instances is a little bit odd from a viewpoint of a regular Python interpreter. When you join(), you tell other threads (main thread, in our case) to lock and wait. This seems to work fine with Houdini, until you start making calls to Houdini API from your thread, (hou.expandString() in your case)

For this reason, there's a hdefereval.executeDeferred(callback) method exists, which doesn't block, but if you need to get something back from your callback, you'd have to take care of this yourself, there are many ways to do this, for example using Queues. This is common producer-consumer pattern.

Hope this helps.

 

 

Link to comment
Share on other sites

  • 2 months later...
On 2019/9/14 at 4:35 PM, Stalkerx777 said:

Here are a few things to know:

First, you should never use hdefereval.executeInMainThreadWithResult from the main thread, obviously, it'll always lock the session.

Now, what's going on with user's Thread instances is a little bit odd from a viewpoint of a regular Python interpreter. When you join(), you tell other threads (main thread, in our case) to lock and wait. This seems to work fine with Houdini, until you start making calls to Houdini API from your thread, (hou.expandString() in your case)

For this reason, there's a hdefereval.executeDeferred(callback) method exists, which doesn't block, but if you need to get something back from your callback, you'd have to take care of this yourself, there are many ways to do this, for example using Queues. This is common producer-consumer pattern.

Hope this helps.

 

 

Hi @Stalkerx777 , thanks so much and sorry about the super late reply! I just realized that I've never replied... 

In my use case, it turned out to be that the third party library that I'm using is subclassing threading.Thread, and houdini is also doing something for each thread, I forgot the specifics but something related to `HOM_AutoLock`, thus when it runs those threads, something about the lock status cased it to hang

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...