From f135c326402aaa757aa96aad283a91873d4ae124 Mon Sep 17 00:00:00 2001 From: David Crawshaw Date: Thu, 4 Aug 2016 13:09:29 -0400 Subject: runtime: initialize hash algs before typemap When compiling with -buildmode=shared, a map[int32]*_type is created for each extra module mapping duplicate types back to a canonical object. This is done in the function typelinksinit, which is called before the init function that sets up the hash functions for the map implementation. The result is typemap becomes unusable after runtime initialization. The fix in this CL is to move algorithm init before typelinksinit in the runtime setup process. (For 1.8, we may want to turn typemap into a sorted slice of types and use binary search.) Manually tested on GOOS=linux with: GOHOSTARCH=386 GOARCH=386 ./make.bash && \ go install -buildmode=shared std && \ cd ../test && \ go run run.go -linkshared Fixes #16590 Change-Id: Idc08c50cc70d20028276fbf564509d2cd5405210 Reviewed-on: https://go-review.googlesource.com/25469 Run-TryBot: David Crawshaw Reviewed-by: Keith Randall --- src/runtime/alg.go | 2 +- src/runtime/proc.go | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/runtime/alg.go b/src/runtime/alg.go index 66943495b5..147332e1fd 100644 --- a/src/runtime/alg.go +++ b/src/runtime/alg.go @@ -289,7 +289,7 @@ var aeskeysched [hashRandomBytes]byte // used in hash{32,64}.go to seed the hash function var hashkey [4]uintptr -func init() { +func alginit() { // Install aes hash algorithm if we have the instructions we need if (GOARCH == "386" || GOARCH == "amd64") && GOOS != "nacl" && diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 1d00930ac5..e693f7e05f 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -439,7 +439,8 @@ func schedinit() { stackinit() mallocinit() mcommoninit(_g_.m) - typelinksinit() + alginit() // maps must not be used before this call + typelinksinit() // uses maps itabsinit() msigsave(_g_.m) -- cgit v1.3 From da070bed19fb23a8dd1b9f974c7fdf1f247fdba0 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Thu, 4 Aug 2016 12:21:05 -0700 Subject: syscall: fix Gettimeofday on macOS Sierra Fixes #16606 Change-Id: I57465061b90e901293cd8b6ef756d6aa84ebd4a3 Reviewed-on: https://go-review.googlesource.com/25495 Reviewed-by: Quentin Smith Reviewed-by: Ian Lance Taylor Run-TryBot: Quentin Smith TryBot-Result: Gobot Gobot --- src/syscall/syscall_darwin_386.go | 21 ++++++++++++++------- src/syscall/syscall_darwin_amd64.go | 21 ++++++++++++++------- src/syscall/syscall_darwin_test.go | 23 +++++++++++++++++++++++ 3 files changed, 51 insertions(+), 14 deletions(-) create mode 100644 src/syscall/syscall_darwin_test.go diff --git a/src/syscall/syscall_darwin_386.go b/src/syscall/syscall_darwin_386.go index 7dbb1c3d64..f75de000bd 100644 --- a/src/syscall/syscall_darwin_386.go +++ b/src/syscall/syscall_darwin_386.go @@ -26,14 +26,21 @@ func NsecToTimeval(nsec int64) (tv Timeval) { } //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { - // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back - // in the two registers. +func Gettimeofday(tv *Timeval) error { + // The tv passed to gettimeofday must be non-nil. + // Before macOS Sierra (10.12), tv was otherwise unused and + // the answers came back in the two registers. + // As of Sierra, gettimeofday return zeros and populates + // tv itself. sec, usec, err := gettimeofday(tv) - tv.Sec = int32(sec) - tv.Usec = int32(usec) - return err + if err != nil { + return err + } + if sec != 0 || usec != 0 { + tv.Sec = int32(sec) + tv.Usec = int32(usec) + } + return nil } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/src/syscall/syscall_darwin_amd64.go b/src/syscall/syscall_darwin_amd64.go index 80e6024aeb..79083117b6 100644 --- a/src/syscall/syscall_darwin_amd64.go +++ b/src/syscall/syscall_darwin_amd64.go @@ -26,14 +26,21 @@ func NsecToTimeval(nsec int64) (tv Timeval) { } //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { - // The tv passed to gettimeofday must be non-nil - // but is otherwise unused. The answers come back - // in the two registers. +func Gettimeofday(tv *Timeval) error { + // The tv passed to gettimeofday must be non-nil. + // Before macOS Sierra (10.12), tv was otherwise unused and + // the answers came back in the two registers. + // As of Sierra, gettimeofday return zeros and populates + // tv itself. sec, usec, err := gettimeofday(tv) - tv.Sec = sec - tv.Usec = usec - return err + if err != nil { + return err + } + if sec != 0 || usec != 0 { + tv.Sec = sec + tv.Usec = usec + } + return nil } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/src/syscall/syscall_darwin_test.go b/src/syscall/syscall_darwin_test.go new file mode 100644 index 0000000000..dd0e32b968 --- /dev/null +++ b/src/syscall/syscall_darwin_test.go @@ -0,0 +1,23 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build darwin +// +build amd64 386 + +package syscall_test + +import ( + "syscall" + "testing" +) + +func TestDarwinGettimeofday(t *testing.T) { + tv := &syscall.Timeval{} + if err := syscall.Gettimeofday(tv); err != nil { + t.Fatal(err) + } + if tv.Sec == 0 && tv.Usec == 0 { + t.Fatal("Sec and Usec both zero") + } +} -- cgit v1.3 From 10316757cec3c2744ea61088e0fc905cfeb28fb2 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 5 Aug 2016 16:42:31 +0000 Subject: net/http: update bundled http2 for flow control window adjustment fix Updates bundled http2 to x/net/http2 git rev 075e191 for: http2: adjust flow control on open streams when processing SETTINGS https://golang.org/cl/25508 Fixes #16612 Change-Id: Ib0513201bff44ab747a574ae6894479325c105d2 Reviewed-on: https://go-review.googlesource.com/25543 Run-TryBot: Chris Broadfoot Reviewed-by: Ian Lance Taylor Reviewed-by: Chris Broadfoot TryBot-Result: Gobot Gobot --- src/net/http/h2_bundle.go | 112 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 34 deletions(-) diff --git a/src/net/http/h2_bundle.go b/src/net/http/h2_bundle.go index cd66c0960e..ffe15f0605 100644 --- a/src/net/http/h2_bundle.go +++ b/src/net/http/h2_bundle.go @@ -28,6 +28,7 @@ import ( "io" "io/ioutil" "log" + "math" "net" "net/http/httptrace" "net/textproto" @@ -403,9 +404,17 @@ func (e http2ConnectionError) Error() string { type http2StreamError struct { StreamID uint32 Code http2ErrCode + Cause error // optional additional detail +} + +func http2streamError(id uint32, code http2ErrCode) http2StreamError { + return http2StreamError{StreamID: id, Code: code} } func (e http2StreamError) Error() string { + if e.Cause != nil { + return fmt.Sprintf("stream error: stream ID %d; %v; %v", e.StreamID, e.Code, e.Cause) + } return fmt.Sprintf("stream error: stream ID %d; %v", e.StreamID, e.Code) } @@ -1366,7 +1375,7 @@ func http2parseWindowUpdateFrame(fh http2FrameHeader, p []byte) (http2Frame, err if fh.StreamID == 0 { return nil, http2ConnectionError(http2ErrCodeProtocol) } - return nil, http2StreamError{fh.StreamID, http2ErrCodeProtocol} + return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol) } return &http2WindowUpdateFrame{ http2FrameHeader: fh, @@ -1444,7 +1453,7 @@ func http2parseHeadersFrame(fh http2FrameHeader, p []byte) (_ http2Frame, err er } } if len(p)-int(padLength) <= 0 { - return nil, http2StreamError{fh.StreamID, http2ErrCodeProtocol} + return nil, http2streamError(fh.StreamID, http2ErrCodeProtocol) } hf.headerFragBuf = p[:len(p)-int(padLength)] return hf, nil @@ -1911,6 +1920,9 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr hdec.SetEmitEnabled(true) hdec.SetMaxStringLength(fr.maxHeaderStringLen()) hdec.SetEmitFunc(func(hf hpack.HeaderField) { + if http2VerboseLogs && http2logFrameReads { + log.Printf("http2: decoded hpack field %+v", hf) + } if !httplex.ValidHeaderFieldValue(hf.Value) { invalid = http2headerFieldValueError(hf.Value) } @@ -1969,11 +1981,17 @@ func (fr *http2Framer) readMetaFrame(hf *http2HeadersFrame) (*http2MetaHeadersFr } if invalid != nil { fr.errDetail = invalid - return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol} + if http2VerboseLogs { + log.Printf("http2: invalid header: %v", invalid) + } + return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, invalid} } if err := mh.checkPseudos(); err != nil { fr.errDetail = err - return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol} + if http2VerboseLogs { + log.Printf("http2: invalid pseudo headers: %v", err) + } + return nil, http2StreamError{mh.StreamID, http2ErrCodeProtocol, err} } return mh, nil } @@ -3604,7 +3622,7 @@ func (sc *http2serverConn) wroteFrame(res http2frameWriteResult) { case http2stateOpen: st.state = http2stateHalfClosedLocal - errCancel := http2StreamError{st.id, http2ErrCodeCancel} + errCancel := http2streamError(st.id, http2ErrCodeCancel) sc.resetStream(errCancel) case http2stateHalfClosedRemote: sc.closeStream(st, http2errHandlerComplete) @@ -3797,7 +3815,7 @@ func (sc *http2serverConn) processWindowUpdate(f *http2WindowUpdateFrame) error return nil } if !st.flow.add(int32(f.Increment)) { - return http2StreamError{f.StreamID, http2ErrCodeFlowControl} + return http2streamError(f.StreamID, http2ErrCodeFlowControl) } default: if !sc.flow.add(int32(f.Increment)) { @@ -3819,7 +3837,7 @@ func (sc *http2serverConn) processResetStream(f *http2RSTStreamFrame) error { if st != nil { st.gotReset = true st.cancelCtx() - sc.closeStream(st, http2StreamError{f.StreamID, f.ErrCode}) + sc.closeStream(st, http2streamError(f.StreamID, f.ErrCode)) } return nil } @@ -3922,13 +3940,13 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error { if !ok || st.state != http2stateOpen || st.gotTrailerHeader { if sc.inflow.available() < int32(f.Length) { - return http2StreamError{id, http2ErrCodeFlowControl} + return http2streamError(id, http2ErrCodeFlowControl) } sc.inflow.take(int32(f.Length)) sc.sendWindowUpdate(nil, int(f.Length)) - return http2StreamError{id, http2ErrCodeStreamClosed} + return http2streamError(id, http2ErrCodeStreamClosed) } if st.body == nil { panic("internal error: should have a body in this state") @@ -3936,19 +3954,19 @@ func (sc *http2serverConn) processData(f *http2DataFrame) error { if st.declBodyBytes != -1 && st.bodyBytes+int64(len(data)) > st.declBodyBytes { st.body.CloseWithError(fmt.Errorf("sender tried to send more than declared Content-Length of %d bytes", st.declBodyBytes)) - return http2StreamError{id, http2ErrCodeStreamClosed} + return http2streamError(id, http2ErrCodeStreamClosed) } if f.Length > 0 { if st.inflow.available() < int32(f.Length) { - return http2StreamError{id, http2ErrCodeFlowControl} + return http2streamError(id, http2ErrCodeFlowControl) } st.inflow.take(int32(f.Length)) if len(data) > 0 { wrote, err := st.body.Write(data) if err != nil { - return http2StreamError{id, http2ErrCodeStreamClosed} + return http2streamError(id, http2ErrCodeStreamClosed) } if wrote != len(data) { panic("internal error: bad Writer") @@ -4046,10 +4064,10 @@ func (sc *http2serverConn) processHeaders(f *http2MetaHeadersFrame) error { if sc.unackedSettings == 0 { - return http2StreamError{st.id, http2ErrCodeProtocol} + return http2streamError(st.id, http2ErrCodeProtocol) } - return http2StreamError{st.id, http2ErrCodeRefusedStream} + return http2streamError(st.id, http2ErrCodeRefusedStream) } rw, req, err := sc.newWriterAndRequest(st, f) @@ -4083,18 +4101,18 @@ func (st *http2stream) processTrailerHeaders(f *http2MetaHeadersFrame) error { } st.gotTrailerHeader = true if !f.StreamEnded() { - return http2StreamError{st.id, http2ErrCodeProtocol} + return http2streamError(st.id, http2ErrCodeProtocol) } if len(f.PseudoFields()) > 0 { - return http2StreamError{st.id, http2ErrCodeProtocol} + return http2streamError(st.id, http2ErrCodeProtocol) } if st.trailer != nil { for _, hf := range f.RegularFields() { key := sc.canonicalHeader(hf.Name) if !http2ValidTrailerHeader(key) { - return http2StreamError{st.id, http2ErrCodeProtocol} + return http2streamError(st.id, http2ErrCodeProtocol) } st.trailer[key] = append(st.trailer[key], hf.Value) } @@ -4148,18 +4166,18 @@ func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHead isConnect := method == "CONNECT" if isConnect { if path != "" || scheme != "" || authority == "" { - return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol} + return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol) } } else if method == "" || path == "" || (scheme != "https" && scheme != "http") { - return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol} + return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol) } bodyOpen := !f.StreamEnded() if method == "HEAD" && bodyOpen { - return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol} + return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol) } var tlsState *tls.ConnectionState // nil if not scheme https @@ -4216,7 +4234,7 @@ func (sc *http2serverConn) newWriterAndRequest(st *http2stream, f *http2MetaHead var err error url_, err = url.ParseRequestURI(path) if err != nil { - return nil, nil, http2StreamError{f.StreamID, http2ErrCodeProtocol} + return nil, nil, http2streamError(f.StreamID, http2ErrCodeProtocol) } requestURI = path } @@ -4993,14 +5011,14 @@ type http2ClientConn struct { br *bufio.Reader fr *http2Framer lastActive time.Time - - // Settings from peer: + // Settings from peer: (also guarded by mu) maxFrameSize uint32 maxConcurrentStreams uint32 initialWindowSize uint32 - hbuf bytes.Buffer // HPACK encoder writes into this - henc *hpack.Encoder - freeBuf [][]byte + + hbuf bytes.Buffer // HPACK encoder writes into this + henc *hpack.Encoder + freeBuf [][]byte wmu sync.Mutex // held while writing; acquire AFTER mu if holding both werr error // first write error that has occurred @@ -5244,10 +5262,6 @@ func (t *http2Transport) NewClientConn(c net.Conn) (*http2ClientConn, error) { } func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2ClientConn, error) { - if http2VerboseLogs { - t.vlogf("http2: Transport creating client conn to %v", c.RemoteAddr()) - } - cc := &http2ClientConn{ t: t, tconn: c, @@ -5260,6 +5274,10 @@ func (t *http2Transport) newClientConn(c net.Conn, singleUse bool) (*http2Client singleUse: singleUse, wantSettingsAck: true, } + if http2VerboseLogs { + t.vlogf("http2: Transport creating client conn %p to %v", cc, c.RemoteAddr()) + } + cc.cond = sync.NewCond(&cc.mu) cc.flow.add(int32(http2initialWindowSize)) @@ -5324,7 +5342,7 @@ func (cc *http2ClientConn) canTakeNewRequestLocked() bool { } return cc.goAway == nil && !cc.closed && int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) && - cc.nextStreamID < 2147483647 + cc.nextStreamID < math.MaxInt32 } func (cc *http2ClientConn) closeIfIdle() { @@ -5334,9 +5352,13 @@ func (cc *http2ClientConn) closeIfIdle() { return } cc.closed = true + nextID := cc.nextStreamID cc.mu.Unlock() + if http2VerboseLogs { + cc.vlogf("http2: Transport closing idle conn %p (forSingleUse=%v, maxStream=%v)", cc, cc.singleUse, nextID-2) + } cc.tconn.Close() } @@ -5986,11 +6008,15 @@ func (rl *http2clientConnReadLoop) run() error { for { f, err := cc.fr.ReadFrame() if err != nil { - cc.vlogf("Transport readFrame error: (%T) %v", err, err) + cc.vlogf("http2: Transport readFrame error on conn %p: (%T) %v", cc, err, err) } if se, ok := err.(http2StreamError); ok { if cs := cc.streamByID(se.StreamID, true); cs != nil { - rl.endStreamError(cs, cc.fr.errDetail) + cs.cc.writeStreamReset(cs.ID, se.Code, err) + if se.Cause == nil { + se.Cause = cc.fr.errDetail + } + rl.endStreamError(cs, se) } continue } else if err != nil { @@ -6034,6 +6060,9 @@ func (rl *http2clientConnReadLoop) run() error { cc.logf("Transport: unhandled response frame type %T", f) } if err != nil { + if http2VerboseLogs { + cc.vlogf("http2: Transport conn %p received error from processing frame %v: %v", cc, http2summarizeFrame(f), err) + } return err } if rl.closeWhenIdle && gotReply && maybeIdle && len(rl.activeRes) == 0 { @@ -6381,6 +6410,11 @@ func (rl *http2clientConnReadLoop) endStreamError(cs *http2clientStream, err err if http2isConnectionCloseRequest(cs.req) { rl.closeWhenIdle = true } + + select { + case cs.resc <- http2resAndError{err: err}: + default: + } } func (cs *http2clientStream) copyTrailers() { @@ -6425,6 +6459,16 @@ func (rl *http2clientConnReadLoop) processSettings(f *http2SettingsFrame) error cc.maxConcurrentStreams = s.Val case http2SettingInitialWindowSize: + if s.Val > math.MaxInt32 { + return http2ConnectionError(http2ErrCodeFlowControl) + } + + delta := int32(s.Val) - int32(cc.initialWindowSize) + for _, cs := range cc.streams { + cs.flow.add(delta) + } + cc.cond.Broadcast() + cc.initialWindowSize = s.Val default: @@ -6475,7 +6519,7 @@ func (rl *http2clientConnReadLoop) processResetStream(f *http2RSTStreamFrame) er case <-cs.peerReset: default: - err := http2StreamError{cs.ID, f.ErrCode} + err := http2streamError(cs.ID, f.ErrCode) cs.resetErr = err close(cs.peerReset) cs.bufPipe.CloseWithError(err) -- cgit v1.3 From 3a03e877cc03c1fd155055e60a3f1f9cb8bda8d0 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 4 Aug 2016 19:53:52 -0700 Subject: os: check for waitid returning ENOSYS Reportedly waitid is not available for Ubuntu on Windows. Fixes #16610. Change-Id: Ia724f45a85c6d3467b847da06d8c65d280781dcd Reviewed-on: https://go-review.googlesource.com/25507 Run-TryBot: Ian Lance Taylor TryBot-Result: Gobot Gobot Reviewed-by: Brad Fitzpatrick --- src/os/wait_waitid.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/os/wait_waitid.go b/src/os/wait_waitid.go index 5dbd7f9766..74b7494c0d 100644 --- a/src/os/wait_waitid.go +++ b/src/os/wait_waitid.go @@ -28,6 +28,12 @@ func (p *Process) blockUntilWaitable() (bool, error) { _, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0) runtime.KeepAlive(psig) if e != 0 { + // waitid has been available since Linux 2.6.9, but + // reportedly is not available in Ubuntu on Windows. + // See issue 16610. + if e == syscall.ENOSYS { + return false, nil + } return false, NewSyscallError("waitid", e) } return true, nil -- cgit v1.3 From 9fde86b0124b8c75000eb5d05887eff922a24566 Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Thu, 4 Aug 2016 21:34:06 -0400 Subject: runtime, syscall: fix kernel gettimeofday ABI change on iOS 10 Fixes #16570 on iOS. Thanks Daniel Burhans for reporting the bug and testing the fix. Change-Id: I43ae7b78c8f85a131ed3d93ea59da9f32a02cd8f Reviewed-on: https://go-review.googlesource.com/25481 Reviewed-by: Ian Lance Taylor Reviewed-by: Brad Fitzpatrick --- src/runtime/sys_darwin_arm.s | 15 ++++++++++++--- src/runtime/sys_darwin_arm64.s | 14 ++++++++++++-- src/syscall/syscall_darwin_arm.go | 13 +++++++++---- src/syscall/syscall_darwin_arm64.go | 13 +++++++++---- src/syscall/syscall_darwin_test.go | 2 +- 5 files changed, 43 insertions(+), 14 deletions(-) diff --git a/src/runtime/sys_darwin_arm.s b/src/runtime/sys_darwin_arm.s index 6b6437dddd..52f6a94d46 100644 --- a/src/runtime/sys_darwin_arm.s +++ b/src/runtime/sys_darwin_arm.s @@ -162,11 +162,15 @@ TEXT runtime·mincore(SB),NOSPLIT,$0 TEXT time·now(SB), 7, $32 MOVW $8(R13), R0 // timeval MOVW $0, R1 // zone + MOVW $0, R2 // see issue 16570 MOVW $SYS_gettimeofday, R12 SWI $0x80 // Note: R0 is tv_sec, R1 is tv_usec - + CMP $0, R0 + BNE inreg + MOVW 8(R13), R0 + MOVW 12(R13), R1 +inreg: MOVW R1, R2 // usec - MOVW R0, sec+0(FP) MOVW $0, R1 MOVW R1, loc+4(FP) @@ -178,9 +182,14 @@ TEXT time·now(SB), 7, $32 TEXT runtime·nanotime(SB),NOSPLIT,$32 MOVW $8(R13), R0 // timeval MOVW $0, R1 // zone + MOVW $0, R2 // see issue 16570 MOVW $SYS_gettimeofday, R12 SWI $0x80 // Note: R0 is tv_sec, R1 is tv_usec - + CMP $0, R0 + BNE inreg + MOVW 8(R13), R0 + MOVW 12(R13), R1 +inreg: MOVW R1, R2 MOVW $1000000000, R3 MULLU R0, R3, (R1, R0) diff --git a/src/runtime/sys_darwin_arm64.s b/src/runtime/sys_darwin_arm64.s index a3b851d2fc..8e6b5b1ebf 100644 --- a/src/runtime/sys_darwin_arm64.s +++ b/src/runtime/sys_darwin_arm64.s @@ -155,9 +155,14 @@ TEXT time·now(SB),NOSPLIT,$40-12 MOVD RSP, R0 // timeval MOVD R0, R9 // this is how dyld calls gettimeofday MOVW $0, R1 // zone + MOVD $0, R2 // see issue 16570 MOVW $SYS_gettimeofday, R16 SVC $0x80 // Note: x0 is tv_sec, w1 is tv_usec - + CMP $0, R0 + BNE inreg + MOVD 0(RSP), R0 + MOVW 8(RSP), R1 +inreg: MOVD R0, sec+0(FP) MOVW $1000, R3 MUL R3, R1 @@ -168,9 +173,14 @@ TEXT runtime·nanotime(SB),NOSPLIT,$40 MOVD RSP, R0 // timeval MOVD R0, R9 // this is how dyld calls gettimeofday MOVW $0, R1 // zone + MOVD $0, R2 // see issue 16570 MOVW $SYS_gettimeofday, R16 SVC $0x80 // Note: x0 is tv_sec, w1 is tv_usec - + CMP $0, R0 + BNE inreg + MOVD 0(RSP), R0 + MOVW 8(RSP), R1 +inreg: MOVW $1000000000, R3 MUL R3, R0 MOVW $1000, R3 diff --git a/src/syscall/syscall_darwin_arm.go b/src/syscall/syscall_darwin_arm.go index c302d83131..fe431039f4 100644 --- a/src/syscall/syscall_darwin_arm.go +++ b/src/syscall/syscall_darwin_arm.go @@ -26,14 +26,19 @@ func NsecToTimeval(nsec int64) (tv Timeval) { } //sysnb gettimeofday(tp *Timeval) (sec int32, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { +func Gettimeofday(tv *Timeval) error { // The tv passed to gettimeofday must be non-nil // but is otherwise unused. The answers come back // in the two registers. sec, usec, err := gettimeofday(tv) - tv.Sec = int32(sec) - tv.Usec = int32(usec) - return err + if err != nil { + return err + } + if sec != 0 || usec != 0 { + tv.Sec = int32(sec) + tv.Usec = int32(usec) + } + return nil } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/src/syscall/syscall_darwin_arm64.go b/src/syscall/syscall_darwin_arm64.go index 29f40d4229..d396e25332 100644 --- a/src/syscall/syscall_darwin_arm64.go +++ b/src/syscall/syscall_darwin_arm64.go @@ -26,14 +26,19 @@ func NsecToTimeval(nsec int64) (tv Timeval) { } //sysnb gettimeofday(tp *Timeval) (sec int64, usec int32, err error) -func Gettimeofday(tv *Timeval) (err error) { +func Gettimeofday(tv *Timeval) error { // The tv passed to gettimeofday must be non-nil // but is otherwise unused. The answers come back // in the two registers. sec, usec, err := gettimeofday(tv) - tv.Sec = sec - tv.Usec = usec - return err + if err != nil { + return err + } + if sec != 0 || usec != 0 { + tv.Sec = sec + tv.Usec = usec + } + return nil } func SetKevent(k *Kevent_t, fd, mode, flags int) { diff --git a/src/syscall/syscall_darwin_test.go b/src/syscall/syscall_darwin_test.go index dd0e32b968..cea5636d07 100644 --- a/src/syscall/syscall_darwin_test.go +++ b/src/syscall/syscall_darwin_test.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. // +build darwin -// +build amd64 386 +// +build amd64 386 arm arm64 package syscall_test -- cgit v1.3 From 26015b95634de49bc5b4ac998e8a2d1fcb8eca79 Mon Sep 17 00:00:00 2001 From: Shenghou Ma Date: Fri, 5 Aug 2016 19:16:07 -0400 Subject: runtime: make stack 16-byte aligned for external code in _rt0_amd64_linux_lib Fixes #16618. Change-Id: Iffada12e8672bbdbcf2e787782c497e2c45701b1 Reviewed-on: https://go-review.googlesource.com/25550 Run-TryBot: Minux Ma Reviewed-by: Arjan Van De Ven Reviewed-by: Ian Lance Taylor TryBot-Result: Gobot Gobot --- src/runtime/rt0_linux_amd64.s | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/runtime/rt0_linux_amd64.s b/src/runtime/rt0_linux_amd64.s index 564b51c0b3..ced471f5cb 100644 --- a/src/runtime/rt0_linux_amd64.s +++ b/src/runtime/rt0_linux_amd64.s @@ -12,13 +12,18 @@ TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8 // When building with -buildmode=c-shared, this symbol is called when the shared // library is loaded. -TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0x48 +// Note: This function calls external C code, which might required 16-byte stack +// alignment after cmd/internal/obj applies its transformations. +TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0x50 + MOVQ SP, AX + ANDQ $-16, SP MOVQ BX, 0x10(SP) MOVQ BP, 0x18(SP) MOVQ R12, 0x20(SP) MOVQ R13, 0x28(SP) MOVQ R14, 0x30(SP) MOVQ R15, 0x38(SP) + MOVQ AX, 0x40(SP) MOVQ DI, _rt0_amd64_linux_lib_argc<>(SB) MOVQ SI, _rt0_amd64_linux_lib_argv<>(SB) @@ -50,6 +55,7 @@ restore: MOVQ 0x28(SP), R13 MOVQ 0x30(SP), R14 MOVQ 0x38(SP), R15 + MOVQ 0x40(SP), SP RET TEXT _rt0_amd64_linux_lib_go(SB),NOSPLIT,$0 -- cgit v1.3 From 219ca602ab3f9d7d857bc1640e2b9e01475cdc3d Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Sat, 6 Aug 2016 10:12:03 -0700 Subject: doc: fix required OS X version inconsistency for binary downloads Updates #16625 Change-Id: Icac6705828bd9b29379596ba64b34d922b9002c3 Reviewed-on: https://go-review.googlesource.com/25548 Reviewed-by: Ian Lance Taylor --- doc/install.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/install.html b/doc/install.html index 0e6b86fdaf..cfe3e67a64 100644 --- a/doc/install.html +++ b/doc/install.html @@ -17,7 +17,7 @@

