Commit b95b6dc5 by rfkelly0

fs.expose.fuse: threadsafe file-handle generation

parent 6bd0201e
...@@ -52,7 +52,7 @@ import stat as statinfo ...@@ -52,7 +52,7 @@ import stat as statinfo
import subprocess import subprocess
import pickle import pickle
from fs.base import flags_to_mode from fs.base import flags_to_mode, threading
from fs.errors import * from fs.errors import *
from fs.path import * from fs.path import *
from fs.xattrs import ensure_xattrs from fs.xattrs import ensure_xattrs
...@@ -71,6 +71,7 @@ fuse_get_context = fuse.fuse_get_context ...@@ -71,6 +71,7 @@ fuse_get_context = fuse.fuse_get_context
STARTUP_TIME = time.time() STARTUP_TIME = time.time()
NATIVE_ENCODING = sys.getfilesystemencoding() NATIVE_ENCODING = sys.getfilesystemencoding()
def handle_fs_errors(func): def handle_fs_errors(func):
"""Method decorator to report FS errors in the appropriate way. """Method decorator to report FS errors in the appropriate way.
...@@ -126,9 +127,11 @@ class FSOperations(Operations): ...@@ -126,9 +127,11 @@ class FSOperations(Operations):
def __init__(self,fs,on_init=None,on_destroy=None): def __init__(self,fs,on_init=None,on_destroy=None):
self.fs = ensure_xattrs(fs) self.fs = ensure_xattrs(fs)
self._fhmap = {}
self._on_init = on_init self._on_init = on_init
self._on_destroy = on_destroy self._on_destroy = on_destroy
self._fhmap = {}
self._fh_lock = threading.Lock()
self._fh_next = 1
def _get_file(self,fh): def _get_file(self,fh):
try: try:
...@@ -137,12 +140,14 @@ class FSOperations(Operations): ...@@ -137,12 +140,14 @@ class FSOperations(Operations):
raise FSError("invalid file handle") raise FSError("invalid file handle")
def _reg_file(self,f): def _reg_file(self,f):
# TODO: a better handle-generation routine self._fh_lock.acquire()
fh = int(time.time()*1000) try:
self._fhmap.setdefault(fh,f) fh = self._fh_next
if self._fhmap[fh] is not f: self._fh_next += 1
return self._reg_file(f) self._fhmap[fh] = f
return fh return fh
finally:
self._fh_lock.release()
def init(self,conn): def init(self,conn):
if self._on_init: if self._on_init:
...@@ -179,6 +184,7 @@ class FSOperations(Operations): ...@@ -179,6 +184,7 @@ class FSOperations(Operations):
try: try:
value = self.fs.getxattr(path,name) value = self.fs.getxattr(path,name)
except AttributeError: except AttributeError:
# TODO: raise ENODATA, avoid the need for ensure_xattrs
raise UnsupportedError("getxattr") raise UnsupportedError("getxattr")
else: else:
if value is None: if value is None:
...@@ -274,7 +280,7 @@ class FSOperations(Operations): ...@@ -274,7 +280,7 @@ class FSOperations(Operations):
else: else:
f = self._get_file(fh) f = self._get_file(fh)
if not hasattr(f,"truncate"): if not hasattr(f,"truncate"):
raise UnsupportedError("trunace") raise UnsupportedError("truncate")
f.truncate(length) f.truncate(length)
@handle_fs_errors @handle_fs_errors
......
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