github.com/weedge/lib@v0.0.0-20230424045628-a36dcc1d90e4/poller/netpoll/netpoll_kqueue.go (about)

     1  // +build darwin dragonfly freebsd netbsd openbsd
     2  
     3  package netpoll
     4  
     5  import (
     6  	"os"
     7  )
     8  
     9  // New creates new kqueue-based Poller instance with given config.
    10  func New(c *Config) (Poller, error) {
    11  	cfg := c.withDefaults()
    12  
    13  	kq, err := KqueueCreate(&KqueueConfig{
    14  		OnWaitError: cfg.OnWaitError,
    15  	})
    16  	if err != nil {
    17  		return nil, err
    18  	}
    19  
    20  	return poller{kq}, nil
    21  }
    22  
    23  type poller struct {
    24  	*Kqueue
    25  }
    26  
    27  func (p poller) Start(desc *Desc, cb CallbackFn) error {
    28  	n, events := toKevents(desc.event, true)
    29  	err := p.Add(desc.fd(), events, n, func(kev Kevent) {
    30  		var (
    31  			event Event
    32  
    33  			flags  = kev.Flags
    34  			filter = kev.Filter
    35  		)
    36  
    37  		// Set EventHup for any EOF flag. Below will be more precise detection
    38  		// of what exatcly HUP occured.
    39  		if flags&EV_EOF != 0 {
    40  			event |= EventHup
    41  		}
    42  
    43  		if filter == EVFILT_READ {
    44  			event |= EventRead
    45  			if flags&EV_EOF != 0 {
    46  				event |= EventReadHup
    47  			}
    48  		}
    49  		if filter == EVFILT_WRITE {
    50  			event |= EventWrite
    51  			if flags&EV_EOF != 0 {
    52  				event |= EventWriteHup
    53  			}
    54  		}
    55  		if flags&EV_ERROR != 0 {
    56  			event |= EventErr
    57  		}
    58  		if filter == _EVFILT_CLOSED {
    59  			event |= EventPollerClosed
    60  		}
    61  
    62  		cb(event)
    63  	})
    64  	if err == nil {
    65  		if err = setNonblock(desc.fd(), true); err != nil {
    66  			return os.NewSyscallError("setnonblock", err)
    67  		}
    68  	}
    69  	return err
    70  }
    71  
    72  func (p poller) Stop(desc *Desc) error {
    73  	n, events := toKevents(desc.event, false)
    74  	if err := p.Del(desc.fd()); err != nil {
    75  		return err
    76  	}
    77  	if err := p.Mod(desc.fd(), events, n); err != nil && err != ErrNotRegistered {
    78  		return err
    79  	}
    80  	return nil
    81  }
    82  
    83  func (p poller) Resume(desc *Desc) error {
    84  	n, events := toKevents(desc.event, true)
    85  	return p.Mod(desc.fd(), events, n)
    86  }
    87  
    88  func toKevents(event Event, add bool) (n int, ks Kevents) {
    89  	var flags KeventFlag
    90  	if add {
    91  		flags = EV_ADD
    92  		if event&EventOneShot != 0 {
    93  			flags |= EV_ONESHOT
    94  		}
    95  		if event&EventEdgeTriggered != 0 {
    96  			flags |= EV_CLEAR
    97  		}
    98  	} else {
    99  		flags = EV_DELETE
   100  	}
   101  	if event&EventRead != 0 {
   102  		ks[n].Flags = flags
   103  		ks[n].Filter = EVFILT_READ
   104  		n++
   105  	}
   106  	if event&EventWrite != 0 {
   107  		ks[n].Flags = flags
   108  		ks[n].Filter = EVFILT_WRITE
   109  		n++
   110  	}
   111  	return
   112  }