Beispiel #1
0
        /// <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);
                }
            }
        }
        /// <summary>
        /// The peer thread might try this too, so we use the ref count of the
        /// underlying memory to allow only the last freeer to also free the
        /// associated auto-reset event handle.  Make sure to grab the handle
        /// before freeing the endpoint.
        /// </summary>
        unsafe private static bool TryFreeResources(
            Allocation * /*EndpointCore*/ endpoint,
            SharedHeap.AllocationOwnerId ownerId)
        {
            EndpointCore *epData =
                (EndpointCore *)Allocation.GetDataUnchecked(endpoint);

            AutoResetEventHandle areHandle = epData->GetAreHandle();
            DeliveryHandle       dh        = epData->dImpHandle;

            int channelId = epData->ChannelId;

            bool lastRefGone = SharedHeap.KernelSharedHeap.Free(endpoint,
                                                                ownerId);

            if (lastRefGone)
            {
                if (dh != DeliveryHandle.Zero)
                {
                    DeliveryHandle.Dispose(dh);
                }
                if (areHandle.id != UIntPtr.Zero)
                {
                    Process.kernelProcess.ReleaseHandle(areHandle.id);
                }
            }

            return(lastRefGone);
        }
Beispiel #3
0
 internal static void Dispose(Process process,
                              DeliveryHandle handle)
 {
     Tracing.Log(Tracing.Debug, "DeliveryHandle.Dispose(id={0:x8})",
                 handle.id);
     //
     // Releasing the handle will allow the deliveryImpl to be garbage-
     // collected
     //
     process.ReleaseHandle(handle.id);
 }
Beispiel #4
0
        /// <summary>
        /// Performs the initialization of the core part of each endpoint and cross links
        /// them to form a channel.  Uses the given delivery mechanism.
        /// </summary>
        public static void Connect(
            Allocation * /*EndpointCore* opt(ExHeap)!*/ imp,
            Allocation * /*EndpointCore* opt(ExHeap)!*/ exp,
            Allocation * /*EndpointCore* opt(ExHeap)!*/ securityEp,
            string deliveryImplType)
        {
            if (imp == null || exp == null)
            {
                throw new ApplicationException("Connect called with null endpoints");
            }
            EndpointCore *impData = (EndpointCore *)Allocation.GetData(imp);
            EndpointCore *expData = (EndpointCore *)Allocation.GetData(exp);

            if (impData == null || expData == null)
            {
                throw new ApplicationException("SharedHeap.GetData return null");
            }

            Tracing.Log(Tracing.Debug, "connect {0:x8} and {1:x8}",
                        (UIntPtr)imp, (UIntPtr)exp);

            if (!(DeliveryHandle.Create(deliveryImplType, imp, out impData->deliveryHandle) &&
                  DeliveryHandle.Create(deliveryImplType, exp, out expData->deliveryHandle)))
            {
                throw new EndpointCoreException(
                          "Error trying to create EndpointCore using \"" +
                          deliveryImplType +
                          "\" delivery implementation");
            }
#if false
            DebugStub.Print("imp handle {0,8:x} exp handle {1,8:x}\n",
                            __arglist((uint)impData->deliveryHandle.id, (uint)expData->deliveryHandle.id));
#endif
            DeliveryImpl impDi = impData->EndpointDeliveryImpl;
            DeliveryImpl expDi = expData->EndpointDeliveryImpl;

            VTable.Assert(impDi != null && expDi != null);

            impDi.Connect(expDi, securityEp);

            // keep track of how many channels are open
            Interlocked.Increment(ref openChannelCount);
#if CHANNEL_COUNT
            PerfCounters.IncrementChannelsCreated();
#endif
            Monitoring.Log(Monitoring.Provider.EndpointCore,
                           (ushort)EndpointCoreEvent.Connect, 0,
                           (uint)expData->ChannelId, 0, 0, 0, 0);
        }
Beispiel #5
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");
            }
        }
Beispiel #6
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);
        }
Beispiel #7
0
 public static void Dispose(DeliveryHandle handle)
 {
     Dispose(Process.kernelProcess, handle);
 }
Beispiel #8
0
        public static DeliveryImpl GetImpl(DeliveryHandle handle)
        {
            DeliveryImpl di = HandleTable.GetHandle(handle.id) as DeliveryImpl;

            return(di);
        }