[hackers] [wmii] [python] Fix some deadlock issues. || Kris Maglione

From: <hg_AT_suckless.org>
Date: Fri, 2 Jul 2010 01:45:35 +0000 (UTC)

changeset: 2753:f7e320c341e2
tag: tip
user: Kris Maglione <kris_AT_suckless.org>
date: Thu Jul 01 21:45:27 2010 -0400
files: alternative_wmiircs/python/pygmi/event.py alternative_wmiircs/python/pygmi/fs.py alternative_wmiircs/python/pygmi/monitor.py alternative_wmiircs/python/pyxp/mux.py
description:
[python] Fix some deadlock issues.

diff -r bce3b2614bd5 -r f7e320c341e2 alternative_wmiircs/python/pygmi/event.py
--- a/alternative_wmiircs/python/pygmi/event.py Wed Jun 30 23:12:41 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/event.py Thu Jul 01 21:45:27 2010 -0400
@@ -164,7 +164,7 @@
         """
         self.modes = {}
         self.modelist = []
- self._set_mode('main', False)
+ self.mode = 'main'
         self.defs = {}
         events.bind(Key=self.dispatch)
 
@@ -179,17 +179,18 @@
             }
             self.modelist.append(mode)
 
- def _set_mode(self, mode, execute=True):
+ mode = property(lambda self: self._mode,
+ doc="The current mode for which to dispatch keys")
+ @mode.setter
+ def mode(self, mode):
         self._add_mode(mode)
         self._mode = mode
         self._keys = dict((k % self.defs, v) for k, v in
                           self.modes[mode]['keys'].items() +
                           self.modes[mode]['import'].items());
- if execute:
+ if hasattr(self, 'defs'):
             client.write('/keys', '\n'.join(self._keys.keys()) + '\n')
 
- mode = property(lambda self: self._mode, _set_mode,
- doc="The current mode for which to dispatch keys")
 
     @prop(doc="Returns a short help text describing the bound keys in all modes")
     def help(self):
diff -r bce3b2614bd5 -r f7e320c341e2 alternative_wmiircs/python/pygmi/fs.py
--- a/alternative_wmiircs/python/pygmi/fs.py Wed Jun 30 23:12:41 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/fs.py Thu Jul 01 21:45:27 2010 -0400
@@ -11,6 +11,7 @@
            'Button', 'Colors', 'Color', 'Toggle', 'Always', 'Never')
 
 spacere = re.compile(r'\s')
+sentinel = {}
 
 class utf8(object):
     def __str__(self):
@@ -67,7 +68,6 @@
             tuples, each containing a decoder and encoder function for the
             property's plain text value.
     """
- sentinel = {}
     ctl_types = {}
     ctl_hasid = False
     ctl_open = 'aopen'
@@ -312,14 +312,14 @@
         self.get = get
         self.attr = str(self)
     def __get__(self, area, cls):
- if getattr(area, self.attr, None) is not None:
+ if getattr(area, self.attr, sentinel) is not sentinel:
             return getattr(area, self.attr)
         return self.get(area)
     def __set__(self, area, val):
         setattr(area, self.attr, val)
 
 class Area(object):
- def __init__(self, tag, ord, screen='sel', offset=None, width=None, height=None, frames=None):
+ def __init__(self, tag, ord, screen='sel', offset=sentinel, width=sentinel, height=sentinel, frames=sentinel):
         self.tag = tag
         if ':' in str(ord):
             screen, ord = ord.split(':', 2)
@@ -344,17 +344,20 @@
 
     @property
     def spec(self):
- return '%s:%s' % (self.screen, self.ord)
+ if self.screen is not None:
+ return '%s:%s' % (self.screen, self.ord)
+ return self.ord
 
- def _get_mode(self):
+ @property
+ def mode(self):
         for k, v in self.tag.iteritems():
             if k == 'colmode':
                 v = v.split(' ')
                 if v[0] == self.ord:
                     return v[1]
