[C++-sig] binding a userspace thread library
Mathieu Lacage
Mathieu.Lacage at sophia.inria.fr
Thu Jan 5 10:05:21 CET 2006
On Wed, 2006-01-04 at 11:20 -0500, Stefan Seefeld wrote:
> > [mlacage at chronos yans-current]$ ./bin/python/test-thread.py
> > before sleep
> > Exception exceptions.NameError: "global name 'time_s' is not defined" in 'garbage collection' ignored
> > Fatal Python error: unexpected exception during garbage collection
> > Aborted
> > [mlacage at chronos yans-current]$
> >
> > This error message does not look quite right: it looks like a collision
> > of two error messages. Am I wrong ?
>
> To me it looks plausible: The worker thread writes 'before sleep' and
> then stops. The error you are seeing then seems to be coming from
> the cleanup at the end of your script, i.e. it appears to be an entirely
> different issue.
I fail to see how the call to Simulator.destroy could generate such a
warning but you are likely to be right.
[snip]
> > Traceback (most recent call last):
> > File "./bin/python/test-simulator.py", line 34, in ?
> > simulator.run ()
> > File "./bin/python/test-simulator.py", line 7, in notify
> > print "my event class now=%f" % now_s ();
> > NameError: global name 'now_s' is not defined
> >
> > I suspect that the c++ exception I ignore is interpreted correctly by
> > the boost bindings which re-generate the correct python error. Or maybe
> > not.
>
> I'm not sure. Are you saying that the 'now_s()' call should actually succeed ?
no. I am merely concerned by the fact that I do not get the same warning
when using a Thread and when not using a Thread.
I suspect that, in the case shown here, we have:
- python interpreter calls Simulator.run which calls c++
Simulator::Run
- c++ Simulator::run calls c++ EventWrap::notify which calls python
MyEvent.notify
- MyEvent.notify generates python error because now_s is not defined
and returns.
- c++ EventWrap sees python error, generates c++ exception.
- c++ exception propagates to the outer of Simulator::run, that is the
boost binding for Simulator::run.
- c++ boost binding eats the c++ exception, generates a python error.
In the other case I was looking at, I have:
- python interpreter calls Simulator.run which calls c++
Simulator::Run
- Simulator::Run calls some Event::notify which switches to another c+
+ Thread's stack (c++ Thread::run)
- c++ ThreadWrap::run calls python Thread.run
- python Thread.run generates python error because now_s is not
defined and returns.
- c++ boost binding code generates c++ exception from python error.
- c++ ThreadWrap::run sees exception, eats c++ exception, switches
back to main thread
- c++ main thread (that is, Simulator::run) keeps on executing until
the end of the simulation.
- at the end of the simulation, c++ Simulator::run returns to python
interpreter which keeps on executing
- python interpreter runs Simulator.destroy (), triggers, another
errors, and displays the new error's message together with the old error
message.
So, I decided to work around this by forwarding the boost c++ exception
from my c++ thread to the c++ main thread such that the python
interpreter can generate the right error message as soon as possible. I
ended up doing this:
class ThreadWrap {
void rethrow_exception (error_already_set &set) {
throw set;
}
virtual void run (void) {
try {
call_method<void>(m_self, "run");
} catch (error_already_set &set) {
Simulator::insert_later (make_event (&ThreadWrap::rethrow_exception, this, set));
}
}
};
Which as the nice side-effect of now generating the correct error
message with a buggy script:
[mlacage at chronos yans-current]$ bin/python/test-thread.py
before sleep
Traceback (most recent call last):
File "bin/python/test-thread.py", line 14, in ?
simulator.run ()
File "bin/python/test-thread.py", line 10, in run
print "after sleep %f" % time_s ();
NameError: global name 'time_s' is not defined
[mlacage at chronos yans-current]$
Which is really uber-cool.
> May be you are right, and you need to clear the error flag first before
> terminating the worker thread. Try calling 'PyErr_Clear()' in your exception
> handler in the worker thread. (see http://docs.python.org/api/exceptions.html)
Nice. But I don't think I want to do this.
thanks for your comments,
Mathieu
--
More information about the Cplusplus-sig
mailing list