summaryrefslogtreecommitdiff
path: root/lib/thread.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/thread.rb')
-rw-r--r--lib/thread.rb110
1 files changed, 110 insertions, 0 deletions
diff --git a/lib/thread.rb b/lib/thread.rb
new file mode 100644
index 0000000000..4f294cc9a3
--- /dev/null
+++ b/lib/thread.rb
@@ -0,0 +1,110 @@
+#
+# thread.rb - thread support classes
+# $Date$
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+#
+
+unless defined? Thread
+ fail "Thread not available for this ruby interpreter"
+end
+
+unless defined? ThreadError
+ class ThreadError<Exception
+ end
+end
+
+class Mutex
+ def initialize
+ @waiting = []
+ @locked = FALSE;
+ end
+
+ def locked?
+ @locked
+ end
+
+ def try_lock
+ result = FALSE
+ Thread.critical = TRUE
+ unless @locked
+ @locked = TRUE
+ result = TRUE
+ end
+ Thread.critical = FALSE
+ result
+ end
+
+ def lock
+ while (Thread.critical = TRUE; @locked)
+ @waiting.push Thread.current
+ Thread.stop
+ end
+ @locked = TRUE
+ Thread.critical = FALSE
+ self
+ end
+
+ def unlock
+ return unless @locked
+ Thread.critical = TRUE
+ wait = @waiting
+ @waiting = []
+ @locked = FALSE
+ Thread.critical = FALSE
+ for w in wait
+ w.run
+ end
+ self
+ end
+
+ def synchronize
+ begin
+ lock
+ yield
+ ensure
+ unlock
+ end
+ end
+end
+
+class Queue
+ def initialize
+ @que = []
+ @waiting = []
+ end
+
+ def push(obj)
+ Thread.critical = TRUE
+ @que.push obj
+ t = @waiting.shift
+ Thread.critical = FALSE
+ t.run if t
+ end
+
+ def pop non_block=FALSE
+ item = nil
+ until item
+ Thread.critical = TRUE
+ if @que.length == 0
+ if non_block
+ Thread.critical = FALSE
+ raise ThreadError, "queue empty"
+ end
+ @waiting.push Thread.current
+ Thread.stop
+ else
+ item = @que.shift
+ end
+ end
+ Thread.critical = FALSE
+ item
+ end
+
+ def empty?
+ @que.length == 0
+ end
+
+ def length
+ @que.length
+ end
+end