Commit 17c1950d by rfkelly0

first (very hacky) attempt to prevent timeouts in dokan

parent 77bf5f23
...@@ -160,6 +160,7 @@ def handle_fs_errors(func): ...@@ -160,6 +160,7 @@ def handle_fs_errors(func):
_debug("ERR",name,e) _debug("ERR",name,e)
raise raise
else: else:
_debug("OK",name)
if res is None: if res is None:
res = 0 res = 0
if res != 0: if res != 0:
...@@ -301,6 +302,12 @@ class FSOperations(object): ...@@ -301,6 +302,12 @@ class FSOperations(object):
return return
# Try to open the requested file. It may actually be a directory. # Try to open the requested file. It may actually be a directory.
info.contents.Context = 1 info.contents.Context = 1
finished = threading.Event()
def reset_timeout_callback():
while not finished.isSet():
libdokan.DokanResetTimeout(5*60*1000,info)
finished.wait(timeout=4*60)
threading.Thread(target=reset_timeout_callback).start()
try: try:
f = self.fs.open(path,mode) f = self.fs.open(path,mode)
except ResourceInvalidError: except ResourceInvalidError:
...@@ -314,6 +321,8 @@ class FSOperations(object): ...@@ -314,6 +321,8 @@ class FSOperations(object):
raise raise
else: else:
info.contents.Context = self._reg_file(f,path) info.contents.Context = self._reg_file(f,path)
finally:
finished.set()
return retcode return retcode
@handle_fs_errors @handle_fs_errors
...@@ -345,6 +354,12 @@ class FSOperations(object): ...@@ -345,6 +354,12 @@ class FSOperations(object):
self._pending_delete.remove(path) self._pending_delete.remove(path)
else: else:
(file,_,lock) = self._get_file(info.contents.Context) (file,_,lock) = self._get_file(info.contents.Context)
finished = threading.Event()
def reset_timeout_callback():
while not finished.isSet():
libdokan.DokanResetTimeout(5*60*1000,info)
finished.wait(timeout=4*60)
threading.Thread(target=reset_timeout_callback).start()
lock.acquire() lock.acquire()
try: try:
if info.contents.DeleteOnClose: if info.contents.DeleteOnClose:
...@@ -356,17 +371,25 @@ class FSOperations(object): ...@@ -356,17 +371,25 @@ class FSOperations(object):
else: else:
file.flush() file.flush()
finally: finally:
finished.set()
lock.release() lock.release()
@handle_fs_errors @handle_fs_errors
def CloseFile(self, path, info): def CloseFile(self, path, info):
if info.contents.Context >= MIN_FH: if info.contents.Context >= MIN_FH:
(file,_,lock) = self._get_file(info.contents.Context) (file,_,lock) = self._get_file(info.contents.Context)
finished = threading.Event()
def reset_timeout_callback():
while not finished.isSet():
libdokan.DokanResetTimeout(5*60*1000,info)
finished.wait(timeout=4*60)
threading.Thread(target=reset_timeout_callback).start()
lock.acquire() lock.acquire()
try: try:
file.close() file.close()
self._del_file(info.contents.Context) self._del_file(info.contents.Context)
finally: finally:
finished.set()
lock.release() lock.release()
info.contents.Context = 0 info.contents.Context = 0
...@@ -398,8 +421,14 @@ class FSOperations(object): ...@@ -398,8 +421,14 @@ class FSOperations(object):
ctypes.memmove(data,buffer,nBytesToWrite) ctypes.memmove(data,buffer,nBytesToWrite)
file.write(data.raw) file.write(data.raw)
nBytesWritten[0] = len(data.raw) nBytesWritten[0] = len(data.raw)
if offset + nBytesWritten[0] > self._files_size_written[path][fh]: try:
self._files_size_written[path][fh] = offset + nBytesWritten[0] size_written = self._files_size_written[path][fh]
except KeyError:
pass
else:
if offset + nBytesWritten[0] > size_written:
new_size_written = offset + nBytesWritten[0]
self._files_size_written[path][fh] = new_size_written
finally: finally:
lock.release() lock.release()
...@@ -509,6 +538,12 @@ class FSOperations(object): ...@@ -509,6 +538,12 @@ class FSOperations(object):
def SetEndOfFile(self, path, length, info): def SetEndOfFile(self, path, length, info):
path = normpath(path) path = normpath(path)
(file,_,lock) = self._get_file(info.contents.Context) (file,_,lock) = self._get_file(info.contents.Context)
finished = threading.Event()
def reset_timeout_callback():
while not finished.isSet():
libdokan.DokanResetTimeout(5*60*1000,info)
finished.wait(timeout=4*60)
threading.Thread(target=reset_timeout_callback).start()
lock.acquire() lock.acquire()
try: try:
pos = file.tell() pos = file.tell()
...@@ -518,6 +553,7 @@ class FSOperations(object): ...@@ -518,6 +553,7 @@ class FSOperations(object):
if pos < length: if pos < length:
file.seek(min(pos,length)) file.seek(min(pos,length))
finally: finally:
finished.set()
lock.release() lock.release()
@handle_fs_errors @handle_fs_errors
......
...@@ -239,6 +239,8 @@ DokanDriverVersion.argtypes = ( ...@@ -239,6 +239,8 @@ DokanDriverVersion.argtypes = (
DokanResetTimeout = windll.Dokan.DokanResetTimeout DokanResetTimeout = windll.Dokan.DokanResetTimeout
DokanResetTimeout.restype = BOOL DokanResetTimeout.restype = BOOL
DokanResetTimeout.argtypes = ( DokanResetTimeout.argtypes = (
ULONG, #timeout
PDOKAN_FILE_INFO, # file info pointer
) )
...@@ -22,6 +22,7 @@ FS subclasses interfacing with a remote filesystem. These include: ...@@ -22,6 +22,7 @@ FS subclasses interfacing with a remote filesystem. These include:
""" """
import os import os
import sys
import time import time
import copy import copy
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment