Skip to content

Return shared ArrayPool #459

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 23, 2025
Merged

Return shared ArrayPool #459

merged 5 commits into from
Jun 23, 2025

Conversation

shargon
Copy link
Contributor

@shargon shargon commented Jun 18, 2025

Rent byte arrays should be returned

jsquire
jsquire previously approved these changes Jun 22, 2025
Copy link
Collaborator

@jsquire jsquire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @shargon. Thank you for your contribution and interest in improving the OpenAI developer experience. Thanks for catching these, as these appear to be legitimate leaks to me.

@joseharriaga: This looks to be a clean fix that is safe to make here. Can you please confirm and, if so, complete the merge after the requested pattern change?

@jsquire jsquire dismissed their stale review June 22, 2025 18:47

Intended to just add a comment, as a pattern adjustment was requested.

Copy link
Collaborator

@jsquire jsquire left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @shargon! I touched base with @joseharriaga earlier and confirmed that this won't cause issues with in-flight work upstream. Merging.

@jsquire jsquire merged commit c03dc6c into openai:main Jun 23, 2025
1 check passed
@@ -26,6 +26,7 @@ public AsyncWebsocketMessageResultEnumerator(WebSocket webSocket, CancellationTo

public ValueTask DisposeAsync()
{
ArrayPool<byte>.Shared.Return(_receiveBuffer);
Copy link
Contributor

@stephentoub stephentoub Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If disposal is performed multiple times, this will end up returning the buffer multiple times. That needs to be fixed, assuming this enumerator can be returned out to user code.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is on me, as I was under the impression that it was safe to return multiple times. However, looks like I'm incorrect.

Copy link
Contributor

@stephentoub stephentoub Jun 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This use of ArrayPool looks dangerous in general. The enumerator is yielding references to this array. If the consumer holds on to those yielded elements after disposal and reads from them (which is technically fine for them to do), that's a use-after-free bug.

I think the right answer here is to stop using ArrayPool here, i.e. revert the addition of the Return and change the Rent to just be a normal allocation. That won't be any worse than the state of allocation today because the array was already not being returned. If in the future perf problems demonstrate pooling is important, it can be re-evaluated holistically.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, it may not be as bad as I feared... tracing through where _recieveBuffer goes, it looks like it may not actually be stored into the yielded object but instead just having its data copied out? If so, using an ArrayPool array would be ok. But we still want to ensure it's only returned to the pool once.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filed #474 for investigation.

}
finally
{
ArrayPool<byte>.Shared.Return(bytes);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is OK. FWIW, though, we generally don't consider it a bug to not return an ArrayPool array in exceptional situations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants