Changeset ca21a37af375…
Parent 33753d10447f…
by
Changes to 2 files · Browse files at ca21a37af375 Showing diff from parent 33753d10447f Diff from another changeset...
@@ -9,7 +9,7 @@ import pango
import Queue
import re
-import threading
+import threading, thread2
import time
from mercurial import hg, ui, util, revlog
from hglib import hgcmd_toq
@@ -36,8 +36,11 @@ pass
def get_tbbuttons(self):
- return [ self.make_toolbutton(gtk.STOCK_FIND, 'New Search',
- self._search_clicked, tip='Open new search tab')
+ return [
+ self.make_toolbutton(gtk.STOCK_FIND, 'New Search',
+ self._search_clicked, tip='Open new search tab'),
+ self.make_toolbutton(gtk.STOCK_STOP, 'Stop Search',
+ self._stop_search, tip='Stop search on current tab')
]
def prepare_display(self):
@@ -264,8 +267,9 @@ for x in excs:
if x: args.extend(['-X', x])
args.append(re)
- thread = threading.Thread(target=hgcmd_toq, args=args)
+ thread = thread2.Thread(target=hgcmd_toq, args=args)
thread.start()
+ frame._mythread = thread
model.clear()
search_hbox.set_sensitive(False)
@@ -282,9 +286,9 @@ self.notebook.set_tab_label(frame, hbox)
gobject.timeout_add(50, self.grep_wait, thread, q, model,
- search_hbox, regexp)
+ search_hbox, regexp, frame)
- def grep_wait(self, thread, q, model, search_hbox, regexp):
+ def grep_wait(self, thread, q, model, search_hbox, regexp, frame):
"""
Handle all the messages currently in the queue (if any).
"""
@@ -299,6 +303,7 @@ if thread.isAlive():
return True
else:
+ frame._mythread = None
search_hbox.set_sensitive(True)
regexp.grab_focus()
self.stbar.end()
@@ -316,6 +321,14 @@ self.curpath = model[iter][self.COL_PATH]
self.stbar.set_status_text(model[iter][self.COL_TOOLTIP])
+ def _stop_search(self, button, widget):
+ num = self.notebook.get_current_page()
+ frame = self.notebook.get_nth_page(num)
+ if hasattr(frame, '_mythread') and frame._mythread:
+ frame._mythread.terminate()
+ frame._mythread.join()
+ frame._mythread = None
+
def close_page(self, button, widget):
'''Close page button has been pressed'''
num = self.notebook.page_num(widget)
|
|
@@ -0,0 +1,49 @@ + # Interuptible threads
+#
+# http://sebulba.wikispaces.com/recipe+thread2
+
+import threading
+import inspect
+import ctypes
+
+
+def _async_raise(tid, exctype):
+ """raises the exception, performs cleanup if needed"""
+ if not inspect.isclass(exctype):
+ raise TypeError("Only types can be raised (not instances)")
+ res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype))
+ if res == 0:
+ raise ValueError("invalid thread id")
+ elif res != 1:
+ # """if it returns a number greater than one, you're in trouble,
+ # and you should call it again with exc=NULL to revert the effect"""
+ ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0)
+ raise SystemError("PyThreadState_SetAsyncExc failed")
+
+
+class Thread(threading.Thread):
+ def _get_my_tid(self):
+ """determines this (self's) thread id"""
+ if not self.isAlive():
+ raise threading.ThreadError("the thread is not active")
+
+ # do we have it cached?
+ if hasattr(self, "_thread_id"):
+ return self._thread_id
+
+ # no, look for it in the _active dict
+ for tid, tobj in threading._active.items():
+ if tobj is self:
+ self._thread_id = tid
+ return tid
+
+ raise AssertionError("could not determine the thread's id")
+
+ def raise_exc(self, exctype):
+ """raises the given exception type in the context of this thread"""
+ _async_raise(self._get_my_tid(), exctype)
+
+ def terminate(self):
+ """raises SystemExit in the context of the given thread, which should
+ cause the thread to exit silently (unless caught)"""
+ self.raise_exc(SystemExit)
|
Loading...