/// <summary> /// Explicitly frees this end of the channel. If other end is also /// freed, the channel is deallocated, meaning we have to deallocate /// the kernel handles for the auto reset events. /// 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> internal static bool Free(SingleAddrSpaceDelivery dm) { Tracing.Log(Tracing.Debug, "Freeing endpoint {0:x8} of deliveryImpl type:" + ImplName, (UIntPtr)dm.endpointAlloc); bool isExp = (dm.endpoint->ChannelId > 0); bool peerFreed = false; bool meFreed = false; if (dm.Peer() != null) { // release our ref count on the peer peerFreed = TryFreeResources(dm.Peer(), SharedHeap.CurrentProcessSharedHeap.EndpointPeerOwnerId); } // release our endpoint meFreed = TryFreeResources(dm.endpointAlloc, SharedHeap.CurrentProcessSharedHeap.EndpointOwnerId); // our definition of freeing the channel is if we freed the exp // side return((isExp && meFreed) || (!isExp && peerFreed)); }
public static bool Free(DeliveryHandle handle) { DeliveryImpl di = GetImpl(handle); // This is a pretty kludgy hack, but is necessary since static // methods can't be called on an object. switch (di.GetImplName()) { case SingleAddrSpaceDelivery.ImplName: return(SingleAddrSpaceDelivery.Free((SingleAddrSpaceDelivery)di)); #if PAGING // TODO paging #endif default: throw new DeliveryHandleException( "Free of unknown channel delivery implementation \"" + di.GetImplName() + "\" requested"); } }
public unsafe static bool Create( string implName, Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint, out DeliveryHandle handle) { DeliveryImpl deliveryImpl; switch (implName) { case SingleAddrSpaceDelivery.ImplName: deliveryImpl = new SingleAddrSpaceDelivery(endpoint); break; #if PAGING // TODO paging #endif default: throw new DeliveryHandleException( "Unknown channel delivery implementation \"" + implName + "\" requested"); } if (!deliveryImpl.IsMechanismInitialized()) { DebugStub.Print("Ack! IsMechInit returns false!\n"); DebugStub.Break(); handle = Zero; return(false); } handle = new DeliveryHandle( Process.kernelProcess.AllocateHandle(deliveryImpl)); #if false unsafe { DebugStub.WriteLine("DeliveryHandle.Create: got handle {0,8:x}\n", __arglist((uint)handle.id)); } #endif return(true); }