From 997d9b8ae2f5f391ef23dc4d3792e7d863675eb8 Mon Sep 17 00:00:00 2001 From: Kyle Banker Date: Thu, 17 Mar 2011 22:14:31 -0400 Subject: [PATCH] RUBY-231 RUBY-250 Validate socket against pid --- lib/mongo/util/pool.rb | 17 +++++++++++++++-- test/connection_test.rb | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/mongo/util/pool.rb b/lib/mongo/util/pool.rb index eb8c19a..1ec45f8 100644 --- a/lib/mongo/util/pool.rb +++ b/lib/mongo/util/pool.rb @@ -41,6 +41,7 @@ module Mongo @socket_ops = Hash.new { |h, k| h[k] = [] } @sockets = [] + @pids = {} @checked_out = [] end @@ -54,6 +55,7 @@ module Mongo end @host = @port = nil @sockets.clear + @pids.clear @checked_out.clear end @@ -83,6 +85,7 @@ module Mongo @connection.apply_saved_authentication(:socket => socket) @sockets << socket + @pids[socket] = Process.pid @checked_out << socket socket end @@ -115,12 +118,22 @@ module Mongo # Checks out the first available socket from the pool. # + # If the pid has changed, remove the socket and check out + # new one. + # # This method is called exclusively from #checkout; # therefore, it runs within a mutex. def checkout_existing_socket socket = (@sockets - @checked_out).first - @checked_out << socket - socket + if @pids[socket] != Process.pid + @pids[socket] = nil + @sockets.delete(socket) + socket.close + checkout_new_socket + else + @checked_out << socket + socket + end end # Check out an existing socket or create a new socket if the maximum diff --git a/test/connection_test.rb b/test/connection_test.rb index 37abbfd..76ff6fb 100644 --- a/test/connection_test.rb +++ b/test/connection_test.rb @@ -220,6 +220,7 @@ class TestConnection < Test::Unit::TestCase conn.primary_pool.host = 'localhost' conn.primary_pool.port = Mongo::Connection::DEFAULT_PORT + conn.primary_pool.instance_variable_set("@pids", {dropped_socket => Process.pid}) conn.primary_pool.instance_variable_set("@sockets", [dropped_socket]) assert !conn.active?