Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
lmb committed Dec 14, 2021
1 parent 7d37711 commit 26fab34
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 16 deletions.
12 changes: 11 additions & 1 deletion internal/epoll/poller.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package epoll

import (
"errors"
"fmt"
"math"
"os"
"runtime"
"sync"
"time"

"github.com/cilium/ebpf/internal"
"github.com/cilium/ebpf/internal/unix"
Expand Down Expand Up @@ -119,7 +121,7 @@ func (p *Poller) Add(fd int, id int) error {
//
// Returns the number of pending events or an error wrapping os.ErrClosed if
// Close is called.
func (p *Poller) Wait(events []unix.EpollEvent, msec int) (int, error) {
func (p *Poller) Wait(events []unix.EpollEvent, deadline time.Time) (int, error) {
p.epollMu.Lock()
defer p.epollMu.Unlock()

Expand All @@ -128,7 +130,15 @@ func (p *Poller) Wait(events []unix.EpollEvent, msec int) (int, error) {
}

for {
msec := int(-1)
if !deadline.IsZero() {
msec = int(time.Until(deadline).Milliseconds())
}

n, err := unix.EpollWait(p.epollFd, events, msec)
if errors.Is(err, unix.EINTR) {
return 0, os.ErrDeadlineExceeded
}
if temp, ok := err.(temporaryError); ok && temp.Temporary() {
// Retry the syscall if we were interrupted, see https://github.com/golang/go/issues/20400
continue
Expand Down
21 changes: 6 additions & 15 deletions perf/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -267,35 +267,26 @@ func (pr *Reader) Close() error {
//
// Calling Close interrupts the function.
func (pr *Reader) Read() (Record, error) {
return pr.read(-1)
return pr.read(time.Time{})
}

// ReadTimeout is Read but will time out and return os.ErrDeadlineExceeded
// ReadDeadline is Read but will time out and return os.ErrDeadlineExceeded
// if the timeout expires.
func (pr *Reader) ReadTimeout(timeout time.Duration) (Record, error) {
if timeout > 0 && timeout < time.Millisecond {
return Record{}, fmt.Errorf("non-zero timeout too small")
}

return pr.read(timeout)
func (pr *Reader) ReadDeadline(deadline time.Time) (Record, error) {
return pr.read(deadline)
}

func (pr *Reader) read(timeout time.Duration) (Record, error) {
func (pr *Reader) read(deadline time.Time) (Record, error) {
pr.mu.Lock()
defer pr.mu.Unlock()

if pr.rings == nil {
return Record{}, fmt.Errorf("perf ringbuffer: %w", ErrClosed)
}

msec := int(timeout.Milliseconds())
if timeout == -1 {
msec = -1
}

for {
if len(pr.epollRings) == 0 {
nEvents, err := pr.poller.Wait(pr.epollEvents, msec)
nEvents, err := pr.poller.Wait(pr.epollEvents, deadline)
if err != nil {
return Record{}, err
}
Expand Down

0 comments on commit 26fab34

Please sign in to comment.