From 752b7d84e7227b92e0e4e39240b705fb919b224f Mon Sep 17 00:00:00 2001 From: jgoerzen Date: Mon, 6 Jan 2003 12:07:16 +0100 Subject: [PATCH] /offlineimap/head: changeset 310 Added some temporary debug code to help weed out a few race conditions with the curses Blinkenlights interface. Think I've finally got it. I'm leaving the debugging code in for now, though, to help in case there are future problems. --- .../head/offlineimap/ui/Blinkenlights.py | 12 ++++-- offlineimap/head/offlineimap/ui/Curses.py | 10 +++-- offlineimap/head/offlineimap/ui/debuglock.py | 43 +++++++++++++++++++ 3 files changed, 57 insertions(+), 8 deletions(-) create mode 100644 offlineimap/head/offlineimap/ui/debuglock.py diff --git a/offlineimap/head/offlineimap/ui/Blinkenlights.py b/offlineimap/head/offlineimap/ui/Blinkenlights.py index 4f9b376..b87cacc 100644 --- a/offlineimap/head/offlineimap/ui/Blinkenlights.py +++ b/offlineimap/head/offlineimap/ui/Blinkenlights.py @@ -20,6 +20,8 @@ from threading import * from offlineimap.ui.UIBase import UIBase import thread +from debuglock import DebuggingLock + class BlinkenBase: """This is a mix-in class that should be mixed in with either UIBase or another appropriate base class. The Tk interface, for instance, @@ -73,7 +75,7 @@ class BlinkenBase: def init_banner(s): s.availablethreadframes = {} s.threadframes = {} - s.tflock = Lock() + s.tflock = DebuggingLock('tflock') def threadExited(s, thread): threadid = thread.threadid @@ -93,8 +95,9 @@ class BlinkenBase: def gettf(s, lock = 1): threadid = thread.get_ident() accountname = s.getthreadaccount() - - s.tflock.acquire() + + if lock: + s.tflock.acquire() try: if not accountname in s.threadframes: @@ -115,6 +118,7 @@ class BlinkenBase: return tf finally: - s.tflock.release() + if lock: + s.tflock.release() diff --git a/offlineimap/head/offlineimap/ui/Curses.py b/offlineimap/head/offlineimap/ui/Curses.py index 28d6aa1..c51b321 100644 --- a/offlineimap/head/offlineimap/ui/Curses.py +++ b/offlineimap/head/offlineimap/ui/Curses.py @@ -22,6 +22,7 @@ from threading import * from offlineimap import version, threadutil import curses, curses.panel, curses.textpad, curses.wrapper +from debuglock import DebuggingLock class CursesUtil: def __init__(self): @@ -138,6 +139,7 @@ class CursesThreadFrame: self.iolock.acquire() try: self.window.addstr(self.y, self.x, '.', self.color) + self.c.stdscr.move(self.c.height - 1, self.c.width - 1) self.window.refresh() finally: if lock: @@ -163,9 +165,9 @@ class InputHandler: def __init__(s, util): s.c = util s.bgchar = None - s.inputlock = Lock() + s.inputlock = DebuggingLock('inputlock') s.lockheld = 0 - s.statuslock = Lock() + s.statuslock = DebuggingLock('statuslock') s.startup = Event() s.startthread() @@ -232,9 +234,9 @@ class InputHandler: class Blinkenlights(BlinkenBase, UIBase): def init_banner(s): - s.iolock = Lock() + s.iolock = DebuggingLock('iolock') s.af = {} - s.aflock = Lock() + s.aflock = DebuggingLock('aflock') s.c = CursesUtil() s.text = [] BlinkenBase.init_banner(s) diff --git a/offlineimap/head/offlineimap/ui/debuglock.py b/offlineimap/head/offlineimap/ui/debuglock.py new file mode 100644 index 0000000..b884414 --- /dev/null +++ b/offlineimap/head/offlineimap/ui/debuglock.py @@ -0,0 +1,43 @@ +# Locking debugging code -- temporary +# Copyright (C) 2003 John Goerzen +# +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +from threading import * +import traceback +logfile = open("/tmp/logfile", "wt") + +class DebuggingLock: + def __init__(self, name): + self.lock = Lock() + self.name = name + + def acquire(self, blocking = 1): + self.print_tb("Acquire lock") + self.lock.acquire(blocking) + logfile.write("===== %s: Thread %s acquired lock\n" % (self.name, currentThread().getName())) + + def release(self): + self.print_tb("Release lock") + self.lock.release() + + def print_tb(self, msg): + logfile.write("==== %s: Thread %s attempting to %s\n" % \ + (self.name, currentThread().getName(), msg)) + logfile.write("\n".join(traceback.format_list(traceback.extract_stack()))) + logfile.write("\n") + logfile.flush() +