summaryrefslogtreecommitdiff
path: root/fs/osfs
diff options
context:
space:
mode:
authorrfkelly0 <rfkelly0@67cdc799-7952-0410-af00-57a81ceafa0f>2010-09-28 10:48:45 +0000
committerrfkelly0 <rfkelly0@67cdc799-7952-0410-af00-57a81ceafa0f>2010-09-28 10:48:45 +0000
commit8fd6524cfc64f27e3e5c9edfe991ee233dd5f88f (patch)
treeadab838da31241e449b12020259181e573d7c4c8 /fs/osfs
parent29734163705a0703650744425217e2a9392ba9c0 (diff)
downloadpyfilesystem-8fd6524cfc64f27e3e5c9edfe991ee233dd5f88f.tar.gz
watch_win32: use weakrefs to avoid immortal reference cycles
git-svn-id: http://pyfilesystem.googlecode.com/svn/trunk@454 67cdc799-7952-0410-af00-57a81ceafa0f
Diffstat (limited to 'fs/osfs')
-rw-r--r--fs/osfs/watch_win32.py35
1 files changed, 27 insertions, 8 deletions
diff --git a/fs/osfs/watch_win32.py b/fs/osfs/watch_win32.py
index 8e6b4d9..0bf1491 100644
--- a/fs/osfs/watch_win32.py
+++ b/fs/osfs/watch_win32.py
@@ -16,6 +16,7 @@ import struct
import ctypes
import ctypes.wintypes
import traceback
+import weakref
try:
LPVOID = ctypes.wintypes.LPVOID
@@ -192,6 +193,7 @@ class WatchedDirectory(object):
self.callback = callback
self.recursive = recursive
self.handle = None
+ self.error = None
self.handle = CreateFileW(path,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE,
@@ -219,9 +221,14 @@ class WatchedDirectory(object):
overlapped.OffsetHigh = 0
overlapped.Pointer = 0
overlapped.hEvent = 0
- ReadDirectoryChangesW(self.handle,
- ctypes.byref(self.result),len(self.result),
- self.recursive,self.flags,None,overlapped,None)
+ try:
+ ReadDirectoryChangesW(self.handle,
+ ctypes.byref(self.result),len(self.result),
+ self.recursive,self.flags,None,
+ overlapped,None)
+ except WindowsError, e:
+ self.error = e
+ self.close()
def complete(self,nbytes):
if nbytes == 0:
@@ -370,8 +377,11 @@ class WatchThread(threading.Thread):
try:
while True:
w = self._new_watches.get_nowait()
- CreateIoCompletionPort(w.handle,self._iocp,hash(w),0)
- w.post()
+ if w.handle is not None:
+ CreateIoCompletionPort(w.handle,
+ self._iocp,
+ hash(w),0)
+ w.post()
w.ready.set()
except Queue.Empty:
pass
@@ -405,17 +415,26 @@ class OSFSWatchMixin(WatchableFSMixin):
w = super(OSFSWatchMixin,self).add_watcher(callback,path,events,recursive)
syspath = self.getsyspath(path)
wt = self.__get_watch_thread()
+ # Careful not to create a reference cycle here.
+ weak_self = weakref.ref(self)
def handle_event(event_class,path,*args,**kwds):
+ selfref = weak_self()
+ if selfref is None:
+ return
try:
- path = self.unsyspath(path)
+ path = selfref.unsyspath(path)
except ValueError:
pass
else:
if event_class in (MOVED_SRC,MOVED_DST) and args and args[0]:
- args = (self.unsyspath(args[0]),) + args[1:]
- event = event_class(self,path,*args,**kwds)
+ args = (selfref.unsyspath(args[0]),) + args[1:]
+ event = event_class(selfref,path,*args,**kwds)
w.handle_event(event)
w._watch_objs = wt.add_watcher(handle_event,syspath,w.events,w.recursive)
+ for wd in w._watch_objs:
+ if wd.error is not None:
+ self.del_watcher(w)
+ raise wd.error
return w
@convert_os_errors