openbsd-ports/www/canto/patches/patch-canto_process_py
dcoppa bbd348b237 Fix a bug causing a crash on OpenBSD.
Problem reported by a user on the #canto irc channel.
Patch by Jack Miller <jack@codezen.org> (upstream developer)

OK landry@, jasper@
2011-03-13 09:36:24 +00:00

84 lines
2.4 KiB
Plaintext

$OpenBSD: patch-canto_process_py,v 1.1 2011/03/13 09:36:24 dcoppa Exp $
Fix a crash reported by a user on the #canto irc channel.
Patch by Jack Miller <jack@codezen.org> (upstream developer)
http://codezen.org/cgi-bin/gitweb.cgi?p=canto.git;a=commit;h=e5a4b15b0ddcab49699ab2293d560966fd9af810
--- canto/process.py.orig Tue Jul 27 19:47:06 2010
+++ canto/process.py Fri Mar 11 10:53:43 2011
@@ -106,6 +106,7 @@ from threading import Thread, Lock
from cPickle import dumps, loads
import select
import signal
+import errno
import time
import sys
import os
@@ -122,17 +123,41 @@ class Queue():
self.thread = None
self.alive = True
+ self.frag = ""
+ def _try_parse(self):
+ if "\0" in self.frag:
+ idx = self.frag.index("\0")
+ s, self.frag = self.frag[:idx], self.frag[idx+1:]
+ return loads(s)
+ return None
+
def get(self, block=True, timeout=None):
+
+ # Parse a message out of the remaining fragment.
+ r = self._try_parse()
+ if r:
+ return r
+
ready = self.poll.poll(timeout)
- for fd, event in ready:
- l = os.read(self.recvpipe, 1)
- while l[-1] != " ":
- l += os.read(self.recvpipe, 1)
- l = int(l)
+ if not ready:
+ raise Exception
- s = os.read(self.recvpipe, l)
- return loads(s)
+ while True:
+ try:
+ self.frag += os.read(self.recvpipe, 1024)
+ r = self._try_parse()
+ if r:
+ return r
+ except OSError, e:
+ if e.errno == errno.EINTR:
+ continue
+ raise
+
+ if block and timeout == None:
+ continue
+ break
+
raise Exception
def feed_pipe(self):
@@ -145,9 +170,14 @@ class Queue():
self.objlist = self.objlist[1:]
self.objlock.release()
- s = dumps(obj)
- l = len(s)
- os.write(self.sendpipe, "%d %s" % (l, s))
+ s = dumps(obj) + "\0"
+ while s:
+ try:
+ written = os.write(self.sendpipe, s)
+ s = s[written:]
+ except OSError, e:
+ if e.errno != errno.EINTR:
+ raise
def put(self, obj):
if not self.thread: