libgo: update to go1.9
[official-gcc.git] / libgo / go / internal / poll / fd_io_plan9.go
blob287d11bd8c29f6a0bc46225183a669b06c03275e
1 // Copyright 2016 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.
5 package poll
7 import (
8 "runtime"
9 "sync"
10 "syscall"
13 // asyncIO implements asynchronous cancelable I/O.
14 // An asyncIO represents a single asynchronous Read or Write
15 // operation. The result is returned on the result channel.
16 // The undergoing I/O system call can either complete or be
17 // interrupted by a note.
18 type asyncIO struct {
19 res chan result
21 // mu guards the pid field.
22 mu sync.Mutex
24 // pid holds the process id of
25 // the process running the IO operation.
26 pid int
29 // result is the return value of a Read or Write operation.
30 type result struct {
31 n int
32 err error
35 // newAsyncIO returns a new asyncIO that performs an I/O
36 // operation by calling fn, which must do one and only one
37 // interruptible system call.
38 func newAsyncIO(fn func([]byte) (int, error), b []byte) *asyncIO {
39 aio := &asyncIO{
40 res: make(chan result, 0),
42 aio.mu.Lock()
43 go func() {
44 // Lock the current goroutine to its process
45 // and store the pid in io so that Cancel can
46 // interrupt it. We ignore the "hangup" signal,
47 // so the signal does not take down the entire
48 // Go runtime.
49 runtime.LockOSThread()
50 runtime_ignoreHangup()
51 aio.pid = syscall.Getpid()
52 aio.mu.Unlock()
54 n, err := fn(b)
56 aio.mu.Lock()
57 aio.pid = -1
58 runtime_unignoreHangup()
59 aio.mu.Unlock()
61 aio.res <- result{n, err}
62 }()
63 return aio
66 // Cancel interrupts the I/O operation, causing
67 // the Wait function to return.
68 func (aio *asyncIO) Cancel() {
69 aio.mu.Lock()
70 defer aio.mu.Unlock()
71 if aio.pid == -1 {
72 return
74 f, e := syscall.Open("/proc/"+itoa(aio.pid)+"/note", syscall.O_WRONLY)
75 if e != nil {
76 return
78 syscall.Write(f, []byte("hangup"))
79 syscall.Close(f)
82 // Wait for the I/O operation to complete.
83 func (aio *asyncIO) Wait() (int, error) {
84 res := <-aio.res
85 return res.n, res.err
88 // The following functions, provided by the runtime, are used to
89 // ignore and unignore the "hangup" signal received by the process.
90 func runtime_ignoreHangup()
91 func runtime_unignoreHangup()