@@ -9,26 +9,27 @@ import "C"
99import (
1010 "fmt"
1111 "sync"
12+ "sync/atomic"
1213 "syscall"
14+ "unsafe"
1315)
1416
1517//
1618// RingBuffer
1719//
1820
1921type RingBuffer struct {
20- rb * C.struct_ring_buffer
21- bpfMap * BPFMap
22- slots []uint
23- stop chan struct {}
24- closed bool
25- wg sync. WaitGroup
22+ rb * C.struct_ring_buffer
23+ bpfMap * BPFMap
24+ slots []uint
25+ closed bool
26+ wg sync. WaitGroup
27+ stopFlag uint32 // use with atomic operations
2628}
2729
2830// Poll will wait until timeout in milliseconds to gather
2931// data from the ring buffer.
3032func (rb * RingBuffer ) Poll (timeout int ) {
31- rb .stop = make (chan struct {})
3233 rb .wg .Add (1 )
3334 go rb .poll (timeout )
3435}
@@ -39,12 +40,12 @@ func (rb *RingBuffer) Start() {
3940}
4041
4142func (rb * RingBuffer ) Stop () {
42- if rb .stop == nil {
43+ if atomic . LoadUint32 ( & rb .stopFlag ) == 1 {
4344 return
4445 }
4546
4647 // Signal the poll goroutine to exit
47- close ( rb .stop )
48+ atomic . StoreUint32 ( & rb .stopFlag , 1 )
4849
4950 // The event channel should be drained here since the consumer
5051 // may have stopped at this point. Failure to drain it will
@@ -69,9 +70,6 @@ func (rb *RingBuffer) Stop() {
6970 eventChan := eventChannels .get (slot ).(chan []byte )
7071 close (eventChan )
7172 }
72-
73- // Reset pb.stop to allow multiple safe calls to Stop()
74- rb .stop = nil
7573}
7674
7775func (rb * RingBuffer ) Close () {
@@ -87,32 +85,13 @@ func (rb *RingBuffer) Close() {
8785 rb .closed = true
8886}
8987
90- func (rb * RingBuffer ) isStopped () bool {
91- select {
92- case <- rb .stop :
93- return true
94- default :
95- return false
96- }
97- }
98-
9988func (rb * RingBuffer ) poll (timeout int ) error {
10089 defer rb .wg .Done ()
10190
102- for {
103- retC := C .ring_buffer__poll (rb .rb , C .int (timeout ))
104- if rb .isStopped () {
105- break
106- }
107-
108- if retC < 0 {
109- errno := syscall .Errno (- retC )
110- if errno == syscall .EINTR {
111- continue
112- }
113-
114- return fmt .Errorf ("error polling ring buffer: %w" , errno )
115- }
91+ stopFlag := (* C .uint32_t )(unsafe .Pointer (& rb .stopFlag ))
92+ ret := C .cgo_ring_buffer__poll (rb .rb , C .int (timeout ), stopFlag )
93+ if ret < 0 {
94+ return fmt .Errorf ("error polling perf buffer: %w" , syscall .Errno (- ret ))
11695 }
11796
11897 return nil
0 commit comments