/// <summary> /// Explicitly frees this end of the channel. /// /// Since both threads on the channel could try to do this simultaneously, /// we use the ref counting on the underlying endpoints to let the last /// free operation (the one pulling the ref count to 0) to free the associated /// event. /// </summary> public unsafe static void Free(Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint) { // Use unchecked GetData here, since this may be called from the // cleanup threading running in the kernel. EndpointCore *ep = ((EndpointCore *)Allocation.GetDataUnchecked(endpoint)); if (ep->deliveryHandle != DeliveryHandle.Zero) { if (DeliveryHandle.Free(ep->deliveryHandle)) { Interlocked.Decrement(ref openChannelCount); } } else { // was never connected, just free this endpoint AutoResetEventHandle areHandle = ep->cachedMessageEvent; SharedHeap.KernelSharedHeap.Free(endpoint, SharedHeap.CurrentProcessSharedHeap.EndpointPeerOwnerId); if (areHandle.id != UIntPtr.Zero) { Process.kernelProcess.ReleaseHandle(areHandle.id); } } }
internal static DeliveryImpl AllocationEndpointDeliveryImplUnchecked( Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint) { EndpointCore *ep = (EndpointCore *)Allocation.GetDataUnchecked(endpoint); if (ep == null) { return(null); } else { return(ep->EndpointDeliveryImpl); } }