libgo: Update to Go 1.2.1 release.
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 3 Mar 2014 20:14:52 +0000 (20:14 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 3 Mar 2014 20:14:52 +0000 (20:14 +0000)
From-SVN: r208286

libgo/MERGE
libgo/go/database/sql/sql.go
libgo/go/database/sql/sql_test.go
libgo/go/net/fd_windows.go
libgo/runtime/mgc0.c

index 14d78ea..cc27a79 100644 (file)
@@ -1,4 +1,4 @@
-65bf677ab8d8
+0ddbdc3c7ce2
 
 The first line of this file holds the Mercurial revision number of the
 last merge done from the master library sources.
index dddf5a3..84a0965 100644 (file)
@@ -620,8 +620,8 @@ func (db *DB) conn() (*driverConn, error) {
        }
 
        // If db.maxOpen > 0 and the number of open connections is over the limit
-       // or there are no free connection, then make a request and wait.
-       if db.maxOpen > 0 && (db.numOpen >= db.maxOpen || db.freeConn.Len() == 0) {
+       // and there are no free connection, make a request and wait.
+       if db.maxOpen > 0 && db.numOpen >= db.maxOpen && db.freeConn.Len() == 0 {
                // Make the connRequest channel. It's buffered so that the
                // connectionOpener doesn't block while waiting for the req to be read.
                ch := make(chan interface{}, 1)
index 093c0d6..787a5c9 100644 (file)
@@ -1005,6 +1005,29 @@ func TestMaxOpenConns(t *testing.T) {
        }
 }
 
+func TestSingleOpenConn(t *testing.T) {
+       db := newTestDB(t, "people")
+       defer closeDB(t, db)
+
+       db.SetMaxOpenConns(1)
+
+       rows, err := db.Query("SELECT|people|name|")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if err = rows.Close(); err != nil {
+               t.Fatal(err)
+       }
+       // shouldn't deadlock
+       rows, err = db.Query("SELECT|people|name|")
+       if err != nil {
+               t.Fatal(err)
+       }
+       if err = rows.Close(); err != nil {
+               t.Fatal(err)
+       }
+}
+
 // golang.org/issue/5323
 func TestStmtCloseDeps(t *testing.T) {
        if testing.Short() {
index 64d56c7..630fc5e 100644 (file)
@@ -513,12 +513,7 @@ func (fd *netFD) WriteTo(buf []byte, sa syscall.Sockaddr) (int, error) {
        })
 }
 
-func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
-       if err := fd.readLock(); err != nil {
-               return nil, err
-       }
-       defer fd.readUnlock()
-
+func (fd *netFD) acceptOne(toAddr func(syscall.Sockaddr) Addr, rawsa []syscall.RawSockaddrAny, o *operation) (*netFD, error) {
        // Get new socket.
        s, err := sysSocket(fd.family, fd.sotype, 0)
        if err != nil {
@@ -537,9 +532,7 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
        }
 
        // Submit accept request.
-       o := &fd.rop
        o.handle = s
-       var rawsa [2]syscall.RawSockaddrAny
        o.rsan = int32(unsafe.Sizeof(rawsa[0]))
        _, err = rsrv.ExecIO(o, "AcceptEx", func(o *operation) error {
                return syscall.AcceptEx(o.fd.sysfd, o.handle, (*byte)(unsafe.Pointer(&rawsa[0])), 0, uint32(o.rsan), uint32(o.rsan), &o.qty, &o.o)
@@ -556,6 +549,45 @@ func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
                return nil, &OpError{"Setsockopt", fd.net, fd.laddr, err}
        }
 
+       return netfd, nil
+}
+
+func (fd *netFD) accept(toAddr func(syscall.Sockaddr) Addr) (*netFD, error) {
+       if err := fd.readLock(); err != nil {
+               return nil, err
+       }
+       defer fd.readUnlock()
+
+       o := &fd.rop
+       var netfd *netFD
+       var err error
+       var rawsa [2]syscall.RawSockaddrAny
+       for {
+               netfd, err = fd.acceptOne(toAddr, rawsa[:], o)
+               if err == nil {
+                       break
+               }
+               // Sometimes we see WSAECONNRESET and ERROR_NETNAME_DELETED is
+               // returned here. These happen if connection reset is received
+               // before AcceptEx could complete. These errors relate to new
+               // connection, not to AcceptEx, so ignore broken connection and
+               // try AcceptEx again for more connections.
+               operr, ok := err.(*OpError)
+               if !ok {
+                       return nil, err
+               }
+               errno, ok := operr.Err.(syscall.Errno)
+               if !ok {
+                       return nil, err
+               }
+               switch errno {
+               case syscall.ERROR_NETNAME_DELETED, syscall.WSAECONNRESET:
+                       // ignore these and try again
+               default:
+                       return nil, err
+               }
+       }
+
        // Get local and peer addr out of AcceptEx buffer.
        var lrsa, rrsa *syscall.RawSockaddrAny
        var llen, rlen int32
index d5ce9c8..f963686 100644 (file)
@@ -1770,6 +1770,8 @@ runtime_memorydump(void)
 void
 runtime_gchelper(void)
 {
+       uint32 nproc;
+
        gchelperstart();
 
        // parallel mark for over gc roots
@@ -1786,7 +1788,8 @@ runtime_gchelper(void)
 
        runtime_parfordo(work.sweepfor);
        bufferList[runtime_m()->helpgc].busy = 0;
-       if(runtime_xadd(&work.ndone, +1) == work.nproc-1)
+       nproc = work.nproc;  // work.nproc can change right after we increment work.ndone
+       if(runtime_xadd(&work.ndone, +1) == nproc-1)
                runtime_notewakeup(&work.alldone);
 }