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