[Stackless] "Attempt to run a locked frame!"
Bernd Rinn
Bernd.Rinn at uni-konstanz.de
Mon Feb 12 14:19:11 CET 2001
Hi,
I am currently trying to port a threaded socket-server from
Standard-Python threads to microthreads and I am getting strange error
messages:
"SystemError: Attempt to run a locked frame!"
when calling a constructor of a class within a microthread that is
running (at least) twice.
Since the program works well with Standard-Python threads, I suspect
it might be a bug either in stackless python or in the microthread
implementation.
I have attached the striped-down sample code to this mail.
To reproduce the error, start miniserver.py once and miniclient.py
twice in parallel.
My Platform is GNU/Linux 2.2.x with glibc 2.1.3 and compiler gcc
2.95.2. I am using Python 2.0.42-S1.2.4 together with the new
uthread.py from http://world.std.com/~wware/.
Does anyone have an idea what's going wrong here?
Regards,
Bernd
P.S.: Due to technical problem of the provider epost.de of my
mailpointer I am still not subscribed to the list. So, please cc
answers to Bernd.Rinn at uni-konstanz.de.
--
Bernd Rinn
Fakultät für Physik
Universität Konstanz
Tel. 07531/88-3812,
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
-------------- next part --------------
#! /usr/bin/python
# author: Bernd Rinn, 2001
import cPickle, comm, socket, socketFile, uthread
PORT = 50000
def handle(req, addr, conns, timeout):
print "handle()"
while 1:
f = socketFile.socketFile(req,
socketFile.readMode,
timeout=timeout)
argument = cPickle.load(f)
if not argument: break
print "received:", argument
f = socketFile.socketFile(req, socketFile.writeMode,
timeout=timeout)
cPickle.dump(conns, f)
f.send()
conns.remove(addr)
print "conns=", conns
def serverloop(sock):
conns = []
while 1:
print "serverloop()"
(req, addr) = comm.accept(sock, timeout=None)
conns.append(addr)
uthread.new(handle, req, addr, conns, 10)
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(('', PORT))
sock.listen(5)
uthread.new(serverloop, sock)
uthread.run()
-------------- next part --------------
#! /usr/bin/python
# author: Bernd Rinn, 2001
import socket, select, comm, socketFile, cPickle
PORT = 50000
# uthread.wait() does not work in non-threaded programs
comm.nbselect = select.select
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('', PORT))
count = 0
while count < 100:
count += 1
f = socketFile.socketFile(s, socketFile.writeMode,
timeout=10)
cPickle.dump((count,2*count), f)
f.send()
#s.send(str(count))
f = socketFile.socketFile(s, socketFile.readMode)
print cPickle.load(f)
f = socketFile.socketFile(s, socketFile.writeMode,
timeout=10)
cPickle.dump(None, f)
f.send()
-------------- next part --------------
# author: Bernd Rinn, 2001
# python services
import socket
# Network timeout
class CommunicationTimeOut(Exception): pass
def nbselect(iwtd, owtd, ewtd, timeout=None):
"Non-blocking select()."
from select import select
from time import time
from uthread import wait
(r, w, e) = select(iwtd, owtd, ewtd, 0)
if r or w or e or timeout == 0: return (r, w, e)
# No timeout
if timeout == None:
timeout = 2.0**31-1 # symbolic for 'end of epoch'
endtime = time() + timeout
delay = 0.000001 # 1 usec
while 1:
(r, w, e) = select(iwtd, owtd, ewtd, 0)
if r or w or e or time() >= endtime: break
wait(delay)
if delay < 0.5: delay *= 2.0
return (r, w, e)
def accept(socket, timeout=10):
ready = nbselect([socket], [], [], timeout)
if ready[0] == []:
raise CommunicationTimeOut, (socket.getpeername()[0],
socket.getsockname()[1])
return socket.accept()
def connect(socket, address, timeout=10):
ready = nbselect([], [socket], [], timeout)
if ready[1] == []:
raise CommunicationTimeOut, (socket.getpeername()[0],
socket.getsockname()[1])
return socket.connect(address)
def send(socket, string, flags=0, timeout=10):
ready = nbselect([], [socket], [], timeout)
if ready[1] == []:
raise CommunicationTimeOut, (socket.getpeername()[0],
socket.getsockname()[1])
return socket.send(string, flags)
def recv(socket, bufsize, flags=0, timeout=10):
ready = nbselect([socket], [], [], timeout)
if ready[0] == []:
raise CommunicationTimeOut, (socket.getpeername()[0],
socket.getsockname()[1])
return socket.recv(bufsize, flags)
-------------- next part --------------
# author: Bernd Rinn, 2001
import string, comm
class CommunicationError(Exception): pass
readMode = 0
writeMode = 1
class socketFile:
def __init__(self, sock, mode, init_buffer="", timeout=10):
self.socket = sock
self.buffer = init_buffer
self.mode = mode
self.timeout = timeout
if mode == readMode: self.get()
def write(self, s):
self.buffer = self.buffer + s
def send(self):
comm.send(self.socket, str(len(self.buffer)) + '\0',
timeout=self.timeout)
comm.send(self.socket, self.buffer,
timeout=self.timeout)
def get(self):
length = 0
if self.buffer:
pos = string.find(self.buffer, '\0')
if pos >= 0:
length = int(self.buffer[:pos])
if length == 0:
self.buffer = self.buffer +\
comm.recv(self.socket, 1024, timeout=self.timeout)
pos = string.find(self.buffer, '\0')
if pos >= 0:
length = int(self.buffer[:pos])
else:
raise CommunicationError, "no length specification"
self.buffer = self.buffer[pos+1:]
while len(self.buffer) < length:
self.buffer = self.buffer +\
comm.recv(self.socket, 1024, timeout=self.timeout)
def read(self, i):
val = self.buffer[:i]
self.buffer = self.buffer[i:]
return val
def readline(self):
i = string.find(self.buffer, '\n')
val = self.buffer[:i+1]
self.buffer = self.buffer[i+1:]
return val
More information about the Stackless
mailing list