/*! ReadWriteLock - v5.0.0 - 2015-01-16
 * Author: Alberto La Rocca <a71104@gmail.com> (https://github.com/71104)
 * Released under the MIT license
 * Copyright (c) 2015 Alberto La Rocca */
module.exports=function(){"use strict";function a(){this.readers=0,this.queue=[]}function b(b,c,f){var g;"function"!=typeof b?(e.hasOwnProperty(b)||(e[b]=new a),g=e[b]):(f=c,c=b,g=d),f||(f={});var h=null;f.hasOwnProperty("scope")&&(h=f.scope);var i=function(){var a=!1;return function(){a||(a=!0,g.readers--,g.queue.length&&g.queue[0]())}}();if(g.readers<0||g.queue.length){var j=!1;if(g.queue.push(function(){!j&&g.readers>=0&&(j=!0,g.queue.shift(),g.readers++,c.call(h,i),g.queue.length&&g.queue[0]())}),f.hasOwnProperty("timeout")){var k=null;f.hasOwnProperty("timeoutCallback")&&(k=f.timeoutCallback),setTimeout(function(){j||(j=!0,g.queue.shift(),k&&k.call(f.scope))},f.timeout)}}else g.readers++,c.call(f.scope,i)}function c(b,c,f){var g;"function"!=typeof b?(e.hasOwnProperty(b)||(e[b]=new a),g=e[b]):(f=c,c=b,g=d),f||(f={});var h=null;f.hasOwnProperty("scope")&&(h=f.scope);var i=function(){var a=!1;return function(){a||(a=!0,g.readers=0,g.queue.length&&g.queue[0]())}}();if(g.readers||g.queue.length){var j=!1;if(g.queue.push(function(){j||g.readers||(j=!0,g.queue.shift(),g.readers=-1,c.call(f.scope,i))}),f.hasOwnProperty("timeout")){var k=null;f.hasOwnProperty("timeoutCallback")&&(k=f.timeoutCallback),setTimeout(function(){j||(j=!0,g.queue.shift(),k&&k.call(h))},f.timeout)}}else g.readers=-1,c.call(f.scope,i)}var d=new a,e={};this.readLock=b,this.writeLock=c,this.async={readLock:function(a,c,d){"function"!=typeof a?b(a,function(a){c.call(this,null,a)},d):(c=a,d=c,b(function(a){c.call(this,null,a)},d))},writeLock:function(a,b,d){"function"!=typeof a?c(a,function(a){b.call(this,null,a)},d):(b=a,d=b,c(function(a){b.call(this,null,a)},d))}}};