Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

simplify PreAllocatedOverlapped lifetime management#10302

Closed
geoffkizer wants to merge 1 commit intodotnet:masterfrom
geoffkizer:preallocatedoverlapped
Closed

simplify PreAllocatedOverlapped lifetime management#10302
geoffkizer wants to merge 1 commit intodotnet:masterfrom
geoffkizer:preallocatedoverlapped

Conversation

@geoffkizer
Copy link

PreAllocatedOverlapped has some lifetime management state/logic that is not used in practice. Remove this.

On my socket microbenchmark, this seems to give a small win (1-1.5%), though it may be noise.

@jkotas @stephentoub

@jkotas
Copy link
Member

jkotas commented Mar 20, 2017

This logic you are removing seems to be protecting against finalization races. I do not understand this well enough to tell whether it is ok remove it.

/// Frees the resources associated with this <see cref="PreAllocatedOverlapped"/> instance.
/// </summary>
public unsafe void Dispose()
unsafe void Dispose(bool disposing)
Copy link
Member

Choose a reason for hiding this comment

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

Nit: private

/// </summary>
/// <seealso cref="ThreadPoolBoundHandle.AllocateNativeOverlapped(PreAllocatedOverlapped)"/>
public sealed class PreAllocatedOverlapped : IDisposable, IDeferredDisposable
public sealed class PreAllocatedOverlapped : IDisposable
Copy link
Member

Choose a reason for hiding this comment

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

You can delete IDeferredDisposable and DeferredDisposableLifetime as well.

@stephentoub
Copy link
Member

stephentoub commented Mar 20, 2017

@geoffkizer, from a quick read, it appears that logic is protecting against Dispose'ing a PreAllocatedOverlapped while a NativeOverlapped created from it is still in use (similar to SafeHandle deferring its disposal until all outstanding ref counts from P/Invokes and other Dangerous usage have completed). We don't care about that?

@geoffkizer
Copy link
Author

Yeah, I pushed this too quickly.

We don't care about deferred dispose in Sockets because we already manage the deferred dispose ourselves. But since this is public, other uses may care.

We don't need full AddRef/Release, since AddRef is not exposed and is never called internally except from AllocateNativeOverlapped. But to handle deferred dispose, we do need to distinguish between in-use and not in use.

I'll take another look at this.

@geoffkizer
Copy link
Author

BTW, the more general issue here is that the way the PreAllocatedOverlapped-related APIs work is not great from a perf point of view -- there's a nontrivial amount of overhead in AllocateNativeOverlapped and FreeNativeOverlapped.

In the Socket code, we are explicitly managing the lifetime and state of the overlapped object ourselves. All we really want is a way to say "please reset the state on this overlapped so we can use it again". This should be cheap in theory.

@geoffkizer
Copy link
Author

Closing for now. I will revisit later.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants