diff --git a/libcuframes/src/consumer.c b/libcuframes/src/consumer.c index 02f46c1..595cba4 100644 --- a/libcuframes/src/consumer.c +++ b/libcuframes/src/consumer.c @@ -290,6 +290,17 @@ int cuframes_subscriber_next(cuframes_subscriber_t *sub, if (cerr != cudaSuccess) return CUFRAMES_ERR_CUDA; } + /* TOCTOU защита: producer_event signal'ит для последнего published + * frame, не per-slot. Если producer wrapped ring пока мы ждали + * event sync, slot[slot_idx] уже содержит DIFFERENT seq. + * Re-verify slot_seq — если изменился, retry с новым target_seq. */ + uint64_t verify_seq = atomic_load_explicit(&sub->hdr->slots[slot_idx].seq, + memory_order_acquire); + if (verify_seq != target_seq) { + /* Slot overwritten во время event wait — outer loop пересчитает */ + continue; + } + /* Fill frame_out */ struct cuframes_frame *f = &sub->frame_obj; f->cuda_ptr = sub->mapped_ptrs[slot_idx];