From: beatles Date: Thu, 2 Oct 2008 04:04:11 +0000 (+0000) Subject: Refactored. X-Git-Tag: 20170902~238 X-Git-Url: http://git.sourceforge.jp/view?p=shogi-server%2Fshogi-server.git;a=commitdiff_plain;h=c96f64a48c084e484c78137c3442c1b3c44707d6 Refactored. --- diff --git a/shogi_server/player.rb b/shogi_server/player.rb index 07303cb..f6c735a 100644 --- a/shogi_server/player.rb +++ b/shogi_server/player.rb @@ -17,8 +17,6 @@ ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -require 'monitor' - module ShogiServer # for a namespace class BasicPlayer @@ -112,9 +110,7 @@ class Player < BasicPlayer @sente = nil @socket_buffer = [] @main_thread = Thread::current - @write_queue = [] - @wq_mon = Monitor.new - @wq_cond = @wq_mon.new_cond + @write_queue = ShogiServer::TimeoutQueue.new(20) @player_logger = nil start_write_thread end @@ -188,24 +184,10 @@ class Player < BasicPlayer @write_thread = Thread.start do Thread.pass while !@socket.closed? - str = "" begin - timeout_flg = false - @wq_mon.synchronize do - if @write_queue.empty? - if @wq_cond.wait(15) - #timeout - timeout_flg = true - # log_debug("write_queue health check timeout") - end - end - if !timeout_flg && !@write_queue.empty? - str = @write_queue.shift - # log_debug("Dequeued %s from %s's write_queue." % [str, @name]) - end - end # synchronize - next if timeout_flg - break if str == nil # exit + str = @write_queue.deq + break if (str == nil) + next if (str == :timeout) if r = select(nil, [@socket], nil, 20) r[1].first.write(str) @@ -227,12 +209,7 @@ class Player < BasicPlayer # Note that sending a message is included in the giant lock. # def write_safe(str) - @wq_mon.synchronize do - # log_debug("Enqueuing %s..." % [str]) - @write_queue.push(str) - # log_debug("Enqueued %s into %s's write_queue." % [str, @name]) - @wq_cond.broadcast - end + @write_queue.enq(str) end def to_s diff --git a/shogi_server/timeout_queue.rb b/shogi_server/timeout_queue.rb index 8b367b4..60189d0 100644 --- a/shogi_server/timeout_queue.rb +++ b/shogi_server/timeout_queue.rb @@ -1,3 +1,22 @@ +## $Id$ + +## Copyright (C) 2004 NABEYA Kenichi (aka nanami@2ch) +## Copyright (C) 2007-2008 Daigo Moriwaki (daigo at debian dot org) +## +## This program is free software; you can redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 2 of the License, or +## (at your option) any later version. +## +## This program is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + # queue = Queue.new # timeout(5) do # queue.deq @@ -9,75 +28,45 @@ # See: http://www.ruby-forum.com/topic/107864 # -require 'thread' require 'monitor' module ShogiServer class TimeoutQueue - def initialize - @lock = Mutex.new - @messages = [] - @readers = [] + def initialize(timeout=20) + @timeout = 20 # sec + @queue = [] + @mon = Monitor.new + @cond = @mon.new_cond end def enq(msg) - @lock.synchronize do - unless @readers.empty? - @readers.pop << msg - else - @messages.push msg - end + @mon.synchronize do + @queue.push(msg) + @cond.broadcast end end # - # @param timeout - # @return nil if timeout + # @return :timeout if timeout # - def deq(timeout=5) - timeout_thread = nil - mon = nil - empty_cond = nil + def deq + timeout_flg = false + ret = nil - begin - reader = nil - @lock.synchronize do - unless @messages.empty? - # fast path - return @messages.shift - else - reader = Queue.new - @readers.push reader - if timeout - mon = Monitor.new - empty_cond = mon.new_cond - - timeout_thread = Thread.new do - mon.synchronize do - if empty_cond.wait(timeout) - # timeout - @lock.synchronize do - @readers.delete reader - reader << nil - end - else - # timeout_thread was waked up before timeout - end - end - end # thread - end + @mon.synchronize do + if @queue.empty? + if @cond.wait(15) + #timeout + timeout_flg = true + ret = :timeout end end - # either timeout or writer will send to us - return reader.shift - ensure - # (try to) clean up timeout thread - if timeout_thread - mon.synchronize { empty_cond.signal } - Thread.pass + if !timeout_flg && !@queue.empty? + ret = @queue.shift end - end + end # synchronize + return ret end end