@@ -148,7 +148,7 @@ int ring_buffer__add(struct ring_buffer *rb, int map_fd,
148148 e = & rb -> events [rb -> ring_cnt ];
149149 memset (e , 0 , sizeof (* e ));
150150
151- e -> events = EPOLLIN ;
151+ e -> events = EPOLLIN | EPOLLET ;
152152 e -> data .fd = rb -> ring_cnt ;
153153 if (epoll_ctl (rb -> epoll_fd , EPOLL_CTL_ADD , map_fd , e ) < 0 ) {
154154 err = - errno ;
@@ -260,7 +260,19 @@ static int64_t ringbuf_process_ring(struct ring *r)
260260 cnt ++ ;
261261 }
262262
263- smp_store_release (r -> consumer_pos , cons_pos );
263+ /* This ordering is critical to ensure that an epoll
264+ * notification gets sent in the case where the next
265+ * iteration of this loop discovers that the consumer is
266+ * caught up. If this store were performed using
267+ * RELEASE, it'd be possible for the consumer to fail to
268+ * see an updated producer position and for that
269+ * producer to fail to see this write. By making this
270+ * write SEQ_CST, we know that either the newly produced
271+ * message will be visible to theconsumer, or the
272+ * producer will discover that the consumer is caught
273+ * up, and will ensure a notification is sent.
274+ */
275+ __atomic_store_n (r -> consumer_pos , cons_pos , __ATOMIC_SEQ_CST );
264276 }
265277 } while (got_new_data );
266278done :
0 commit comments