summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-09 12:32:33 +0000
committerkosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-09-09 12:32:33 +0000
commit7198053a49d39a5c80551fc9147b9c0ab21e75a2 (patch)
tree8488378792d720378b0ff9a756eb8cf62ad8599f /lib
parent61f530500e07335b50999409a05b51a5deff67bd (diff)
* lib/thread.rb (Queue#pop): Fixed double registration issue when
mutex.sleep is interrupted. [Bug #5258] [ruby-dev:44448] * lib/thread.rb (SizedQueue#push): ditto. * test/thread/test_queue.rb (test_sized_queue_and_wakeup, test_queue_pop_interrupt, test_sized_queue_pop_interrupt, test_sized_queue_push_interrupt): new tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36938 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r--lib/thread.rb34
1 files changed, 21 insertions, 13 deletions
diff --git a/lib/thread.rb b/lib/thread.rb
index 88e86ab2e1..0a5d1f41c1 100644
--- a/lib/thread.rb
+++ b/lib/thread.rb
@@ -182,16 +182,20 @@ class Queue
#
def pop(non_block=false)
@mutex.synchronize{
- while true
- if @que.empty?
- raise ThreadError, "queue empty" if non_block
- # @waiting.include? check is necessary for avoiding a race against
- # Thread.wakeup [Bug 5195]
- @waiting.push Thread.current unless @waiting.include?(Thread.current)
- @mutex.sleep
- else
- return @que.shift
+ begin
+ while true
+ if @que.empty?
+ raise ThreadError, "queue empty" if non_block
+ # @waiting.include? check is necessary for avoiding a race against
+ # Thread.wakeup [Bug 5195]
+ @waiting.push Thread.current unless @waiting.include?(Thread.current)
+ @mutex.sleep
+ else
+ return @que.shift
+ end
end
+ ensure
+ @waiting.delete(Thread.current)
end
}
end
@@ -298,10 +302,14 @@ class SizedQueue < Queue
#
def push(obj)
@mutex.synchronize{
- while true
- break if @que.length < @max
- @queue_wait.push Thread.current
- @mutex.sleep
+ begin
+ while true
+ break if @que.length < @max
+ @queue_wait.push Thread.current unless @queue_wait.include?(Thread.current)
+ @mutex.sleep
+ end
+ ensure
+ @queue_wait.delete(Thread.current)
end
@que.push obj