Fix memory leak and dead no-op wait in Lance streaming path#8
Fix memory leak and dead no-op wait in Lance streaming path#8Copilot wants to merge 2 commits intotsafin/lance_streamfrom
Conversation
…e::push() Co-authored-by: tsafin <4956130+tsafin@users.noreply.github.com>
|
@claude review |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ee95869d03
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| let reader = unsafe { ArrowArrayStreamReader::from_raw(stream_ptr) } | ||
| .map_err(|e| format!("Failed to import ArrowArrayStream: {}", e))?; | ||
| let result = unsafe { ArrowArrayStreamReader::from_raw(stream_ptr) }; | ||
| unsafe { libc::free(stream_ptr as *mut c_void) }; |
There was a problem hiding this comment.
Keep stream ownership single on import failure
start_stream now unconditionally calls libc::free(stream_ptr) before propagating from_raw errors, but the C++ caller still frees the same pointer when lance_writer_start_stream returns non-zero (src/writers/lance_writer.cpp:259-262). If ArrowArrayStreamReader::from_raw returns Err (e.g., invalid exported stream), this path double-frees the same allocation and can corrupt the heap or abort the process.
Useful? React with 👍 / 👎.
Two bugs identified by copilot-swe-agent in PR #8: - lib.rs: fix memory leak on ArrowArrayStreamReader::from_raw() failure. The original code called libc::free() after the ? early-return, so the malloc'd ArrowArrayStream struct leaked if from_raw() failed. Fix: free unconditionally before propagating the error. - lance_writer.cpp: remove dead no-op else branch in StreamState::push(). The else path (queue not full) called not_full_cv_.wait() with a predicate already satisfied, making it a guaranteed immediate return. Removing it clarifies the backpressure logic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
Both fixes incorporated into tsafin/lance_stream as commit f5142c6. Thank you for the review — the memory leak on from_raw() failure and the dead else branch are now fixed directly in our working branch. |
Two bugs identified by copilot-swe-agent in PR #8: - lib.rs: fix memory leak on ArrowArrayStreamReader::from_raw() failure. The original code called libc::free() after the ? early-return, so the malloc'd ArrowArrayStream struct leaked if from_raw() failed. Fix: free unconditionally before propagating the error. - lance_writer.cpp: remove dead no-op else branch in StreamState::push(). The else path (queue not full) called not_full_cv_.wait() with a predicate already satisfied, making it a guaranteed immediate return. Removing it clarifies the backpressure logic. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs in the Lance streaming write path identified during code review.
Changes
start_stream()(Rust) —libc::free()was called after the?early-return onArrowArrayStreamReader::from_raw()failure, leaving themalloc'dstream_ptrunreachable since C++ had already transferred ownership. Fixed by unconditionally freeing before propagating the error:elsebranch inStreamState::push()(C++) — theelsepath (queue has space) callednot_full_cv_.wait()with a predicate guaranteed satisfied immediately, since the mutex is held continuously from the top ofpush(). This was a no-op that obscured the backpressure logic. Removed the branch entirely.💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.