// Generated by IcedCoffeeScript 1.7.1-c
(function() {
  var Lock, NamedLock, Table, iced, __iced_k, __iced_k_noop,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  iced = require('iced-runtime').iced;
  __iced_k = __iced_k_noop = function() {};

  exports.Lock = Lock = (function() {
    function Lock() {
      this._open = true;
      this._waiters = [];
    }

    Lock.prototype.acquire = function(cb) {
      if (this._open) {
        this._open = false;
        return cb();
      } else {
        return this._waiters.push(cb);
      }
    };

    Lock.prototype.release = function() {
      var w;
      if (this._waiters.length) {
        w = this._waiters.shift();
        return w();
      } else {
        return this._open = true;
      }
    };

    Lock.prototype.open = function() {
      return this._open;
    };

    return Lock;

  })();

  NamedLock = (function(_super) {
    __extends(NamedLock, _super);

    function NamedLock(tab, name) {
      this.tab = tab;
      this.name = name;
      NamedLock.__super__.constructor.call(this);
      this.refs = 0;
    }

    NamedLock.prototype.incref = function() {
      return ++this.refs;
    };

    NamedLock.prototype.decref = function() {
      return --this.refs;
    };

    NamedLock.prototype.release = function() {
      NamedLock.__super__.release.call(this);
      if (this.decref() === 0) {
        return delete this.tab.locks[this.name];
      }
    };

    return NamedLock;

  })(Lock);

  exports.Table = Table = (function() {
    function Table() {
      this.locks = {};
    }

    Table.prototype.create = function(name) {
      var l;
      l = new NamedLock(this, name);
      return this.locks[name] = l;
    };

    Table.prototype.acquire = function(name, cb, wait) {
      var l, was_open, ___iced_passed_deferral, __iced_deferrals, __iced_k;
      __iced_k = __iced_k_noop;
      ___iced_passed_deferral = iced.findDeferral(arguments);
      l = this.locks[name] || this.create(name);
      was_open = l._open;
      l.incref();
      (function(_this) {
        return (function(__iced_k) {
          if (wait || l._open) {
            (function(__iced_k) {
              __iced_deferrals = new iced.Deferrals(__iced_k, {
                parent: ___iced_passed_deferral,
                filename: "/Users/max/src/iced/iced-utils/src/lock.iced",
                funcname: "Table.acquire"
              });
              l.acquire(__iced_deferrals.defer({
                lineno: 47
              }));
              __iced_deferrals._fulfill();
            })(__iced_k);
          } else {
            return __iced_k(l = null);
          }
        });
      })(this)((function(_this) {
        return function() {
          return cb(l, was_open);
        };
      })(this));
    };

    Table.prototype.lookup = function(name) {
      return this.locks[name];
    };

    return Table;

  })();

}).call(this);
