lib/rmpd/connection.rb in rmpd-1.1.12 vs lib/rmpd/connection.rb in rmpd-1.1.13

- old
+ new

@@ -14,18 +14,26 @@ def initialize(config_file=nil) @config = Rmpd::Config.new(config_file) @socket = nil + @socket_mu = Mutex.new end def close + @socket_mu.lock @socket.close + @socket_mu.unlock end def connect - return unless @socket.nil? || @socket.closed? + @socket_mu.lock + unless @socket.nil? || @socket.closed? + @socket_mu.unlock + return + end + @socket_mu.unlock if %r{^/} === @config.hostname connect_unix_socket else connect_inet_socket @@ -34,53 +42,67 @@ read_response # protocol version, ignore for now password(@config.password) if @config.password end def connect_unix_socket - @socket = UNIXSocket.new(@config.hostname) - rescue StandardError => error - @socket = nil - raise MpdConnRefusedError.new(error) + @socket_mu.lock + begin + @socket = UNIXSocket.new(@config.hostname) + rescue StandardError => error + @socket = nil + raise MpdConnRefusedError.new(error) + ensure + @socket_mu.unlock + end end def connect_inet_socket Socket::getaddrinfo(@config.hostname, @config.port, nil, SOCK_STREAM).each do |info| + @socket_mu.lock begin sockaddr = Socket.pack_sockaddr_in(info[1], info[3]) @socket = Socket.new(info[4], info[5], 0) @socket.connect(sockaddr) rescue StandardError => error @socket = nil raise MpdConnRefusedError.new(error) else break + ensure + @socket_mu.unlock end end end def send_command(command, *args) tries = 0 + connect + @socket_mu.lock begin - connect @socket.puts("#{command} #{quote(args).join(" ")}".strip) rescue Errno::EPIPE, EOFError @socket.close if (tries += 1) < MAX_RETRIES retry else raise MpdError.new("Retry count exceeded") end + ensure + @socket_mu.unlock end end def read_response response = [] - while (line = @socket.readline.force_encoding("UTF-8")) - response << line.strip - break if END_RE === line + @socket_mu.synchronize do + while (line = @socket.readline.force_encoding("UTF-8")) + response << line.strip + break if END_RE === line + end end + response end def mpd self