Skip to content

Commit 3792db5

Browse files
net: refactor poller into new internal/poll package
This will make it possible to use the poller with the os package. This is a lot of code movement but the behavior is intended to be unchanged. Update #6817. Update #7903. Update #15021. Update #18507. Change-Id: I1413685928017c32df5654ded73a2643820977ae Reviewed-on: https://go-review.googlesource.com/36799 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: David Crawshaw <[email protected]> Reviewed-by: Russ Cox <[email protected]>
1 parent b548eee commit 3792db5

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

79 files changed

+2722
-1619
lines changed

src/cmd/dist/deps.go

+48-47
Large diffs are not rendered by default.

src/cmd/go/internal/work/build.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -2180,7 +2180,7 @@ func (gcToolchain) gc(b *Builder, p *load.Package, archive, obj string, asmhdr b
21802180
extFiles := len(p.CgoFiles) + len(p.CFiles) + len(p.CXXFiles) + len(p.MFiles) + len(p.FFiles) + len(p.SFiles) + len(p.SysoFiles) + len(p.SwigFiles) + len(p.SwigCXXFiles)
21812181
if p.Standard {
21822182
switch p.ImportPath {
2183-
case "bytes", "net", "os", "runtime/pprof", "sync", "time":
2183+
case "bytes", "internal/poll", "net", "os", "runtime/pprof", "sync", "time":
21842184
extFiles++
21852185
}
21862186
}

src/go/build/deps_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,8 @@ var pkgDeps = map[string][]string{
150150
"syscall",
151151
},
152152

153-
"os": {"L1", "os", "syscall", "time", "internal/syscall/windows"},
153+
"internal/poll": {"L0", "internal/race", "syscall", "time", "unicode/utf16", "unicode/utf8"},
154+
"os": {"L1", "os", "syscall", "time", "internal/poll", "internal/syscall/windows"},
154155
"path/filepath": {"L2", "os", "syscall"},
155156
"io/ioutil": {"L2", "os", "path/filepath", "time"},
156157
"os/exec": {"L2", "os", "context", "path/filepath", "syscall"},
@@ -300,7 +301,7 @@ var pkgDeps = map[string][]string{
300301
"net": {
301302
"L0", "CGO",
302303
"context", "math/rand", "os", "sort", "syscall", "time",
303-
"internal/nettrace",
304+
"internal/nettrace", "internal/poll",
304305
"internal/syscall/windows", "internal/singleflight", "internal/race",
305306
"golang_org/x/net/lif", "golang_org/x/net/route",
306307
},

src/internal/poll/export_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2010 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Export guts for testing.
6+
// Since testing imports os and os imports internal/poll,
7+
// the internal/poll tests can not be in package poll.
8+
9+
package poll
10+
11+
var Consume = consume
12+
13+
type FDMutex struct {
14+
fdMutex
15+
}
16+
17+
func (mu *FDMutex) Incref() bool {
18+
return mu.incref()
19+
}
20+
21+
func (mu *FDMutex) IncrefAndClose() bool {
22+
return mu.increfAndClose()
23+
}
24+
25+
func (mu *FDMutex) Decref() bool {
26+
return mu.decref()
27+
}
28+
29+
func (mu *FDMutex) RWLock(read bool) bool {
30+
return mu.rwlock(read)
31+
}
32+
33+
func (mu *FDMutex) RWUnlock(read bool) bool {
34+
return mu.rwunlock(read)
35+
}
36+
37+
func (fd *FD) EOFError(n int, err error) error {
38+
return fd.eofError(n, err)
39+
}

src/internal/poll/fd.go

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// Copyright 2017 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Package poll supports non-blocking I/O on file descriptors with polling.
6+
// This supports I/O operations that block only a goroutine, not a thread.
7+
// This is used by the net and os packages.
8+
// It uses a poller built into the runtime, with support from the
9+
// runtime scheduler.
10+
package poll
11+
12+
import (
13+
"errors"
14+
)
15+
16+
// ErrClosing is returned when a descriptor is used after it has been closed.
17+
var ErrClosing = errors.New("use of closed file or network connection")
18+
19+
// ErrTimeout is returned for an expired deadline.
20+
var ErrTimeout error = &TimeoutError{}
21+
22+
// TimeoutError is returned for an expired deadline.
23+
type TimeoutError struct{}
24+
25+
// Implement the net.Error interface.
26+
func (e *TimeoutError) Error() string { return "i/o timeout" }
27+
func (e *TimeoutError) Timeout() bool { return true }
28+
func (e *TimeoutError) Temporary() bool { return true }
29+
30+
// consume removes data from a slice of byte slices, for writev.
31+
func consume(v *[][]byte, n int64) {
32+
for len(*v) > 0 {
33+
ln0 := int64(len((*v)[0]))
34+
if ln0 > n {
35+
(*v)[0] = (*v)[0][n:]
36+
return
37+
}
38+
n -= ln0
39+
*v = (*v)[1:]
40+
}
41+
}
42+
43+
// TestHookDidWritev is a hook for testing writev.
44+
var TestHookDidWritev = func(wrote int) {}

src/net/fd_io_plan9.go renamed to src/internal/poll/fd_io_plan9.go

+6-8
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
package net
5+
package poll
66

77
import (
8-
"os"
98
"runtime"
109
"sync"
1110
"syscall"
@@ -49,7 +48,7 @@ func newAsyncIO(fn func([]byte) (int, error), b []byte) *asyncIO {
4948
// Go runtime.
5049
runtime.LockOSThread()
5150
runtime_ignoreHangup()
52-
aio.pid = os.Getpid()
51+
aio.pid = syscall.Getpid()
5352
aio.mu.Unlock()
5453

5554
n, err := fn(b)
@@ -64,8 +63,6 @@ func newAsyncIO(fn func([]byte) (int, error), b []byte) *asyncIO {
6463
return aio
6564
}
6665

67-
var hangupNote os.Signal = syscall.Note("hangup")
68-
6966
// Cancel interrupts the I/O operation, causing
7067
// the Wait function to return.
7168
func (aio *asyncIO) Cancel() {
@@ -74,11 +71,12 @@ func (aio *asyncIO) Cancel() {
7471
if aio.pid == -1 {
7572
return
7673
}
77-
proc, err := os.FindProcess(aio.pid)
78-
if err != nil {
74+
f, e := syscall.Open("/proc/"+itoa(aio.pid)+"/note", syscall.O_WRONLY)
75+
if e != nil {
7976
return
8077
}
81-
proc.Signal(hangupNote)
78+
syscall.Write(f, []byte("hangup"))
79+
syscall.Close(f)
8280
}
8381

8482
// Wait for the I/O operation to complete.

src/net/fd_mutex.go renamed to src/internal/poll/fd_mutex.go

+14-13
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,21 @@
22
// Use of this source code is governed by a BSD-style
33
// license that can be found in the LICENSE file.
44

5-
package net
5+
package poll
66

77
import "sync/atomic"
88

99
// fdMutex is a specialized synchronization primitive that manages
1010
// lifetime of an fd and serializes access to Read, Write and Close
11-
// methods on netFD.
11+
// methods on FD.
1212
type fdMutex struct {
1313
state uint64
1414
rsema uint32
1515
wsema uint32
1616
}
1717

1818
// fdMutex.state is organized as follows:
19-
// 1 bit - whether netFD is closed, if set all subsequent lock operations will fail.
19+
// 1 bit - whether FD is closed, if set all subsequent lock operations will fail.
2020
// 1 bit - lock for read operations.
2121
// 1 bit - lock for write operations.
2222
// 20 bits - total number of references (read+write+misc).
@@ -196,53 +196,54 @@ func runtime_Semrelease(sema *uint32)
196196

197197
// incref adds a reference to fd.
198198
// It returns an error when fd cannot be used.
199-
func (fd *netFD) incref() error {
199+
func (fd *FD) incref() error {
200200
if !fd.fdmu.incref() {
201-
return errClosing
201+
return ErrClosing
202202
}
203203
return nil
204204
}
205205

206206
// decref removes a reference from fd.
207207
// It also closes fd when the state of fd is set to closed and there
208208
// is no remaining reference.
209-
func (fd *netFD) decref() {
209+
func (fd *FD) decref() error {
210210
if fd.fdmu.decref() {
211-
fd.destroy()
211+
return fd.destroy()
212212
}
213+
return nil
213214
}
214215

215216
// readLock adds a reference to fd and locks fd for reading.
216217
// It returns an error when fd cannot be used for reading.
217-
func (fd *netFD) readLock() error {
218+
func (fd *FD) readLock() error {
218219
if !fd.fdmu.rwlock(true) {
219-
return errClosing
220+
return ErrClosing
220221
}
221222
return nil
222223
}
223224

224225
// readUnlock removes a reference from fd and unlocks fd for reading.
225226
// It also closes fd when the state of fd is set to closed and there
226227
// is no remaining reference.
227-
func (fd *netFD) readUnlock() {
228+
func (fd *FD) readUnlock() {
228229
if fd.fdmu.rwunlock(true) {
229230
fd.destroy()
230231
}
231232
}
232233

233234
// writeLock adds a reference to fd and locks fd for writing.
234235
// It returns an error when fd cannot be used for writing.
235-
func (fd *netFD) writeLock() error {
236+
func (fd *FD) writeLock() error {
236237
if !fd.fdmu.rwlock(false) {
237-
return errClosing
238+
return ErrClosing
238239
}
239240
return nil
240241
}
241242

242243
// writeUnlock removes a reference from fd and unlocks fd for writing.
243244
// It also closes fd when the state of fd is set to closed and there
244245
// is no remaining reference.
245-
func (fd *netFD) writeUnlock() {
246+
func (fd *FD) writeUnlock() {
246247
if fd.fdmu.rwunlock(false) {
247248
fd.destroy()
248249
}

0 commit comments

Comments
 (0)