Skip to content

net/http: bug in late binding #10155

Closed
Closed
@dvyukov

Description

@dvyukov

Late binding does the following (putIdleConn):

waitingDialer := t.idleConnCh[key]
select {
case waitingDialer <- pconn:
    t.idleMu.Unlock()
    return true
default:
    if waitingDialer != nil {
        delete(t.idleConnCh, key)
    }
}

However, receive in getConn is not atomic with creation of the idleConnCh channel, so it is possible that:

  • getConn inserts a chan into idleConnCh
  • putIdleConn gets the chan, but the non-blocking send fails
  • getConn blocks on receive from idleConnCh

So when we need a conn the most, we actually miss the opportunity to match getConn and putIdleConn.

Another bad consequence is that putIdleConn will delete the chan from t.idleConnCh in this situation. This can disable late binding for a set of concurrent getConn's -- subsequent putIdleConn's won't hand off connections to them.

@bradfitz

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions