diff options
author | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-09-09 12:32:33 +0000 |
---|---|---|
committer | kosaki <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-09-09 12:32:33 +0000 |
commit | 7198053a49d39a5c80551fc9147b9c0ab21e75a2 (patch) | |
tree | 8488378792d720378b0ff9a756eb8cf62ad8599f /lib | |
parent | 61f530500e07335b50999409a05b51a5deff67bd (diff) | |
download | ruby-7198053a49d39a5c80551fc9147b9c0ab21e75a2.tar.gz |
* 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.rb | 34 |
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 |