diff options
author | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-03 20:14:52 +0000 |
---|---|---|
committer | ian <ian@138bc75d-0d04-0410-961f-82ee72b054a4> | 2014-03-03 20:14:52 +0000 |
commit | 2f501e2420760a9e62838d39fa7738e7d3284231 (patch) | |
tree | fb0eb29cec9de27ca80e274d703ef63dd94e37c3 /libgo/go | |
parent | d7f5615e21e38f5c85175b3cf2a1a6525d9d9558 (diff) | |
download | gcc-2f501e2420760a9e62838d39fa7738e7d3284231.tar.gz |
libgo: Update to Go 1.2.1 release.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@208286 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libgo/go')
-rw-r--r-- | libgo/go/database/sql/sql.go | 4 | ||||
-rw-r--r-- | libgo/go/database/sql/sql_test.go | 23 | ||||
-rw-r--r-- | libgo/go/net/fd_windows.go | 48 |
3 files changed, 65 insertions, 10 deletions
diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go index dddf5a3f257..84a09651322 100644 --- a/libgo/go/database/sql/sql.go +++ b/libgo/go/database/sql/sql.go @@ -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) diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go index 093c0d64cac..787a5c9f744 100644 --- a/libgo/go/database/sql/sql_test.go +++ b/libgo/go/database/sql/sql_test.go @@ -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() { diff --git a/libgo/go/net/fd_windows.go b/libgo/go/net/fd_windows.go index 64d56c73e06..630fc5e6f71 100644 --- a/libgo/go/net/fd_windows.go +++ b/libgo/go/net/fd_windows.go @@ -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 |