...
1
2
3
4
5 package poll
6
7 import (
8 "internal/itoa"
9 "runtime"
10 "sync"
11 "syscall"
12 )
13
14
15
16
17
18
19 type asyncIO struct {
20 res chan result
21
22
23 mu sync.Mutex
24
25
26
27 pid int
28 }
29
30
31 type result struct {
32 n int
33 err error
34 }
35
36
37
38
39 func newAsyncIO(fn func([]byte) (int, error), b []byte) *asyncIO {
40 aio := &asyncIO{
41 res: make(chan result, 0),
42 }
43 aio.mu.Lock()
44 go func() {
45
46
47
48
49
50 runtime.LockOSThread()
51 runtime_ignoreHangup()
52 aio.pid = syscall.Getpid()
53 aio.mu.Unlock()
54
55 n, err := fn(b)
56
57 aio.mu.Lock()
58 aio.pid = -1
59 runtime_unignoreHangup()
60 aio.mu.Unlock()
61
62 aio.res <- result{n, err}
63 }()
64 return aio
65 }
66
67
68
69 func (aio *asyncIO) Cancel() {
70 aio.mu.Lock()
71 defer aio.mu.Unlock()
72 if aio.pid == -1 {
73 return
74 }
75 f, e := syscall.Open("/proc/"+itoa.Itoa(aio.pid)+"/note", syscall.O_WRONLY)
76 if e != nil {
77 return
78 }
79 syscall.Write(f, []byte("hangup"))
80 syscall.Close(f)
81 }
82
83
84 func (aio *asyncIO) Wait() (int, error) {
85 res := <-aio.res
86 return res.n, res.err
87 }
88
89
90
91 func runtime_ignoreHangup()
92 func runtime_unignoreHangup()
93
View as plain text