[Stackless] "Attempt to run a locked frame!"
Bernd.Rinn at epost.de
Tue Feb 20 13:04:50 CET 2001
On Mon, Feb 19, 2001 at 07:55:23PM -0500, Gordon McMillan wrote:
> [...] What's probably going on is either (1) trying to use a
> continuation from a recursive invocation of Python or (2) trying
> to use a plain callable object as a continuation.
> You could hit (1), for example, by trying to use a continuation
> within a __getitem__ (or other magic method). This is
> implemented by C code that realizes it needs to execute pure
> Python, so recursively invokes the interpreter. But if that pure
> Python tries to use a continuation created in an outer
> invocation of the interpreter, it would trash the C stack. So, it's
> streng verbotten. [...]
Does "use a continuation" include an automatic task switch performed
by the uthread module? And as a consequence: are magic methods written
in Python generally a bad idea when using microthreads? I do not use
continuations directly but only the uthread module. What actions in
uthreaded programs could trigger (1) or (2)?
More generally: Is there somewhere a list of do's and dont's when
I have written a metathread package to encapsulate differences between
threads und uthreads and a multithreaded server framework that makes
use of it (python remote procedure calls) and I want to make it freely
available to the Python community very soon. It has been a nice amount
of work and I really want to get it out of the door. Unfortunately the
"Attempt to run a locked frame!" exception crashes each and any
prpc-session when using microthreads instead of Python threads.
> BTW, your sample code neglected to say what module was
> what, so I didn't bother to try it.
Oh, I am sorry about that. So here are the explanations:
* comm.py contains functions to perform socket operations in a
non-blocking way (when using microthreads), such as accept() or
send(). The core function of this module is nbselect() which
substitutes select.select() from the Python Libarary. So if 's' is a
socket you do not call
(BTW: the nbselect() in connect() is rubbish.)
* socketFile.py defines a class socketFile that is instantiated with a
socket 'sock' and a mode (either readMode or writeMode). It is used
to transmit Python data objects over a socket by means of pickling
and unpickling. To transmit an object 'x', you do:
f = socketFile.socketFile(sock, socketFile.writeMode)
f = socketFile.socketFile(sock, socketFile.readMode)
x = cPickle.load(f)
* miniserver.py spawns a uthreaded server that is listening on 'PORT'
(which is set to 50000). It consists of (1) serverloop() which
accept()s new connections and (2) handle() which handles the connection
requests. serverloop() spawns a new microthread for each
connection running the function handle() therein.
* miniclient.py makes a connection to port 'PORT' on localhost and
causes some network traffic in a loop. It transmits trash to the
server and receives a list of active connections. Finally it sends
a 'None' to finish the connection.
When I start one miniserver and one miniclient everything works
well. As soon as I start two miniclients in parallel, the server
bombs with the exception
SystemError: Attempt to run a locked frame!
Since I am not familiar with continuations I see no way to track down
that bug myself. I ask myself, if it bites other uthread users as well...
Fakultät für Physik
e-mail: Bernd.Rinn at uni-konstanz.de
PGP-Fingerprint: 1F AC 31 64 FF EF A9 67 6E 0D 4C 26 0B E7 ED 5C
Stackless mailing list
Stackless at starship.python.net
More information about the Stackless