Ctypes and C Infinite Callback Loops

Thomas Dimson tdimson at gmail.com
Wed Apr 9 18:51:00 EDT 2008


On Apr 9, 1:24 am, Dennis Lee Bieber <wlfr... at ix.netcom.com> wrote:
> On Tue, 8 Apr 2008 16:49:27 -0700 (PDT), Thomas Dimson
> <tdim... at gmail.com> declaimed the following in comp.lang.python:
>
>
>
> > I assume there is some issue with the global interpreter lock or that
> > you can't exit the infinite loop from above Python. Any suggestions on
> > how I can design this so the thread will be able to issue exits/raise
> > exceptions just like a regular thread? Is there a way of terminating
> > this thread from the python interpreter or ctypes.pythonapi?
>
>         No... as I recall, you can't /EXIT/ Python from a sub-thread...
> Which is what sys.exit() or whatever is trying to do -- shut down the
> entire program, not just the thread. The error you get indicates that
> the thread doing the shutdown wants to wait for the sub-thread to finish
> -- but /it/ IS the sub-thread. Even console interrupts have to be
> delivered to the main program.
>
>         The only safe way to terminate a thread is to be able to code it
> such that /it/ responds to an externally set value (a boolean, read a
> message off a Queue, etc.) and for IT to then exit. Based upon the
> sample you showed, that would require the C main loop to be checking for
> a shutdown signal... If the API to that main loop library doesn't
> include a shutdown capability I'd suggest it is a less than complete
> library... And the only thing I'd suggest is not using a Python thread,
> but instead spawning a separate process that somehow communicates to the
> parent process -- and which can be forceably killed using OS specific
> capabilities... "kill -9 pid" <G>
>
> --
>         Wulfraed        Dennis Lee Bieber               KD6MOG
>         wlfr... at ix.netcom.com              wulfr... at bestiaria.com
>                 HTTP://wlfraed.home.netcom.com/
>         (Bestiaria Support Staff:               web-a... at bestiaria.com)
>                 HTTP://www.bestiaria.com/

Thanks for the response, it put me in the right direction (I didn't
realize there was no way of exiting the interpreter directly from a
non-main thread).

If anyone ever has the same problem, the solution I ended up using
went like this:

I created a wrapper around the infinite loop call that had a setjmp in
it, exiting if setjmp was non-zero.

Inside each callback function, I had a try/except statement that
caught all exceptions. If it had an exception, it would set a thread-
specific exception variable to sys.exc_info() and then call a C
function that did a longjmp.

The thread would first call the wrapper to the infinite loop. If the
wrapper returns (because of a longjmp), it would check the thread-
specific exception variable for a non-None value and raise the very
same exception (with the same traceback) if it found it.

A fairly large hack, but it seemed to do the job. Thanks again.



More information about the Python-list mailing list