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.
4
5package net
6
7import (
8	"syscall"
9	"time"
10)
11
12type pollDesc struct {
13	fd      *netFD
14	closing bool
15}
16
17func (pd *pollDesc) Init(fd *netFD) error { pd.fd = fd; return nil }
18
19func (pd *pollDesc) Close() {}
20
21func (pd *pollDesc) Evict() {
22	pd.closing = true
23	if pd.fd != nil {
24		syscall.StopIO(pd.fd.sysfd)
25	}
26}
27
28func (pd *pollDesc) Prepare(mode int) error {
29	if pd.closing {
30		return errClosing
31	}
32	return nil
33}
34
35func (pd *pollDesc) PrepareRead() error { return pd.Prepare('r') }
36
37func (pd *pollDesc) PrepareWrite() error { return pd.Prepare('w') }
38
39func (pd *pollDesc) Wait(mode int) error {
40	if pd.closing {
41		return errClosing
42	}
43	return errTimeout
44}
45
46func (pd *pollDesc) WaitRead() error { return pd.Wait('r') }
47
48func (pd *pollDesc) WaitWrite() error { return pd.Wait('w') }
49
50func (pd *pollDesc) WaitCanceled(mode int) {}
51
52func (pd *pollDesc) WaitCanceledRead() {}
53
54func (pd *pollDesc) WaitCanceledWrite() {}
55
56func (fd *netFD) setDeadline(t time.Time) error {
57	return setDeadlineImpl(fd, t, 'r'+'w')
58}
59
60func (fd *netFD) setReadDeadline(t time.Time) error {
61	return setDeadlineImpl(fd, t, 'r')
62}
63
64func (fd *netFD) setWriteDeadline(t time.Time) error {
65	return setDeadlineImpl(fd, t, 'w')
66}
67
68func setDeadlineImpl(fd *netFD, t time.Time, mode int) error {
69	d := t.UnixNano()
70	if t.IsZero() {
71		d = 0
72	}
73	if err := fd.incref(); err != nil {
74		return err
75	}
76	switch mode {
77	case 'r':
78		syscall.SetReadDeadline(fd.sysfd, d)
79	case 'w':
80		syscall.SetWriteDeadline(fd.sysfd, d)
81	case 'r' + 'w':
82		syscall.SetReadDeadline(fd.sysfd, d)
83		syscall.SetWriteDeadline(fd.sysfd, d)
84	}
85	fd.decref()
86	return nil
87}
88