- mode = property(
- _get_mode,
- lambda self, val: self.tag.set('colmode %s' % self.spec, val))
+ @mode.setter
+ def mode(self, val):
+ self.tag['colmode %s' % self.spec] = val
 
     def grow(self, dir, amount=None):
         self.tag.grow(self, dir, amount)
@@ -364,7 +367,7 @@
 class Frame(object):
     live = False
 
- def __init__(self, client, area=None, ord=None, offset=None, height=None):
+ def __init__(self, client, area=sentinel, ord=sentinel, offset=sentinel, height=sentinel):
         self.client = client
         self.ord = ord
         self.offset = offset
@@ -414,21 +417,24 @@
             dir = ' '.join(dir)
         return dir
 
- def _set_selected(self, frame):
+ @property
+ def selected(self):
+ return tuple(self['select'].split(' '))
+ @selected.setter
+ def selected(self, frame):
         if not isinstance(frame, basestring) or ' ' not in frame:
             frame = self.framespec(frame)
         self['select'] = frame
- selected = property(lambda self: tuple(self['select'].split(' ')),
- _set_selected)
 
- def _get_selclient(self):
+ @property
+ def selclient(self):
         for k, v in self.iteritems():
             if k == 'select' and 'client' in v:
                 return Client(v.split(' ')[1])
         return None
- selclient = property(_get_selclient,
- lambda self, val: self.set('select',
- self.framespec(val)))
+ @selclient.setter
+ def selclient(self, val):
+ self['select'] = self.framespec(val)
 
     @property
     def selcol(self):
@@ -437,9 +443,9 @@
     @property
     def index(self):
         areas = []
- for l in [l.split(' ')
+ for l in (l.split(' ')
                   for l in client.readlines('%s/index' % self.path)
- if l]:
+ if l):
             if l[0] == '#':
                 m = re.match(r'(?:(\d+):)?(\d+|~)', l[1])
                 if m.group(2) == '~':
@@ -447,7 +453,7 @@
                                 height=l[3], frames=[])
                 else:
                     area = Area(tag=self, screen=m.group(1) or 0,
- ord=m.group(2), offset=l[2], width=l[3],
+ height=None, ord=m.group(2), offset=l[2], width=l[3],
                                 frames=[])
                 areas.append(area)
                 i = 0
@@ -797,12 +803,12 @@
         self.tags[tag].button.label = urgent and '*' + tag or tag
 
     def next(self, reverse=False):
- tags = [t for t in wmii.tags if t.id not in self.ignore]
+ tags = [t for t in wmii.tags if t not in self.ignore]
         tags.append(tags[0])
         if reverse:
             tags.reverse()
         for i in range(0, len(tags)):
- if tags[i] == self.sel:
+ if tags[i] == self.sel.id:
                 return tags[i+1]
         return self.sel
 
diff -r bce3b2614bd5 -r f7e320c341e2 alternative_wmiircs/python/pygmi/monitor.py
--- a/alternative_wmiircs/python/pygmi/monitor.py Wed Jun 30 23:12:41 2010 -0400
+++ b/alternative_wmiircs/python/pygmi/monitor.py Thu Jul 01 21:45:27 2010 -0400
@@ -107,7 +107,12 @@
             return None
 
     _active = True
- def _set_active(self, val):
+ @property
+ def active(self):
+ return self._active
+
+ @active.setter
+ def active(self, val):
         with self.lock:
             self._active = bool(val)
         if val:
@@ -115,8 +120,4 @@
         else:
             self.button.remove()
 
- active = property(
- lambda self: self._active,
- _set_active)
-
 # vim:se sts=4 sw=4 et:
diff -r bce3b2614bd5 -r f7e320c341e2 alternative_wmiircs/python/pyxp/mux.py
--- a/alternative_wmiircs/python/pyxp/mux.py Wed Jun 30 23:12:41 2010 -0400
+++ b/alternative_wmiircs/python/pyxp/mux.py Thu Jul 01 21:45:27 2010 -0400
@@ -39,6 +39,9 @@
         self.maxtag = maxtag
         self.muxer = None
 
