singrdk/base/Kernel/Singularity/V1/Services/ChannelService.cs

421 lines
16 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity - Singularity ABI Implementation
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: EndpointCore.cs
//
// Note:
//
using System;
using System.Threading;
using System.Runtime.CompilerServices;
using Microsoft.Singularity;
using Microsoft.Singularity.Channels;
using Microsoft.Singularity.Security;
using Microsoft.Singularity.Memory;
using Microsoft.Singularity.V1.Security;
using Microsoft.Singularity.V1.Threads;
using Microsoft.Singularity.V1.Types;
namespace Microsoft.Singularity.V1.Services
{
using Allocation = SharedHeapService.Allocation;
using EndpointCoreImplementation = Microsoft.Singularity.Channels.EndpointCore;
[CLSCompliant(false)]
public enum ChannelServiceEvent : ushort
{
TransferBlockOwnership = 1,
TransferContentOwnership = 2,
}
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
[CLSCompliant(false)]
unsafe public struct EndpointCore
{
2008-11-17 18:29:00 -05:00
////////////////////////////////////////////////////////////////////
// Fields
////////////////////////////////////////////////////////////////////
//
// NOTE: The fields specified here must match those in:
// Kernel/Singularity/Channels/EndpointCore.cs
// Kernel/Singularity/V1/Services/ChannelServices.cs
// Libraries/Singuarity.V1/Services/ChannelServices.cs
2008-03-05 09:52:00 -05:00
/// <summary>
2008-11-17 18:29:00 -05:00
/// Handle to the actual message delivery mechanism
2008-03-05 09:52:00 -05:00
/// </summary>
2008-11-17 18:29:00 -05:00
private DeliveryHandle deliveryHandle;
2008-03-05 09:52:00 -05:00
/// <summary>
2008-11-17 18:29:00 -05:00
/// Event handle in case this endpoint is part of a collection
2008-03-05 09:52:00 -05:00
/// </summary>
2008-11-17 18:29:00 -05:00
private AutoResetEventHandle collectionEvent;
//
// These "cached" fields are directly accessable by user programs,
// but are not trusted by the kernel (as they could be modified by untrusted
// code). The kernel relies on the trusted shadow copies held in the
// deliveryImpl object, but updates these fields to reflect any changes to user
// apps.
//
2008-03-05 09:52:00 -05:00
/// <summary>
/// Event on which sends are signaled to this endpoint.
/// The handle is owned by the kernel, since the endpoint can move.
/// The kernel deallocates the handle when the channel is deallocated.
/// NOTE: stays valid until the entire channel gets collected.
/// </summary>
2008-11-17 18:29:00 -05:00
private AutoResetEventHandle cachedMessageEvent;
2008-03-05 09:52:00 -05:00
/// <summary>
2008-11-17 18:29:00 -05:00
/// Closed flag
2008-03-05 09:52:00 -05:00
/// </summary>
2008-11-17 18:29:00 -05:00
private bool cachedClosed;
2008-03-05 09:52:00 -05:00
/// <summary>
/// Contains the process id of the process currently owning this end of the
/// channel.
/// </summary>
2008-11-17 18:29:00 -05:00
private int cachedOwnerProcessId;
2008-03-05 09:52:00 -05:00
/// <summary>
2008-11-17 18:29:00 -05:00
/// Contains the channelId (positive on the EXP endpoint, negative on the imp endpoint)
2008-03-05 09:52:00 -05:00
/// </summary>
2008-11-17 18:29:00 -05:00
private int cachedChannelId;
2008-03-05 09:52:00 -05:00
/// <summary>
2008-11-17 18:29:00 -05:00
/// Whether to marshall or not
2008-03-05 09:52:00 -05:00
/// </summary>
2008-11-17 18:29:00 -05:00
private bool cachedMarshall;
2008-03-05 09:52:00 -05:00
/// <summary>
2008-11-17 18:29:00 -05:00
/// Points to the peer endpoint
/// </summary>
private Allocation* /*EndpointCore* opt(ExHeap)*/ cachedPeer;
/// <summary>
/// If true then the peer state can be queried directly from cachedPeer
2008-03-05 09:52:00 -05:00
/// </summary>
2008-11-17 18:29:00 -05:00
private bool peerStateValid;
////////////////////////////////////////////////////////////////////
// Methods
////////////////////////////////////////////////////////////////////
2008-03-05 09:52:00 -05:00
/// <summary>
/// Used to allocate a channel endpoint. The size must be correctly computed by
/// the trusted caller (currently trusted code NewChannel)
/// </summary>
[ExternalEntryPoint]
2008-11-17 18:29:00 -05:00
public static Allocation* //EndpointCore* opt(ExHeap)!
2008-03-05 09:52:00 -05:00
Allocate(uint size, SystemType st)
{
Allocation* ep = (Allocation*) SharedHeap.CurrentProcessSharedHeap.Allocate(
size, st.id, 0, SharedHeap.CurrentProcessSharedHeap.EndpointOwnerId);
if (ep == null) {
throw new ApplicationException("SharedHeap.Allocate returned null");
}
return ep;
}
/// <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.
/// Returns true for success, false for failure.
/// </summary>
[ExternalEntryPoint]
public static bool Dispose(ref EndpointCore endpoint)
{
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->Dispose();
}
}
/// <summary>
/// Deallocates this end of the channel. If other end is also
/// deallocated, the entire channel is deallocated.
/// </summary>
[ExternalEntryPoint]
public static void Free(Allocation* /* EndpointCore* opt(ExHeap) */ endpoint)
{
EndpointCoreImplementation.Free((SharedHeap.Allocation*)endpoint);
}
/// <summary>
/// Performs the initialization of the core part of each endpoint and cross links
/// them to form a channel.
/// </summary>
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
[ExternalEntryPoint]
public static void Connect(
Allocation* /*EndpointCore* opt(ExHeap)!*/ imp,
2008-11-17 18:29:00 -05:00
Allocation* /*EndpointCore* opt(ExHeap)!*/ exp,
Allocation* /*EndpointCore* opt(ExHeap) */ ep)
2008-03-05 09:52:00 -05:00
{
EndpointCoreImplementation.Connect((SharedHeap.Allocation*)imp,
2008-11-17 18:29:00 -05:00
(SharedHeap.Allocation*)exp,
(SharedHeap.Allocation*)ep);
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// Indicates if this endpoint is closed
/// </summary>
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public static bool Closed(ref EndpointCore endpoint)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
// kernel methods always access the shadowed copy in deliveryImpl
// not the user accessable copy in EndpointCore
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->Closed();
}
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
/// <summary>
/// Indicates if the peer endpoint is closed
/// </summary>
2008-03-05 09:52:00 -05:00
public static bool PeerClosed(ref EndpointCore ep)
{
2008-11-17 18:29:00 -05:00
// kernel methods always access the shadowed copy in deliveryImpl
// not the user accessable copy in EndpointCore
return PeerClosedABI(ref ep);
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
/// <summary>
/// Indicates if the peer endpoint is closed (ABI call)
/// </summary>
2008-03-05 09:52:00 -05:00
[ExternalEntryPoint]
2008-11-17 18:29:00 -05:00
public static bool PeerClosedABI(ref EndpointCore endpoint) {
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->PeerClosed();
}
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// Set this end to closed
/// </summary>
[ExternalEntryPoint]
2008-11-17 18:29:00 -05:00
public static void Close(ref EndpointCore endpoint) {
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
epimp->Close();
}
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// The endpoint to which this endpoint is connected.
/// </summary>
public static Allocation* /*EndpointCore* opt(ExHeap) */ GetPeer(ref EndpointCore ep,
out bool marshall)
{
2008-11-17 18:29:00 -05:00
// kernel methods always access the shadowed copy in deliveryImpl
// not the user accessable copy in EndpointCore
return GetPeerABI(ref ep, out marshall);
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
[ExternalEntryPoint]
2008-11-17 18:29:00 -05:00
public static Allocation* /*EndpointCore* opt(ExHeap) */ GetPeerABI(ref EndpointCore endpoint,
out bool marshall)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return (Allocation*) epimp->Peer(out marshall);
}
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// The event to wait for messages on this endpoint. Used by Select.
/// </summary>
2008-11-17 18:29:00 -05:00
public static SyncHandle GetWaitHandle(ref EndpointCore endpoint)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
// kernel methods always access the shadowed copy in deliveryImpl
// not the user accessable copy in EndpointCore
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->GetWaitHandle();
}
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// Notify the owner of this endpoint that a message is ready.
/// Notifies the set owner if this endpoint is part of a set.
/// </summary>
[ExternalEntryPoint]
public static void NotifyPeer(ref EndpointCore endpoint) {
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
epimp->NotifyPeer();
}
}
/// <summary>
/// Wait for a message to arrive on this endpoint.
/// </summary>
public static void Wait(ref EndpointCore ep) {
2008-11-17 18:29:00 -05:00
SyncHandle.WaitOne(GetWaitHandle(ref ep));
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// Transfer the given Allocation block to the target endpoint
/// </summary>
[ExternalEntryPoint]
public static void TransferBlockOwnership(Allocation* ptr, ref EndpointCore target)
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &target) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
EndpointCoreImplementation.TransferBlockOwnership((SharedHeap.Allocation*)ptr, ref *epimp);
}
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// Transfer any contents that needs to be adjusted from the transferee to the target
/// endpoint. Currently, this means setting the ownerProcessId of the
/// transferee to that of the target.
/// </summary>
[ExternalEntryPoint]
public static void TransferContentOwnership(
ref EndpointCore transferee,
ref EndpointCore target)
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep1 = &transferee, ep2 = &target) {
EndpointCoreImplementation* epimp1 = (EndpointCoreImplementation*)ep1;
EndpointCoreImplementation* epimp2 = (EndpointCoreImplementation*)ep2;
EndpointCoreImplementation.TransferContentOwnership(ref *epimp1, ref *epimp2);
}
2008-03-05 09:52:00 -05:00
}
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public static int GetChannelID(ref EndpointCore endpoint)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
// kernel methods always access the shadowed copy in deliveryImpl
// not the user accessable copy in EndpointCore
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->ChannelId;
}
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public static int GetOwnerProcessID(ref EndpointCore endpoint)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
// kernel methods always access the shadowed copy in deliveryImpl
// not the user accessable copy in EndpointCore
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->ProcessId;
}
2008-03-05 09:52:00 -05:00
}
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public static int GetPeerProcessID(ref EndpointCore ep)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
// kernel methods always access the shadowed copy in deliveryImpl
// not the user accessable copy in EndpointCore
return GetPeerProcessIDABI(ref ep);
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
[ExternalEntryPoint]
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public static int GetPeerProcessIDABI(ref EndpointCore endpoint)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->PeerProcessId;
}
2008-03-05 09:52:00 -05:00
}
[ExternalEntryPoint]
2008-11-17 18:29:00 -05:00
public static void AcceptDelegation(Allocation* /*EndpointCore* opt(ExHeap)!*/ imp,
Allocation* /*EndpointCore* opt(ExHeap)!*/ exp,
Allocation* /*EndpointCore* opt(ExHeap)!*/ ep)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
EndpointCoreImplementation.AcceptDelegation((SharedHeap.Allocation*)imp,
(SharedHeap.Allocation*)exp,
(SharedHeap.Allocation*)ep);
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
[ExternalEntryPoint]
public static void EnableDelegation(ref EndpointCore endpoint, bool allowMediation)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
epimp->EnableDelegation(allowMediation);
}
2008-03-05 09:52:00 -05:00
}
2008-11-17 18:29:00 -05:00
2008-03-05 09:52:00 -05:00
[ExternalEntryPoint]
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public static PrincipalHandle GetPeerPrincipalHandle(ref EndpointCore endpoint)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->PeerPrincipalHandle;
}
2008-03-05 09:52:00 -05:00
}
[ExternalEntryPoint]
[NoHeapAllocation]
2008-11-17 18:29:00 -05:00
public static PrincipalHandle GetOwnerPrincipalHandle(ref EndpointCore endpoint)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
return epimp->OwnerPrincipalHandle;
}
2008-03-05 09:52:00 -05:00
}
/// <summary>
/// Instruct the selectable object to signal events on the given AutoResetEvent
/// rather than its normal event in order to aggregate signalling into a set.
/// A selectable object need only support being part of a single collection at
/// any point in time.
/// </summary>
2008-11-17 18:29:00 -05:00
public static void LinkIntoCollection(ref EndpointCore ep,
AutoResetEventHandle ev) {
2008-03-05 09:52:00 -05:00
ep.collectionEvent = ev;
}
/// <summary>
/// Instruct the selectable object to stop signalling events on the given
/// AutoResetEvent.
/// </summary>
2008-11-17 18:29:00 -05:00
public static void UnlinkFromCollection(ref EndpointCore ep,
AutoResetEventHandle ev) {
2008-03-05 09:52:00 -05:00
ep.collectionEvent = new AutoResetEventHandle();
}
[ExternalEntryPoint]
2008-11-17 18:29:00 -05:00
unsafe public static void MarshallMessage(ref EndpointCore endpoint,
byte* basep,
byte* source,
int* tagAddress,
int msgSize)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &endpoint) {
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
epimp->BeginUpdate(basep, source, tagAddress, msgSize);
}
2008-03-05 09:52:00 -05:00
}
[ExternalEntryPoint]
2008-11-17 18:29:00 -05:00
public static void MarshallPointer(ref EndpointCore endpoint, byte* basep, byte** target, SystemType type, byte* parent, int offset)
2008-03-05 09:52:00 -05:00
{
2008-11-17 18:29:00 -05:00
fixed (EndpointCore* ep = &endpoint)
{
EndpointCoreImplementation* epimp = (EndpointCoreImplementation*)ep;
epimp->MarshallPointer(basep, target, type, parent, offset);
}
2008-03-05 09:52:00 -05:00
}
}
}