context: /* Copyright (C) 2004 - 2009  Versant Inc.  http://www.db4o.com */
  
  using System;
  using System.Collections;
  using Db4objects.Db4o.Foundation;
  using Sharpen;
  
  namespace Db4objects.Db4o.Foundation
  {
  	/// <exclude></exclude>
  	public class BlockingQueue : IBlockingQueue4
  	{
  		protected NonblockingQueue _queue = new NonblockingQueue();
  
  		protected Lock4 _lock = new Lock4();
  
  		protected bool _stopped;
  
  		public virtual void Add(object obj)
  		{
  			if (obj == null)
  			{
  				throw new ArgumentException();
  			}
  			_lock.Run(new _IClosure4_20(this, obj));
  		}
  
  		private sealed class _IClosure4_20 : IClosure4
  		{
  			public _IClosure4_20(BlockingQueue _enclosing, object obj)
  			{
  				this._enclosing = _enclosing;
  				this.obj = obj;
  			}
  
  			public object Run()
  			{
  				this._enclosing._queue.Add(obj);
  				this._enclosing._lock.Awake();
  				return null;
  			}
  
  			private readonly BlockingQueue _enclosing;
  
  			private readonly object obj;
  		}
  
  		public virtual bool HasNext()
  		{
  			return (((bool)_lock.Run(new _IClosure4_30(this))));
  		}
  
  		private sealed class _IClosure4_30 : IClosure4
  		{
  			public _IClosure4_30(BlockingQueue _enclosing)
  			{
  				this._enclosing = _enclosing;
  			}
  
  			public object Run()
  			{
  				return this._enclosing._queue.HasNext();
  			}
  
  			private readonly BlockingQueue _enclosing;
  		}
  
  		public virtual IEnumerator Iterator()
  		{
  			return ((IEnumerator)_lock.Run(new _IClosure4_38(this)));
  		}
  
  		private sealed class _IClosure4_38 : IClosure4
  		{
  			public _IClosure4_38(BlockingQueue _enclosing)
  			{
  				this._enclosing = _enclosing;
  			}
  
  			public object Run()
  			{
  				return this._enclosing._queue.Iterator();
  			}
  
  			private readonly BlockingQueue _enclosing;
  		}
  
  		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
  		public virtual object Next(long timeout)
  		{
  			return (object)_lock.Run(new _IClosure4_46(this, timeout));
  		}
  
  		private sealed class _IClosure4_46 : IClosure4
  		{
  			public _IClosure4_46(BlockingQueue _enclosing, long timeout)
  			{
  				this._enclosing = _enclosing;
  				this.timeout = timeout;
  			}
  
  			public object Run()
  			{
  				return this._enclosing.UnsafeWaitForNext(timeout) ? this._enclosing.UnsafeNext() : 
  					null;
  			}
  
  			private readonly BlockingQueue _enclosing;
  
  			private readonly long timeout;
  		}
  
  		public virtual int DrainTo(Collection4 target)
  		{
  			return (((int)_lock.Run(new _IClosure4_54(this, target))));
  		}
  
  		private sealed class _IClosure4_54 : IClosure4
  		{
  			public _IClosure4_54(BlockingQueue _enclosing, Collection4 target)
  			{
  				this._enclosing = _enclosing;
  				this.target = target;
  			}
  
  			public object Run()
  			{
  				this._enclosing.UnsafeWaitForNext();
  				int i = 0;
  				while (this._enclosing.HasNext())
  				{
  					i++;
  					target.Add(this._enclosing.UnsafeNext());
  				}
  				return i;
  			}
  
  			private readonly BlockingQueue _enclosing;
  
  			private readonly Collection4 target;
  		}
  
  		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
  		public virtual bool WaitForNext(long timeout)
  		{
  			return (((bool)_lock.Run(new _IClosure4_68(this, timeout))));
  		}
  
  		private sealed class _IClosure4_68 : IClosure4
  		{
  			public _IClosure4_68(BlockingQueue _enclosing, long timeout)
  			{
  				this._enclosing = _enclosing;
  				this.timeout = timeout;
  			}
  
  			public object Run()
  			{
  				return this._enclosing.UnsafeWaitForNext(timeout);
  			}
  
  			private readonly BlockingQueue _enclosing;
  
  			private readonly long timeout;
  		}
  
  		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
  		public virtual object Next()
  		{
  			return (object)_lock.Run(new _IClosure4_76(this));
  		}
  
  		private sealed class _IClosure4_76 : IClosure4
  		{
  			public _IClosure4_76(BlockingQueue _enclosing)
  			{
  				this._enclosing = _enclosing;
  			}
  
  			public object Run()
  			{
  				this._enclosing.UnsafeWaitForNext();
  				return this._enclosing.UnsafeNext();
  			}
  
  			private readonly BlockingQueue _enclosing;
  		}
  
  		public virtual void Stop()
  		{
  			_lock.Run(new _IClosure4_85(this));
  		}
  
  		private sealed class _IClosure4_85 : IClosure4
  		{
  			public _IClosure4_85(BlockingQueue _enclosing)
  			{
  				this._enclosing = _enclosing;
  			}
  
  			public object Run()
  			{
  				this._enclosing._stopped = true;
  				this._enclosing._lock.Awake();
  				return null;
  			}
  
  			private readonly BlockingQueue _enclosing;
  		}
  
  		public virtual object NextMatching(IPredicate4 condition)
  		{
  			return _lock.Run(new _IClosure4_95(this, condition));
  		}
  
  		private sealed class _IClosure4_95 : IClosure4
  		{
  			public _IClosure4_95(BlockingQueue _enclosing, IPredicate4 condition)
  			{
  				this._enclosing = _enclosing;
  				this.condition = condition;
  			}
  
  			public object Run()
  			{
  				return this._enclosing._queue.NextMatching(condition);
  			}
  
  			private readonly BlockingQueue _enclosing;
  
  			private readonly IPredicate4 condition;
  		}
  
  		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
  		public virtual void WaitForNext()
  		{
  			_lock.Run(new _IClosure4_103(this));
  		}
  
  		private sealed class _IClosure4_103 : IClosure4
  		{
  			public _IClosure4_103(BlockingQueue _enclosing)
  			{
  				this._enclosing = _enclosing;
  			}
  
  			public object Run()
  			{
  				this._enclosing.UnsafeWaitForNext();
  				return null;
  			}
  
  			private readonly BlockingQueue _enclosing;
  		}
  
  		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
  		protected virtual void UnsafeWaitForNext()
  		{
  			UnsafeWaitForNext(long.MaxValue);
  		}
  
  		/// <exception cref="Db4objects.Db4o.Foundation.BlockingQueueStoppedException"></exception>
  		protected virtual bool UnsafeWaitForNext(long timeout)
  		{
  			long timeLeft = timeout;
  			long now = Runtime.CurrentTimeMillis();
  
gt: 			while (timeLeft > 0)