summaryrefslogtreecommitdiff
path: root/lib/thread.rb
blob: 30f77ddbebdea087ac7970dc8436e17cc8e44992 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#
#		thread.rb - thread support classes
#			$Date: 1996/05/21 09:29:21 $
#			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