1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
// Copyright 2013 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 dragonfly freebsd linux netbsd openbsd windows
package net
import (
"sync"
"syscall"
"time"
)
func runtime_pollServerInit()
func runtime_pollOpen(fd uintptr) (uintptr, int)
func runtime_pollClose(ctx uintptr)
func runtime_pollWait(ctx uintptr, mode int) int
func runtime_pollWaitCanceled(ctx uintptr, mode int) int
func runtime_pollReset(ctx uintptr, mode int) int
func runtime_pollSetDeadline(ctx uintptr, d int64, mode int)
func runtime_pollUnblock(ctx uintptr)
type pollDesc struct {
runtimeCtx uintptr
}
var serverInit sync.Once
func (pd *pollDesc) Init(fd *netFD) error {
serverInit.Do(runtime_pollServerInit)
ctx, errno := runtime_pollOpen(uintptr(fd.sysfd))
if errno != 0 {
return syscall.Errno(errno)
}
pd.runtimeCtx = ctx
return nil
}
func (pd *pollDesc) Close() {
if pd.runtimeCtx == 0 {
return
}
runtime_pollClose(pd.runtimeCtx)
pd.runtimeCtx = 0
}
func (pd *pollDesc) Lock() {
}
func (pd *pollDesc) Unlock() {
}
func (pd *pollDesc) Wakeup() {
}
// Evict evicts fd from the pending list, unblocking any I/O running on fd.
// Return value is whether the pollServer should be woken up.
func (pd *pollDesc) Evict() bool {
if pd.runtimeCtx == 0 {
return false
}
runtime_pollUnblock(pd.runtimeCtx)
return false
}
func (pd *pollDesc) Prepare(mode int) error {
res := runtime_pollReset(pd.runtimeCtx, mode)
return convertErr(res)
}
func (pd *pollDesc) PrepareRead() error {
return pd.Prepare('r')
}
func (pd *pollDesc) PrepareWrite() error {
return pd.Prepare('w')
}
func (pd *pollDesc) Wait(mode int) error {
res := runtime_pollWait(pd.runtimeCtx, mode)
return convertErr(res)
}
func (pd *pollDesc) WaitRead() error {
return pd.Wait('r')
}
func (pd *pollDesc) WaitWrite() error {
return pd.Wait('w')
}
func (pd *pollDesc) WaitCanceled(mode int) {
runtime_pollWaitCanceled(pd.runtimeCtx, mode)
}
func (pd *pollDesc) WaitCanceledRead() {
pd.WaitCanceled('r')
}
func (pd *pollDesc) WaitCanceledWrite() {
pd.WaitCanceled('w')
}
func convertErr(res int) error {
switch res {
case 0:
return nil
case 1:
return errClosing
case 2:
return errTimeout
}
println("unreachable: ", res)
panic("unreachable")
}
func (fd *netFD) setDeadline(t time.Time) error {
return setDeadlineImpl(fd, t, 'r'+'w')
}
func (fd *netFD) setReadDeadline(t time.Time) error {
return setDeadlineImpl(fd, t, 'r')
}
func (fd *netFD) setWriteDeadline(t time.Time) error {
return setDeadlineImpl(fd, t, 'w')
}
func setDeadlineImpl(fd *netFD, t time.Time, mode int) error {
d := t.UnixNano()
if t.IsZero() {
d = 0
}
if err := fd.incref(); err != nil {
return err
}
runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
fd.decref()
return nil
}
|