[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