title: redigo connection pool - Why release lock when removing stale connection
body: <p>Redigo is a golang client for the redis database. It uses struct <code>Pool</code> to maintain a pool of connections. This struct holds a mutex lock for application putting and getting connection parallelly.</p>
  
  <pre><code>type Pool struct {
      // ...
      IdleTimeout time.Duration
      mu     sync.Mutex
      // Stack of idleConn with most recently used at the front.
      idle list.List
  }
  </code></pre>
  
  <p>In its <code>get</code> method, connection pool removes stale (idle timeout) connections firstly. When finding a stale connection, the pool pops it, releases lock, then closes connection, tries to acquire lock again.</p>
  
  <pre><code>func (p *Pool) get() (Conn, error) {
      p.mu.Lock()
  
      // Prune stale connections.
  
      if timeout := p.IdleTimeout; timeout &gt; 0 {
          for i, n := 0, p.idle.Len(); i &lt; n; i++ {
              e := p.idle.Back()
              if e == nil {
                  break
              }
              ic := e.Value.(idleConn)
                  if ic.t.Add(timeout).After(nowFunc()) {
                      break
                  }
              p.idle.Remove(e)
              p.release()
              // Why does pool unlock and try to acquire lock again?
              p.mu.Unlock()
              // Close this stale connection.
              ic.c.Close()
              p.mu.Lock()
          }
      }
  </code></pre>
  
  <p>Why does pool unlock and try to acquire lock again, instead of just unlocking before function returns? I guess closing a connection may cost quite a lot time, which will slow down other goroutine waiting on this mutex. </p>
  
  <p>Here is the whole <a href="https://github.com/garyburd/redigo/blob/master/redis/pool.go#L220" rel="nofollow noreferrer">Pool get method</a></p>