Sfoglia il codice sorgente

Wait until we're done connecting before returning from fillPool, to avoid possible race between multiple goroutines opening new connections

Miles Delahunty 11 anni fa
parent
commit
0033e98e26
1 ha cambiato i file con 10 aggiunte e 0 eliminazioni
  1. 10 0
      connectionpool.go

+ 10 - 0
connectionpool.go

@@ -227,6 +227,8 @@ func (c *SimplePool) fillPool() {
 	c.hostMu.RLock()
 
 	//Walk through list of defined hosts
+	cHostConnected := make(chan int, len(c.hosts))
+	hostsPending := 0
 	for host := range c.hosts {
 		addr := JoinHostPort(host, c.cfg.Port)
 
@@ -251,7 +253,9 @@ func (c *SimplePool) fillPool() {
 
 		//This is reached if the host is responsive and needs more connections
 		//Create connections for host synchronously to mitigate flooding the host.
+		hostsPending++
 		go func(a string, conns int) {
+			defer func() { cHostConnected <- 1 }()
 			for ; conns < c.cfg.NumConns; conns++ {
 				c.connect(a)
 			}
@@ -259,6 +263,12 @@ func (c *SimplePool) fillPool() {
 	}
 
 	c.hostMu.RUnlock()
+
+	//Wait until we're finished connecting to each host before returning
+	for hostsPending > 0 {
+		<- cHostConnected
+		hostsPending--
+	}
 }
 
 // Should only be called if c.mu is locked