gcc/libgo/go/net/fd_io_plan9.go
Ian Lance Taylor c2047754c3 libgo: update to Go 1.8 release candidate 1
Compiler changes:
      * Change map assignment to use mapassign and assign value directly.
      * Change string iteration to use decoderune, faster for ASCII strings.
      * Change makeslice to take int, and use makeslice64 for larger values.
      * Add new noverflow field to hmap struct used for maps.
    
    Unresolved problems, to be fixed later:
      * Commented out test in go/types/sizes_test.go that doesn't compile.
      * Commented out reflect.TestStructOf test for padding after zero-sized field.
    
    Reviewed-on: https://go-review.googlesource.com/35231

gotools/:
	Updates for Go 1.8rc1.
	* Makefile.am (go_cmd_go_files): Add bug.go.
	(s-zdefaultcc): Write defaultPkgConfig.
	* Makefile.in: Rebuild.

From-SVN: r244456
2017-01-14 00:05:42 +00:00

94 lines
2.1 KiB
Go

// Copyright 2016 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.
package net
import (
"os"
"runtime"
"sync"
"syscall"
)
// asyncIO implements asynchronous cancelable I/O.
// An asyncIO represents a single asynchronous Read or Write
// operation. The result is returned on the result channel.
// The undergoing I/O system call can either complete or be
// interrupted by a note.
type asyncIO struct {
res chan result
// mu guards the pid field.
mu sync.Mutex
// pid holds the process id of
// the process running the IO operation.
pid int
}
// result is the return value of a Read or Write operation.
type result struct {
n int
err error
}
// newAsyncIO returns a new asyncIO that performs an I/O
// operation by calling fn, which must do one and only one
// interruptible system call.
func newAsyncIO(fn func([]byte) (int, error), b []byte) *asyncIO {
aio := &asyncIO{
res: make(chan result, 0),
}
aio.mu.Lock()
go func() {
// Lock the current goroutine to its process
// and store the pid in io so that Cancel can
// interrupt it. We ignore the "hangup" signal,
// so the signal does not take down the entire
// Go runtime.
runtime.LockOSThread()
runtime_ignoreHangup()
aio.pid = os.Getpid()
aio.mu.Unlock()
n, err := fn(b)
aio.mu.Lock()
aio.pid = -1
runtime_unignoreHangup()
aio.mu.Unlock()
aio.res <- result{n, err}
}()
return aio
}
var hangupNote os.Signal = syscall.Note("hangup")
// Cancel interrupts the I/O operation, causing
// the Wait function to return.
func (aio *asyncIO) Cancel() {
aio.mu.Lock()
defer aio.mu.Unlock()
if aio.pid == -1 {
return
}
proc, err := os.FindProcess(aio.pid)
if err != nil {
return
}
proc.Signal(hangupNote)
}
// Wait for the I/O operation to complete.
func (aio *asyncIO) Wait() (int, error) {
res := <-aio.res
return res.n, res.err
}
// The following functions, provided by the runtime, are used to
// ignore and unignore the "hangup" signal received by the process.
func runtime_ignoreHangup()
func runtime_unignoreHangup()