diff options
Diffstat (limited to 'lib/thread.rb')
-rw-r--r-- | lib/thread.rb | 110 |
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 |