Jump to content
violalyu

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

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!

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
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

Share this post


Link to post
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.

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×