| | |
| | |
| | |
| |
|
| | |
| |
|
| | package poll |
| |
|
| | import ( |
| | "errors" |
| | "sync" |
| | "syscall" |
| | "time" |
| | _ "unsafe" |
| | ) |
| |
|
| | |
| | |
| | |
| | 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) |
| | func runtime_pollReset(ctx uintptr, mode int) int |
| | func runtime_pollSetDeadline(ctx uintptr, d int64, mode int) |
| | func runtime_pollUnblock(ctx uintptr) |
| | func runtime_isPollServerDescriptor(fd uintptr) bool |
| |
|
| | type pollDesc struct { |
| | runtimeCtx uintptr |
| | } |
| |
|
| | var serverInit sync.Once |
| |
|
| | func (pd *pollDesc) init(fd *FD) error { |
| | serverInit.Do(runtime_pollServerInit) |
| | ctx, errno := runtime_pollOpen(uintptr(fd.Sysfd)) |
| | if errno != 0 { |
| | return errnoErr(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) evict() { |
| | if pd.runtimeCtx == 0 { |
| | return |
| | } |
| | runtime_pollUnblock(pd.runtimeCtx) |
| | } |
| |
|
| | func (pd *pollDesc) prepare(mode int, isFile bool) error { |
| | if pd.runtimeCtx == 0 { |
| | return nil |
| | } |
| | res := runtime_pollReset(pd.runtimeCtx, mode) |
| | return convertErr(res, isFile) |
| | } |
| |
|
| | func (pd *pollDesc) prepareRead(isFile bool) error { |
| | return pd.prepare('r', isFile) |
| | } |
| |
|
| | func (pd *pollDesc) prepareWrite(isFile bool) error { |
| | return pd.prepare('w', isFile) |
| | } |
| |
|
| | func (pd *pollDesc) wait(mode int, isFile bool) error { |
| | if pd.runtimeCtx == 0 { |
| | return errors.New("waiting for unsupported file type") |
| | } |
| | res := runtime_pollWait(pd.runtimeCtx, mode) |
| | return convertErr(res, isFile) |
| | } |
| |
|
| | func (pd *pollDesc) waitRead(isFile bool) error { |
| | return pd.wait('r', isFile) |
| | } |
| |
|
| | func (pd *pollDesc) waitWrite(isFile bool) error { |
| | return pd.wait('w', isFile) |
| | } |
| |
|
| | func (pd *pollDesc) waitCanceled(mode int) { |
| | if pd.runtimeCtx == 0 { |
| | return |
| | } |
| | runtime_pollWaitCanceled(pd.runtimeCtx, mode) |
| | } |
| |
|
| | func (pd *pollDesc) pollable() bool { |
| | return pd.runtimeCtx != 0 |
| | } |
| |
|
| | |
| | |
| | const ( |
| | pollNoError = 0 |
| | pollErrClosing = 1 |
| | pollErrTimeout = 2 |
| | pollErrNotPollable = 3 |
| | ) |
| |
|
| | func convertErr(res int, isFile bool) error { |
| | switch res { |
| | case pollNoError: |
| | return nil |
| | case pollErrClosing: |
| | return errClosing(isFile) |
| | case pollErrTimeout: |
| | return ErrDeadlineExceeded |
| | case pollErrNotPollable: |
| | return ErrNotPollable |
| | } |
| | println("unreachable: ", res) |
| | panic("unreachable") |
| | } |
| |
|
| | |
| | func (fd *FD) SetDeadline(t time.Time) error { |
| | return setDeadlineImpl(fd, t, 'r'+'w') |
| | } |
| |
|
| | |
| | func (fd *FD) SetReadDeadline(t time.Time) error { |
| | return setDeadlineImpl(fd, t, 'r') |
| | } |
| |
|
| | |
| | func (fd *FD) SetWriteDeadline(t time.Time) error { |
| | return setDeadlineImpl(fd, t, 'w') |
| | } |
| |
|
| | func setDeadlineImpl(fd *FD, t time.Time, mode int) error { |
| | var d int64 |
| | if !t.IsZero() { |
| | d = int64(time.Until(t)) |
| | if d == 0 { |
| | d = -1 |
| | } |
| | } |
| | if err := fd.incref(); err != nil { |
| | return err |
| | } |
| | defer fd.decref() |
| |
|
| | if fd.pd.runtimeCtx == 0 { |
| | return ErrNoDeadline |
| | } |
| | runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode) |
| | return nil |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | func IsPollDescriptor(fd uintptr) bool { |
| | return runtime_isPollServerDescriptor(fd) |
| | } |
| |
|