]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
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 14d78eae0e9a86ea031c05d00036c5780ba40e43..cc27a7997766d8dcaf9bd13ddc6fa7c273545a1e 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 dddf5a3f257257f78b7d95acbe108198ae8df200..84a096513221bc197aa148ea5de34cfede84b28b 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 093c0d64caceecc170153abf96d500ccf7372097..787a5c9f74423aeeda907390ee6979285a210f15 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 64d56c73e06c4316fb0c9fcc143257120db03775..630fc5e6f7192bdb6b563519a4bff408d1355f78 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 d5ce9c883b1e066062020349769a01b81c9c7251..f963686e31359f8fa074b66e6b859d059d3f0d7d 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);
 }