2017-03-02 Richard Biener <rguenther@suse.de>
[official-gcc.git] / libgo / go / net / fd_poll_runtime.go
blob62b69fcbf150541304db4f6c116969ac82ddd3ad
1 // Copyright 2013 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 // +build darwin dragonfly freebsd linux netbsd openbsd windows solaris
7 package net
9 import (
10 "runtime"
11 "sync"
12 "syscall"
13 "time"
16 // runtimeNano returns the current value of the runtime clock in nanoseconds.
17 func runtimeNano() int64
19 func runtime_pollServerInit()
20 func runtime_pollOpen(fd uintptr) (uintptr, int)
21 func runtime_pollClose(ctx uintptr)
22 func runtime_pollWait(ctx uintptr, mode int) int
23 func runtime_pollWaitCanceled(ctx uintptr, mode int) int
24 func runtime_pollReset(ctx uintptr, mode int) int
25 func runtime_pollSetDeadline(ctx uintptr, d int64, mode int)
26 func runtime_pollUnblock(ctx uintptr)
28 type pollDesc struct {
29 runtimeCtx uintptr
32 var serverInit sync.Once
34 func (pd *pollDesc) init(fd *netFD) error {
35 serverInit.Do(runtime_pollServerInit)
36 ctx, errno := runtime_pollOpen(uintptr(fd.sysfd))
37 runtime.KeepAlive(fd)
38 if errno != 0 {
39 return syscall.Errno(errno)
41 pd.runtimeCtx = ctx
42 return nil
45 func (pd *pollDesc) close() {
46 if pd.runtimeCtx == 0 {
47 return
49 runtime_pollClose(pd.runtimeCtx)
50 pd.runtimeCtx = 0
53 // Evict evicts fd from the pending list, unblocking any I/O running on fd.
54 func (pd *pollDesc) evict() {
55 if pd.runtimeCtx == 0 {
56 return
58 runtime_pollUnblock(pd.runtimeCtx)
61 func (pd *pollDesc) prepare(mode int) error {
62 res := runtime_pollReset(pd.runtimeCtx, mode)
63 return convertErr(res)
66 func (pd *pollDesc) prepareRead() error {
67 return pd.prepare('r')
70 func (pd *pollDesc) prepareWrite() error {
71 return pd.prepare('w')
74 func (pd *pollDesc) wait(mode int) error {
75 res := runtime_pollWait(pd.runtimeCtx, mode)
76 return convertErr(res)
79 func (pd *pollDesc) waitRead() error {
80 return pd.wait('r')
83 func (pd *pollDesc) waitWrite() error {
84 return pd.wait('w')
87 func (pd *pollDesc) waitCanceled(mode int) {
88 runtime_pollWaitCanceled(pd.runtimeCtx, mode)
91 func (pd *pollDesc) waitCanceledRead() {
92 pd.waitCanceled('r')
95 func (pd *pollDesc) waitCanceledWrite() {
96 pd.waitCanceled('w')
99 func convertErr(res int) error {
100 switch res {
101 case 0:
102 return nil
103 case 1:
104 return errClosing
105 case 2:
106 return errTimeout
108 println("unreachable: ", res)
109 panic("unreachable")
112 func (fd *netFD) setDeadline(t time.Time) error {
113 return setDeadlineImpl(fd, t, 'r'+'w')
116 func (fd *netFD) setReadDeadline(t time.Time) error {
117 return setDeadlineImpl(fd, t, 'r')
120 func (fd *netFD) setWriteDeadline(t time.Time) error {
121 return setDeadlineImpl(fd, t, 'w')
124 func setDeadlineImpl(fd *netFD, t time.Time, mode int) error {
125 diff := int64(time.Until(t))
126 d := runtimeNano() + diff
127 if d <= 0 && diff > 0 {
128 // If the user has a deadline in the future, but the delay calculation
129 // overflows, then set the deadline to the maximum possible value.
130 d = 1<<63 - 1
132 if t.IsZero() {
133 d = 0
135 if err := fd.incref(); err != nil {
136 return err
138 runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
139 fd.decref()
140 return nil