about summary refs log tree commit homepage
path: root/lib/unicorn/semaphore.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/unicorn/semaphore.rb')
-rw-r--r--lib/unicorn/semaphore.rb46
1 files changed, 46 insertions, 0 deletions
diff --git a/lib/unicorn/semaphore.rb b/lib/unicorn/semaphore.rb
new file mode 100644
index 0000000..1c0b87c
--- /dev/null
+++ b/lib/unicorn/semaphore.rb
@@ -0,0 +1,46 @@
+class Semaphore
+  def initialize(resource_count = 0)
+    @available_resource_count = resource_count
+    @mutex = Mutex.new
+    @waiting_threads = []
+  end
+  
+  def wait
+    make_thread_wait unless resource_is_available
+  end
+  
+  def signal
+    schedule_waiting_thread if thread_is_waiting
+  end
+  
+  def synchronize
+    self.wait
+    yield
+  ensure
+    self.signal
+  end
+  
+  private
+  
+  def resource_is_available
+    @mutex.synchronize do
+      return (@available_resource_count -= 1) >= 0
+    end
+  end
+  
+  def make_thread_wait
+    @waiting_threads << Thread.current
+    Thread.stop  
+  end
+  
+  def thread_is_waiting
+    @mutex.synchronize do
+      return (@available_resource_count += 1) <= 0
+    end
+  end
+  
+  def schedule_waiting_thread
+    thread = @waiting_threads.shift
+    thread.wakeup if thread
+  end
+end