/// <summary> /// The event to wait for messages on this endpoint. Used by Select. /// </summary> public SyncHandle GetWaitHandle() { DeliveryImpl di = EndpointDeliveryImpl; VTable.Assert(di != null); return(di.MessageEvent); }
/// <summary> /// Get the AutoResetEventHandle /// </summary> public AutoResetEventHandle GetAreHandle() { DeliveryImpl di = EndpointDeliveryImpl; VTable.Assert(di != null); return(di.AreHandle); }
/// <summary> /// Transfer any contents that needs to be adjusted from the transferee to the target /// endpoint. /// </summary> // TODO: change "ref EndpointCore" to "EndpointCore" public static void TransferContentOwnership( ref EndpointCore transferee, ref EndpointCore target) { // TODO MAKE THIS APROPRIATE TO BOTH SINGLE AND PAGED IMPLS DeliveryImpl transfereeDi = transferee.EndpointDeliveryImpl; // XXX BUG? BUG? BUG? // targetDi = transferee.EndpointDeliveryImpl // should be: // targetDi = target.EndpointDeliveryImpl DeliveryImpl targetDi = transferee.EndpointDeliveryImpl; VTable.Assert((transfereeDi != null) && (targetDi != null)); //Monitoring.Log(Monitoring.Provider.ChannelService, // (ushort)ChannelServiceEvent.TransferContentOwnership, 0, // (uint)transfereeDi.ProcessId, // (uint)targetDi.ProcessId, // (uint)transfereeDi.ChannelId, // (uint)targetDi.ChannelId, // (uint)targetDi.Peer.ChannelId); int toProcessId = targetDi.ProcessId; transfereeDi.ProcessId = toProcessId; DelegationState newstate = transfereeDi.OwnerDelegationState; transfereeDi.OwnerPrincipalHandle = TransferPrincipal(transfereeDi.OwnerPrincipalHandle, toProcessId, ref newstate); transfereeDi.OwnerDelegationState = newstate; Allocation *transfereePeerAllocation = transfereeDi.Peer(); // also transfer the peer allocation Allocation.SetOwnerProcessId(transfereePeerAllocation, toProcessId); }
/// <summary> /// Used internally by the kernel to transfer an endpoint to a new owner /// /// Can be used to transfer ANY kind of shared heap data, not just endpoints. /// </summary> public static Allocation *MoveEndpoint(SharedHeap fromHeap, SharedHeap toHeap, Process newOwner, Allocation *ep) { return(DeliveryImpl.MoveData(fromHeap, toHeap, newOwner, ep)); }
/// <summary> /// Generic copy (either from kernel or to kernel) /// Determines if the thing we are moving is an endpoint and copies it accordingly. /// </summary> public static Allocation *MoveData(SharedHeap fromHeap, SharedHeap toHeap, Process newOwner, Allocation *data) { if (data == null) { return(data); } if (!fromHeap.Validate(data)) { throw new ArgumentException("Bad argument. Not visible"); } // We can only transfer either into our out of the kernel's heap DebugStub.Assert(fromHeap == SharedHeap.KernelSharedHeap || toHeap == SharedHeap.KernelSharedHeap); if (SystemType.IsSubtype(data, EndpointCoreSystemType)) { // we have an endpoint DeliveryImpl di = EndpointCore.AllocationEndpointDeliveryImpl(data); return(di.MoveEndpoint(fromHeap, toHeap, newOwner)); } else { // we have a NON-endpoint // TODO FIX this! return(null); // MoveNonEndpoint(fromHeap, toHeap, newOwner, data); } }
/// <summary> /// Return a handle for the peer /// </summary> public Allocation *Peer(out bool marshall) { DeliveryImpl di = EndpointDeliveryImpl; VTable.Assert(di != null); return(di.Peer(out marshall)); }
/// <summary> /// Notify the peer of this endpoint that a message is ready. /// Notifies the set owner if this endpoint is part of a set. /// </summary> public void NotifyPeer() { DeliveryImpl di = EndpointDeliveryImpl; VTable.Assert(di != null); di.NotifyPeer(); }
//versions of begin update and marshallpointer that handle objects with pointers //greater than one level deep internal void BeginUpdate(byte *basep, byte *source, int *tagAddress, int msgSize) { DeliveryImpl di = EndpointDeliveryImpl; VTable.Assert(di != null); // DebugStub.Print("BeginUpdate delivery handle {0,8:x}\n", __arglist((uint)deliveryHandle.id)); di.BeginUpdate(basep, source, tagAddress, msgSize); }
internal void AcceptDelegation(DeliveryImpl expDi, DeliveryImpl epDi) { if (epDi.OwnerDelegationState == DelegationState.Mediated) { OwnerPrincipalHandle = epDi.OwnerPrincipalHandle; PeerPrincipalHandle = epDi.OwnerPrincipalHandle; } }
internal override void Connect(DeliveryImpl expDi, Allocation * /*EndpointCore* opt(ExHeap)!*/ securityEp) { base.Connect(expDi, securityEp); this.Initialize(expDi); expDi.Initialize(this); }
/// <summary> /// Set this end to closed /// </summary> public void Close() { DeliveryImpl di = EndpointDeliveryImpl; if (di != null) { di.Close(); } }
internal override void Initialize(DeliveryImpl peerDi) { peerEp = SharedHeap.CurrentProcessSharedHeap.Share(peerDi.EndpointAlloc, SharedHeap.CurrentProcessSharedHeap.EndpointPeerOwnerId, (UIntPtr)0, Allocation.GetSize(peerDi.EndpointAlloc)); this.endpoint->SetCachedPeer(peerEp); this.endpoint->SetPeerStateValid(true); }
public void MarshallPointer(byte *basep, byte **target, SystemType type, byte *parent, int offset) { if (target == null) { return; } DeliveryImpl di = EndpointDeliveryImpl; // DebugStub.Print("Marshall Pointer delivery handle {0,8:x}\n", __arglist((uint)deliveryHandle.id)); VTable.Assert(di != null); di.MarshallPointer(basep, target, type, parent, offset); }
public static void AcceptDelegation(Allocation * /*EndpointCore* opt(ExHeap)!*/ imp, Allocation * /*EndpointCore* opt(ExHeap)!*/ exp, Allocation * /*EndpointCore* opt(ExHeap)!*/ ep) { DeliveryImpl impDi = AllocationEndpointDeliveryImpl(imp); DeliveryImpl expDi = AllocationEndpointDeliveryImpl(exp); DeliveryImpl epDi = AllocationEndpointDeliveryImpl(ep); VTable.Assert((impDi != null && expDi != null && epDi != null)); VTable.Assert((impDi.GetType() == expDi.GetType()) && (impDi.GetType() == epDi.GetType())); impDi.AcceptDelegation(expDi, epDi); }
/// <summary> /// Closes this end of the channel and frees associated resources, EXCEPT the block /// of memory for this endpoint. It must be released by the caller. Sing# does this /// for the programmer. /// /// This runs in the kernel to avoid a race condition with Process.Stop. /// </summary> public bool Dispose() { DeliveryImpl di = EndpointDeliveryImpl; if (di != null) { return(EndpointDeliveryImpl.Dispose()); } else { return(true); // endpoint was not yet connected } }
// // These getter defer to the delivery implementation, as the kernel only // trusts the shadow versions held in Kernel memory space. // public bool PeerClosed() { DeliveryImpl di = EndpointDeliveryImpl; if (di != null) { return(di.PeerClosed()); } else { // endpoint has not yet been connected return(true); } }
/// <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); }
/// <summary> /// Transfer the given Allocation block to the target endpoint /// </summary> public static void TransferBlockOwnership(Allocation *ptr, ref EndpointCore target) { Allocation.SetOwnerProcessId(ptr, target.cachedOwnerProcessId); // TODO MAKE THIS APROPRIATE TO BOTH SINGLE AND PAGED IMPLS DeliveryImpl di = target.EndpointDeliveryImpl; VTable.Assert(di != null); //Monitoring.Log(Monitoring.Provider.ChannelService, // (ushort)ChannelServiceEvent.TransferBlockOwnership, 0, // (uint)di.ChannelId, // (uint)di.ProcessId, // 0, 0, 0); #if CHANNEL_COUNT IncreaseBytesSentCount((long)Allocation.GetSize(ptr)); #endif Allocation.SetOwnerProcessId(ptr, di.ProcessId); }
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"); } }
internal virtual void Connect(DeliveryImpl expDi, Allocation * /*EndpointCore* opt(ExHeap)!*/ securityEp) { // security principals are held in the delivery impl, not the endpoint core // since this allows them to be kept out of user memory in paging builds if (securityEp != null) { DeliveryImpl secImpl = EndpointCore.AllocationEndpointDeliveryImpl(securityEp); if (secImpl != null && secImpl.OwnerDelegationState == DelegationState.Mediated) { this.OwnerPrincipalHandle = secImpl.OwnerPrincipalHandle; } } int newChannelId = EndpointCore.GetNextChannelId(); this.ChannelId = -newChannelId; expDi.ChannelId = newChannelId; this.Closed = false; expDi.Closed = false; }
public static DeliveryImpl GetImpl(DeliveryHandle handle) { DeliveryImpl di = HandleTable.GetHandle(handle.id) as DeliveryImpl; return(di); }
// // abstract methods which must be defined by actual delivery implementations // internal abstract void Initialize(DeliveryImpl peerDi);