+ self.async_mux = Queue(self.mux)
+ self.async_dispatch = Queue(self.async_dispatch)
+
         if isinstance(con, basestring):
             con = dial(con)
         self.fd = con
@@ -48,8 +51,8 @@
 
     def mux(self, rpc):
         try:
+ self.lock.acquire()
             rpc.waiting = True
- self.lock.acquire()
             while self.muxer and self.muxer != rpc and rpc.data is None:
                 rpc.wait()
 
@@ -69,7 +72,7 @@
                     self.lock.acquire()
                     self.electmuxer()
         except Exception, e:
- traceback.print_exc(sys.stdout)
+ traceback.print_exc(sys.stderr)
             if self.flush:
                 self.flush(self, rpc.data)
             raise e
@@ -77,36 +80,26 @@
             if self.lock._is_owned():
                 self.lock.release()
 
- if rpc.async:
- if callable(rpc.async):
- rpc.async(self, rpc.data)
- else:
- return rpc.data
+ return rpc.data
 
     def rpc(self, dat, async=None):
         rpc = self.newrpc(dat, async)
         if async:
- with self.lock:
- if self.muxer is None:
- self.electmuxer()
+ self.async_mux.push(rpc)
         else:
             return self.mux(rpc)
 
+ def async_dispatch(self, rpc):
+ self.async_mux.pop(rpc)
+ rpc.async(self, rpc.data)
+
     def electmuxer(self):
- async = None
         for rpc in self.queue:
- if self.muxer != rpc:
- if rpc.async:
- async = rpc
- else:
- self.muxer = rpc
- rpc.notify()
- return
+ if self.muxer != rpc and rpc.waiting:
+ self.muxer = rpc
+ rpc.notify()
+ return
         self.muxer = None
- if async:
- self.muxer = async
- t = Thread(target=self.mux, args=(async,))
- t.start()
 
     def dispatch(self, dat):
         tag = dat.tag
@@ -156,8 +149,7 @@
                     data += self.fd.recv(len - 4)
                     return self.process(data)
         except Exception, e:
- traceback.print_exc(sys.stdout)
- print repr(data)
+ traceback.print_exc(sys.stderr)
             return None
 
     def newrpc(self, dat, async=None):
@@ -181,14 +173,50 @@
         self.mux = mux
         self.orig = data
         self.data = None
+ self.async = async
         self.waiting = False
- self.async = async
 
     def dispatch(self, data=None):
         self.data = data
- if not self.async or self.waiting:
- self.notify()
- elif callable(self.async):
- Thread(target=self.async, args=(self.mux, data)).start()
+ self.notify()
+ if callable(self.async):
+ self.mux.async_dispatch(self)
+
+class Queue(Thread):
+ def __init__(self, op):
+ super(Queue, self).__init__()
+ self.cond = Condition()
+ self.op = op
+ self.queue = []
+ self.daemon = True
+
+ def __call__(self, item):
+ return self.push(item)
+
+ def push(self, item):
+ with self.cond:
+ self.queue.append(item)
+ if not self.is_alive():
+ self.start()
+ self.cond.notify()
+ def pop(self, item):
+ with self.cond:
+ if item in self.queue:
+ self.queue.remove(item)
+ return True
+ return False
+
+ def run(self):
+ self.cond.acquire()
+ while True:
+ while self.queue:
+ item = self.queue.pop(0)
+ self.cond.release()
+ try:
+ self.op(item)
+ except Exception, e:
+ traceback.print_exc(sys.stderr)
+ self.cond.acquire()
+ self.cond.wait()
 
 # vim:se sts=4 sw=4 et:
Received on Fri Jul 02 2010 - 03:45:35 CEST

This archive was generated by hypermail 2.2.0 : Fri Jul 02 2010 - 03:48:04 CEST