diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
commit | f154da9e12608589e8d5f0508f908a0c3e88a1bb (patch) | |
tree | f8255d51e10c6f1e0ed69702200b966c9556a431 /src/net/fd_poll_runtime.go | |
parent | 8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff) | |
download | golang-upstream/1.4.tar.gz |
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/net/fd_poll_runtime.go')
-rw-r--r-- | src/net/fd_poll_runtime.go | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/net/fd_poll_runtime.go b/src/net/fd_poll_runtime.go new file mode 100644 index 000000000..2bddc836c --- /dev/null +++ b/src/net/fd_poll_runtime.go @@ -0,0 +1,144 @@ +// Copyright 2013 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. + +// +build darwin dragonfly freebsd linux netbsd openbsd windows solaris + +package net + +import ( + "sync" + "syscall" + "time" +) + +// runtimeNano returns the current value of the runtime clock in nanoseconds. +func runtimeNano() int64 + +func runtime_pollServerInit() +func runtime_pollOpen(fd uintptr) (uintptr, int) +func runtime_pollClose(ctx uintptr) +func runtime_pollWait(ctx uintptr, mode int) int +func runtime_pollWaitCanceled(ctx uintptr, mode int) int +func runtime_pollReset(ctx uintptr, mode int) int +func runtime_pollSetDeadline(ctx uintptr, d int64, mode int) +func runtime_pollUnblock(ctx uintptr) + +type pollDesc struct { + runtimeCtx uintptr +} + +var serverInit sync.Once + +func (pd *pollDesc) Init(fd *netFD) error { + serverInit.Do(runtime_pollServerInit) + ctx, errno := runtime_pollOpen(uintptr(fd.sysfd)) + if errno != 0 { + return syscall.Errno(errno) + } + pd.runtimeCtx = ctx + return nil +} + +func (pd *pollDesc) Close() { + if pd.runtimeCtx == 0 { + return + } + runtime_pollClose(pd.runtimeCtx) + pd.runtimeCtx = 0 +} + +func (pd *pollDesc) Lock() { +} + +func (pd *pollDesc) Unlock() { +} + +func (pd *pollDesc) Wakeup() { +} + +// Evict evicts fd from the pending list, unblocking any I/O running on fd. +// Return value is whether the pollServer should be woken up. +func (pd *pollDesc) Evict() bool { + if pd.runtimeCtx == 0 { + return false + } + runtime_pollUnblock(pd.runtimeCtx) + return false +} + +func (pd *pollDesc) Prepare(mode int) error { + res := runtime_pollReset(pd.runtimeCtx, mode) + return convertErr(res) +} + +func (pd *pollDesc) PrepareRead() error { + return pd.Prepare('r') +} + +func (pd *pollDesc) PrepareWrite() error { + return pd.Prepare('w') +} + +func (pd *pollDesc) Wait(mode int) error { + res := runtime_pollWait(pd.runtimeCtx, mode) + return convertErr(res) +} + +func (pd *pollDesc) WaitRead() error { + return pd.Wait('r') +} + +func (pd *pollDesc) WaitWrite() error { + return pd.Wait('w') +} + +func (pd *pollDesc) WaitCanceled(mode int) { + runtime_pollWaitCanceled(pd.runtimeCtx, mode) +} + +func (pd *pollDesc) WaitCanceledRead() { + pd.WaitCanceled('r') +} + +func (pd *pollDesc) WaitCanceledWrite() { + pd.WaitCanceled('w') +} + +func convertErr(res int) error { + switch res { + case 0: + return nil + case 1: + return errClosing + case 2: + return errTimeout + } + println("unreachable: ", res) + panic("unreachable") +} + +func (fd *netFD) setDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'r'+'w') +} + +func (fd *netFD) setReadDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'r') +} + +func (fd *netFD) setWriteDeadline(t time.Time) error { + return setDeadlineImpl(fd, t, 'w') +} + +func setDeadlineImpl(fd *netFD, t time.Time, mode int) error { + d := runtimeNano() + int64(t.Sub(time.Now())) + if t.IsZero() { + d = 0 + } + if err := fd.incref(); err != nil { + return err + } + runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode) + fd.decref() + return nil +} |