diff --git a/index.js b/index.js index b04f991..3e71ec2 100644 --- a/index.js +++ b/index.js @@ -11,6 +11,8 @@ const binding = require('node-gyp-build')(__dirname) const IS_OSX = os.platform() === 'darwin' const OSX_FOLDER_ICON = '/System/Library/CoreServices/CoreTypes.bundle/Contents/Resources/GenericFolderIcon.icns' const HAS_FOLDER_ICON = IS_OSX && fs.existsSync(OSX_FOLDER_ICON) +const DEFAULT_TIMEOUT = 15 * 1000 +const TIMEOUT_ERRNO = IS_OSX ? -110 : -60 const ENOTCONN = IS_OSX ? -57 : -107 @@ -133,10 +135,12 @@ const OpcodesAndDefaults = new Map([ class Fuse extends Nanoresource { constructor (mnt, ops, opts = {}) { super() + this.opts = opts this.mnt = path.resolve(mnt) - this.ops = ops + this.timeout = opts.timeout || DEFAULT_TIMEOUT + this._force = !!opts.force this._thread = null this._handlers = this._makeHandlerArray() @@ -199,6 +203,7 @@ class Fuse extends Nanoresource { _makeHandlerArray () { const self = this const handlers = new Array(OpcodesAndDefaults.size) + const to = this.timeout || DEFAULT_TIMEOUT for (const [name, { op, defaults }] of OpcodesAndDefaults) { const nativeSignal = binding[`fuse_native_signal_${name}`] @@ -211,7 +216,7 @@ class Fuse extends Nanoresource { function makeHandler (name, op, defaults, nativeSignal) { return function (nativeHandler, opCode, ...args) { - const boundSignal = signal.bind(null, nativeHandler) + const boundSignal = autoTimeout(signal.bind(null, nativeHandler)) const funcName = `_op_${name}` if (!self[funcName] || !self._implemented.has(op)) return boundSignal(-1, ...defaults) return self[funcName].apply(self, [boundSignal, ...args]) @@ -226,6 +231,19 @@ class Fuse extends Nanoresource { return process.nextTick(nativeSignal, ...arr) } } + + function autoTimeout (cb) { + let called = false + const timeout = setTimeout(timeoutWrap, to, TIMEOUT_ERRNO) + return timeoutWrap + + function timeoutWrap (...args) { + if (called) return + called = true + clearTimeout(timeout) + cb(...args) + } + } } // Static methods diff --git a/test/read.js b/test/read.js index fe24e68..388eae1 100644 --- a/test/read.js +++ b/test/read.js @@ -93,6 +93,7 @@ tape.skip('read timeout does not force unmount', function (t) { } else if (path === '/timeout') { console.log('read is gonna time out') // Just let this one timeout + setTimeout(cb, 20 * 1000, -2) return } return cb(-2)