Revision 5aef65a9 deps/npm/node_modules/lockfile/lockfile.js
deps/npm/node_modules/lockfile/lockfile.js | ||
---|---|---|
8 | 8 |
|
9 | 9 |
var locks = {} |
10 | 10 |
|
11 |
function hasOwnProperty (obj, prop) { |
|
12 |
return Object.prototype.hasOwnProperty.call(obj, prop) |
|
13 |
} |
|
14 |
|
|
11 | 15 |
process.on('exit', function () { |
12 | 16 |
// cleanup |
13 | 17 |
Object.keys(locks).forEach(exports.unlockSync) |
... | ... | |
21 | 25 |
}) |
22 | 26 |
if (!l.length) { |
23 | 27 |
// cleanup |
24 |
Object.keys(locks).forEach(exports.unlockSync)
|
|
28 |
try { Object.keys(locks).forEach(exports.unlockSync) } catch (e) {}
|
|
25 | 29 |
process.removeListener('uncaughtException', H) |
26 | 30 |
throw er |
27 | 31 |
} |
... | ... | |
29 | 33 |
|
30 | 34 |
exports.unlock = function (path, cb) { |
31 | 35 |
// best-effort. unlocking an already-unlocked lock is a noop |
32 |
fs.unlink(path, function (unlinkEr) { |
|
33 |
if (!locks.hasOwnProperty(path)) return cb() |
|
34 |
fs.close(locks[path], function (closeEr) { |
|
35 |
delete locks[path] |
|
36 |
cb() |
|
37 |
}) |
|
38 |
}) |
|
36 |
if (hasOwnProperty(locks, path)) |
|
37 |
fs.close(locks[path], unlink) |
|
38 |
else |
|
39 |
unlink() |
|
40 |
|
|
41 |
function unlink () { |
|
42 |
delete locks[path] |
|
43 |
fs.unlink(path, function (unlinkEr) { cb() }) |
|
44 |
} |
|
39 | 45 |
} |
40 | 46 |
|
41 | 47 |
exports.unlockSync = function (path) { |
42 |
try { fs.unlinkSync(path) } catch (er) {} |
|
43 |
if (!locks.hasOwnProperty(path)) return |
|
44 | 48 |
// best-effort. unlocking an already-unlocked lock is a noop |
45 |
try { fs.close(locks[path]) } catch (er) {} |
|
49 |
try { fs.closeSync(locks[path]) } catch (er) {} |
|
50 |
try { fs.unlinkSync(path) } catch (er) {} |
|
46 | 51 |
delete locks[path] |
47 | 52 |
} |
48 | 53 |
|
... | ... | |
161 | 166 |
} |
162 | 167 |
|
163 | 168 |
function notStale (er, path, opts, cb) { |
164 |
if (typeof opts.wait === 'number' && opts.wait > 0) { |
|
165 |
// wait for some ms for the lock to clear |
|
166 |
var start = Date.now() |
|
167 |
|
|
168 |
var retried = false |
|
169 |
function retry () { |
|
170 |
if (retried) return |
|
171 |
retried = true |
|
172 |
// maybe already closed. |
|
173 |
try { watcher.close() } catch (e) {} |
|
174 |
clearTimeout(timer) |
|
175 |
var newWait = Date.now() - start |
|
176 |
var opts_ = Object.create(opts, { wait: { value: newWait }}) |
|
177 |
exports.lock(path, opts_, cb) |
|
178 |
} |
|
169 |
// if we can't wait, then just call it a failure |
|
170 |
if (typeof opts.wait !== 'number' || opts.wait <= 0) |
|
171 |
return cb(er) |
|
179 | 172 |
|
180 |
try { |
|
181 |
var watcher = fs.watch(path, function (change) { |
|
182 |
if (change === 'rename') { |
|
183 |
// ok, try and get it now. |
|
184 |
// if this fails, then continue waiting, maybe. |
|
185 |
retry() |
|
186 |
} |
|
187 |
}) |
|
188 |
watcher.on('error', function (er) { |
|
189 |
// usually means it expired before the watcher spotted it |
|
190 |
retry() |
|
191 |
}) |
|
192 |
} catch (er) { |
|
193 |
retry() |
|
194 |
} |
|
173 |
// console.error('wait', path, opts.wait) |
|
174 |
// wait for some ms for the lock to clear |
|
175 |
var start = Date.now() |
|
176 |
var end = start + opts.wait |
|
195 | 177 |
|
196 |
var timer = setTimeout(function () { |
|
197 |
try { watcher.close() } catch (e) {} |
|
198 |
cb(er) |
|
199 |
}, opts.wait) |
|
200 |
} else { |
|
201 |
// failed to lock! |
|
202 |
return cb(er) |
|
178 |
function retry () { |
|
179 |
var now = Date.now() |
|
180 |
var newWait = end - now |
|
181 |
var newOpts = Object.create(opts, { wait: { value: newWait }}) |
|
182 |
exports.lock(path, newOpts, cb) |
|
203 | 183 |
} |
184 |
|
|
185 |
var timer = setTimeout(retry, 10) |
|
204 | 186 |
} |
205 | 187 |
|
206 | 188 |
exports.lockSync = function (path, opts) { |
Also available in: Unified diff