Browse Source

Defer mutex unlocks to prevent accidental deadlocks in connection pool

One such case happened when panicing because of nil HostInfo
(which in turn was caused by bad discovery mechanism).
Without the defer, it would stay silent and get deadlocked.
Johnny Bergström 10 years ago
parent
commit
64eb2479f8
1 changed files with 3 additions and 4 deletions
  1. 3 4
      connectionpool.go

+ 3 - 4
connectionpool.go

@@ -121,6 +121,7 @@ func newPolicyConnPool(session *Session, hostPolicy HostSelectionPolicy,
 
 
 func (p *policyConnPool) SetHosts(hosts []HostInfo) {
 func (p *policyConnPool) SetHosts(hosts []HostInfo) {
 	p.mu.Lock()
 	p.mu.Lock()
+	defer p.mu.Unlock()
 
 
 	toRemove := make(map[string]struct{})
 	toRemove := make(map[string]struct{})
 	for addr := range p.hostConnPools {
 	for addr := range p.hostConnPools {
@@ -159,7 +160,6 @@ func (p *policyConnPool) SetHosts(hosts []HostInfo) {
 	// update the policy
 	// update the policy
 	p.hostPolicy.SetHosts(hosts)
 	p.hostPolicy.SetHosts(hosts)
 
 
-	p.mu.Unlock()
 }
 }
 
 
 func (p *policyConnPool) SetPartitioner(partitioner string) {
 func (p *policyConnPool) SetPartitioner(partitioner string) {
@@ -186,6 +186,7 @@ func (p *policyConnPool) Pick(qry *Query) (SelectedHost, *Conn) {
 	)
 	)
 
 
 	p.mu.RLock()
 	p.mu.RLock()
+	defer p.mu.RUnlock()
 	for conn == nil {
 	for conn == nil {
 		host = nextHost()
 		host = nextHost()
 		if host == nil {
 		if host == nil {
@@ -201,13 +202,12 @@ func (p *policyConnPool) Pick(qry *Query) (SelectedHost, *Conn) {
 
 
 		conn = pool.Pick(qry)
 		conn = pool.Pick(qry)
 	}
 	}
-
-	p.mu.RUnlock()
 	return host, conn
 	return host, conn
 }
 }
 
 
 func (p *policyConnPool) Close() {
 func (p *policyConnPool) Close() {
 	p.mu.Lock()
 	p.mu.Lock()
+	defer p.mu.Unlock()
 
 
 	// remove the hosts from the policy
 	// remove the hosts from the policy
 	p.hostPolicy.SetHosts([]HostInfo{})
 	p.hostPolicy.SetHosts([]HostInfo{})
@@ -217,7 +217,6 @@ func (p *policyConnPool) Close() {
 		delete(p.hostConnPools, addr)
 		delete(p.hostConnPools, addr)
 		pool.Close()
 		pool.Close()
 	}
 	}
-	p.mu.Unlock()
 }
 }
 
 
 // hostConnPool is a connection pool for a single host.
 // hostConnPool is a connection pool for a single host.