/// <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));
        }
示例#2
0
        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");
            }
        }
示例#3
0
        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);
        }