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);
        }
 public static int GetPeerProcessID(ref EndpointCore ep)
 {
     if (ep.peerStateValid)
     {
         EndpointCore *peer = (EndpointCore *)SharedHeapService.GetData(ep.cachedPeer);
         return(peer->cachedOwnerProcessId);
     }
     else
     {
         return(GetPeerProcessIDABI(ref ep));
     }
 }
 public static bool PeerClosed(ref EndpointCore ep)
 {
     if (ep.cachedPeer != null)
     {
         EndpointCore *peer = (EndpointCore *)SharedHeapService.GetData(ep.cachedPeer);
         return(peer->cachedClosed);
     }
     else
     {
         return(PeerClosedABI(ref ep));
     }
 }
Beispiel #5
0
        internal static DeliveryImpl AllocationEndpointDeliveryImplUnchecked(
            Allocation * /*EndpointCore* opt(ExHeap)!*/ endpoint)
        {
            EndpointCore *ep = (EndpointCore *)Allocation.GetDataUnchecked(endpoint);

            if (ep == null)
            {
                return(null);
            }
            else
            {
                return(ep->EndpointDeliveryImpl);
            }
        }
Beispiel #6
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);
        }
        // requires alloc's owner unlocked
        private unsafe void EndpointVisit(SharedHeap.Allocation *alloc)
        {
// TODO: support PAGING
#if !PAGING
            EndpointCore *epData = (EndpointCore *)
                                   // Currently use unchecked access here, since the shared heap
                                   // walker does not run in the same process as the data.
                                   SharedHeap.Allocation.GetDataUnchecked(alloc);
            if (!epData->Closed())
            {
                epData->Dispose();
            }
            EndpointCore.Free(alloc);
#endif //PAGING
        }
Beispiel #8
0
        ////////////////////////////////////////////////////////////////////
        // Class Methods
        //

        internal DeliveryImpl(Allocation * /*EndpointCore* opt(ExHeap)!*/ ep)
        {
            this.endpointAlloc = ep;
            this.endpoint      = ((EndpointCore *)Allocation.GetData(ep));

            // set default values (shadow cached values in EndpointCore if necessary)
            setMessageEvent(new AutoResetEventHandle(
                                Process.kernelProcess.AllocateHandle(new AutoResetEvent(false))));
            endpoint->CollectionEvent = new AutoResetEventHandle();

            endpoint->SetCachedPeer(null);    // set as null by default

            ProcessId = Thread.CurrentProcess.ProcessId;
            ChannelId = 0;                    // zero initially, corrected in connect
            Marshall  = false;                // false by default
            Closed    = true;                 // opened in connect

            principalHandle = new PrincipalHandle(Thread.CurrentProcess.Principal.Val);
            delegationState = DelegationState.None;
            receiveCount    = 0;
        }