Official binary distributions are available for the FreeBSD (release 8-STABLE and above), -Linux, Mac OS X (10.7 and above), and Windows operating systems and +Linux, Mac OS X (10.8 and above), and Windows operating systems and the 32-bit (386) and 64-bit (amd64) x86 processor architectures.

@@ -49,7 +49,7 @@ If your OS or architecture is not on the list, you may be able to
FreeBSD 8-STABLE or later amd64 Debian GNU/kFreeBSD not supported Linux 2.6.23 or later with glibc amd64, 386, arm CentOS/RHEL 5.x not supported -Mac OS X 10.7 or later amd64 use the clang or gcc that comes with Xcode +Mac OS X 10.7 or later amd64 use the clang or gcc that comes with Xcode for cgo support Windows XP or later amd64, 386 use MinGW gcc. No need for cygwin or msys. -- cgit v1.3 From 7a622740655bb5fcbd160eb96887032314842e6e Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Mon, 8 Aug 2016 17:14:01 +0000 Subject: net/http: make Transport use new connection if over HTTP/2 concurrency limit The Go HTTP/1 client will make as many new TCP connections as the user requests. The HTTP/2 client tried to have that behavior, but the policy of whether a connection is re-usable didn't take into account the extra 1 stream counting against SETTINGS_MAX_CONCURRENT_STREAMS so in practice users were getting errors. For example, if the server's advertised max concurrent streams is 100 and 200 concurrrent Go HTTP requests ask for a connection at once, all 200 will think they can reuse that TCP connection, but then 100 will fail later when the number of concurrent streams exceeds 100. Instead, recognize the "no cached connections" error value in the shouldRetryRequest method, so those 100 will retry a new connection. This is the conservative fix for Go 1.7 so users don't get errors, and to match the HTTP/1 behavior. Issues #13957 and #13774 are the more involved bugs for Go 1.8. Updates #16582 Updates #13957 Change-Id: I1f15a7ce60c07a4baebca87675836d6fe03993e8 Reviewed-on: https://go-review.googlesource.com/25580 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor Reviewed-by: Chris Broadfoot Run-TryBot: Brad Fitzpatrick --- src/net/http/transport.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/net/http/transport.go b/src/net/http/transport.go index 009f3c5b6a..3046de5a8e 100644 --- a/src/net/http/transport.go +++ b/src/net/http/transport.go @@ -398,6 +398,15 @@ func (t *Transport) RoundTrip(req *Request) (*Response, error) { // HTTP request on a new connection. The non-nil input error is the // error from roundTrip. func (pc *persistConn) shouldRetryRequest(req *Request, err error) bool { + if err == http2ErrNoCachedConn { + // Issue 16582: if the user started a bunch of + // requests at once, they can all pick the same conn + // and violate the server's max concurrent streams. + // Instead, match the HTTP/1 behavior for now and dial + // again to get a new TCP connection, rather than failing + // this request. + return true + } if err == errMissingHost { // User error. return false -- cgit v1.3