aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2011-03-15 17:00:34 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2011-03-15 17:00:34 +0200
commite0644a5b0af8b4655f52c52da1b7f57725504b3d (patch)
tree1b18d050bb5523595572ddc67ee8e4df74801c68
parent842e37f7372fbfaf7cc5aa422e5c20a28f5d5d61 (diff)
Avoid holding connection pool lock while pinging connection1.2.0
-rw-r--r--odb/mysql/connection-factory.cxx67
1 files changed, 42 insertions, 25 deletions
diff --git a/odb/mysql/connection-factory.cxx b/odb/mysql/connection-factory.cxx
index bef21ce..225ef9a 100644
--- a/odb/mysql/connection-factory.cxx
+++ b/odb/mysql/connection-factory.cxx
@@ -169,41 +169,58 @@ namespace odb
{
tls_get (mysql_thread_init_);
- lock l (mutex_);
-
+ // The outer loop checks whether the connection we were
+ // given is still valid.
+ //
while (true)
{
- // See if we have a spare connection.
+ shared_ptr<pooled_connection> c;
+
+ lock l (mutex_);
+
+ // The inner loop tries to find a free connection.
//
- if (connections_.size () != 0)
+ while (true)
{
- shared_ptr<pooled_connection> c (connections_.back ());
- connections_.pop_back ();
+ // See if we have a spare connection.
+ //
+ if (connections_.size () != 0)
+ {
+ c = connections_.back ();
+ connections_.pop_back ();
- if (ping_ && !c->ping ())
- continue;
+ c->pool_ = this;
+ in_use_++;
+ break;
+ }
- c->pool_ = this;
- in_use_++;
- return c;
- }
+ // See if we can create a new one.
+ //
+ if(max_ == 0 || in_use_ < max_)
+ {
+ // For new connections we don't need to ping so we
+ // can return immediately.
+ //
+ shared_ptr<pooled_connection> c (
+ new (shared) pooled_connection (*db_, this));
+ in_use_++;
+ return c;
+ }
- // See if we can create a new one.
- //
- if(max_ == 0 || in_use_ < max_)
- {
- shared_ptr<pooled_connection> c (
- new (shared) pooled_connection (*db_, this));
- in_use_++;
- return c;
+ // Wait until someone releases a connection.
+ //
+ waiters_++;
+ cond_.wait ();
+ waiters_--;
}
- // Wait until someone releases a connection.
- //
- waiters_++;
- cond_.wait ();
- waiters_--;
+ l.unlock ();
+
+ if (!ping_ || c->ping ())
+ return c;
}
+
+ return shared_ptr<pooled_connection> (); // Never reached.
}
void connection_pool_factory::