github.com/cbeuw/gotfo@v0.0.0-20180331191851-f2b091af84de/fd_poll_runtime.go (about)

     1  package gotfo
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  )
     7  
     8  func (pd *pollDesc) close() {
     9  	if pd.runtimeCtx == 0 {
    10  		return
    11  	}
    12  	runtime_pollClose(pd.runtimeCtx)
    13  	pd.runtimeCtx = 0
    14  }
    15  
    16  // Evict evicts fd from the pending list, unblocking any I/O running on fd.
    17  func (pd *pollDesc) evict() {
    18  	if pd.runtimeCtx == 0 {
    19  		return
    20  	}
    21  	runtime_pollUnblock(pd.runtimeCtx)
    22  }
    23  
    24  func (pd *pollDesc) prepare(mode int) error {
    25  	if pd.runtimeCtx == 0 {
    26  		return nil
    27  	}
    28  	res := runtime_pollReset(pd.runtimeCtx, mode)
    29  	return convertErr(res)
    30  }
    31  
    32  func (pd *pollDesc) prepareRead(isFile bool) error {
    33  	return pd.prepare('r')
    34  }
    35  
    36  func (pd *pollDesc) prepareWrite(isFile bool) error {
    37  	return pd.prepare('w')
    38  }
    39  
    40  func (pd *pollDesc) wait(mode int) error {
    41  	if pd.runtimeCtx == 0 {
    42  		return errors.New("waiting for unsupported file type")
    43  	}
    44  	res := runtime_pollWait(pd.runtimeCtx, mode)
    45  	return convertErr(res)
    46  }
    47  
    48  func (pd *pollDesc) waitRead() error {
    49  	return pd.wait('r')
    50  }
    51  
    52  func (pd *pollDesc) waitWrite() error {
    53  	return pd.wait('w')
    54  }
    55  
    56  func (pd *pollDesc) waitCanceled(mode int) {
    57  	if pd.runtimeCtx == 0 {
    58  		return
    59  	}
    60  	runtime_pollWaitCanceled(pd.runtimeCtx, mode)
    61  }
    62  
    63  func (pd *pollDesc) pollable() bool {
    64  	return pd.runtimeCtx != 0
    65  }
    66  
    67  func convertErr(res int) error {
    68  	switch res {
    69  	case 0:
    70  		return nil
    71  	case 1:
    72  		return errClosing
    73  	case 2:
    74  		return errTimeout
    75  	}
    76  	println("unreachable: ", res)
    77  	panic("unreachable")
    78  }
    79  
    80  // SetDeadline sets the read and write deadlines associated with fd.
    81  func (fd *netFD) SetDeadline(t time.Time) error {
    82  	return setDeadlineImpl(fd, t, 'r'+'w')
    83  }
    84  
    85  // SetReadDeadline sets the read deadline associated with fd.
    86  func (fd *netFD) SetReadDeadline(t time.Time) error {
    87  	return setDeadlineImpl(fd, t, 'r')
    88  }
    89  
    90  // SetWriteDeadline sets the write deadline associated with fd.
    91  func (fd *netFD) SetWriteDeadline(t time.Time) error {
    92  	return setDeadlineImpl(fd, t, 'w')
    93  }
    94  
    95  func setDeadlineImpl(fd *netFD, t time.Time, mode int) error {
    96  	diff := int64(time.Until(t))
    97  	d := runtimeNano() + diff
    98  	if d <= 0 && diff > 0 {
    99  		// If the user has a deadline in the future, but the delay calculation
   100  		// overflows, then set the deadline to the maximum possible value.
   101  		d = 1<<63 - 1
   102  	}
   103  	if t.IsZero() {
   104  		d = 0
   105  	}
   106  	if err := fd.incref(); err != nil {
   107  		return err
   108  	}
   109  
   110  	// https://github.com/golang/go/commit/3813f941f6ff80f64d14db35f8b6446e10e45411#diff-2fac41fb57b6d5728ad14f6115f7219b
   111  	defer fd.decref()
   112  	if fd.pd.runtimeCtx == 0 {
   113  		return errors.New("file type does not support deadlines")
   114  	}
   115  	runtime_pollSetDeadline(fd.pd.runtimeCtx, d, mode)
   116  	return nil
   117  }