PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/base/Kernel/Singularity/Channels/DeliveryImpl.cs

#
C# | 410 lines | 231 code | 62 blank | 117 comment | 18 complexity | 61c422168158250f7e1dce353e4b6566 MD5 | raw file
  1. ////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Microsoft Research Singularity
  4. //
  5. // Copyright (c) Microsoft Corporation. All rights reserved.
  6. //
  7. // File: DeliveryImpl.cs
  8. //
  9. // Note: Abstract super-class of all channel delivery implementations
  10. //
  11. using System;
  12. using System.Runtime.CompilerServices;
  13. using Microsoft.Singularity;
  14. using Microsoft.Singularity.Memory;
  15. using Microsoft.Singularity.Security;
  16. namespace Microsoft.Singularity.Channels
  17. {
  18. using Microsoft.Singularity.V1.Types;
  19. using Microsoft.Singularity.V1.Security;
  20. using Microsoft.Singularity.V1.Services;
  21. using Microsoft.Singularity.V1.Threads;
  22. using Allocation = Microsoft.Singularity.Memory.SharedHeap.Allocation;
  23. using DelegationState = Microsoft.Singularity.Channels.EndpointCore.DelegationState;
  24. using System.Threading;
  25. [CLSCompliant(false)]
  26. public unsafe abstract class DeliveryImpl
  27. {
  28. ////////////////////////////////////////////////////////////////////
  29. // Class Fields
  30. //
  31. /// <summary>
  32. /// Allocation which holds the endpoint core associated with this
  33. /// delivery implementation
  34. /// </summary>
  35. protected Allocation* /*EndpointCore* opt(ExHeap)!*/ endpointAlloc;
  36. /// <summary>
  37. /// Endpoint core associated with this delivery implementation
  38. /// </summary>
  39. protected EndpointCore* endpoint;
  40. /// <summary>
  41. /// Handle to the owning Principal
  42. /// </summary>
  43. protected PrincipalHandle principalHandle;
  44. /// <summary>
  45. /// Delegation state to control delegation through the principal
  46. /// </summary>
  47. protected DelegationState delegationState;
  48. /// <summary>
  49. /// Contains the number of sends to this endpoint.
  50. /// </summary>
  51. protected int receiveCount;
  52. //
  53. // Shadow "trusted" shadow copies of the fields in endpointCore
  54. //
  55. /// <summary>
  56. /// Event on which sends are signaled to this endpoint.
  57. /// The handle is owned by the kernel, since the endpoint can move.
  58. /// The kernel deallocates the handle when the channel is deallocated.
  59. /// NOTE: stays valid until the entire channel gets collected.
  60. /// </summary>
  61. private AutoResetEventHandle shadowMessageEvent;
  62. /// <summary>
  63. /// Closed flag
  64. /// </summary>
  65. private bool shadowClosed;
  66. /// <summary>
  67. /// Contains the process id of the process currently owning this end of the
  68. /// channel.
  69. /// </summary>
  70. private int shadowProcessId;
  71. /// <summary>
  72. /// Contains the channelId (positive on the EXP endpoint, negative on the imp endpoint)
  73. /// </summary>
  74. private int shadowChannelId;
  75. /// <summary>
  76. /// Whether or not to marshall messages
  77. /// </summary>
  78. private bool shadowMarshall;
  79. ////////////////////////////////////////////////////////////////////
  80. // Class Methods
  81. //
  82. internal DeliveryImpl(Allocation* /*EndpointCore* opt(ExHeap)!*/ ep)
  83. {
  84. this.endpointAlloc = ep;
  85. this.endpoint = ((EndpointCore*)Allocation.GetData(ep));
  86. // set default values (shadow cached values in EndpointCore if necessary)
  87. setMessageEvent(new AutoResetEventHandle(
  88. Process.kernelProcess.AllocateHandle(new AutoResetEvent(false))));
  89. endpoint->CollectionEvent = new AutoResetEventHandle();
  90. endpoint->SetCachedPeer(null); // set as null by default
  91. ProcessId = Thread.CurrentProcess.ProcessId;
  92. ChannelId = 0; // zero initially, corrected in connect
  93. Marshall = false; // false by default
  94. Closed = true; // opened in connect
  95. principalHandle = new PrincipalHandle(Thread.CurrentProcess.Principal.Val);
  96. delegationState = DelegationState.None;
  97. receiveCount = 0;
  98. }
  99. /// <summary>
  100. /// Closes this end of the channel and frees associated resources,
  101. /// EXCEPT the block of memory for this endpoint. It must be released
  102. /// by the caller. Sing# does this for the programmer.
  103. ///
  104. /// This runs in the kernel to avoid a race condition with Process.Stop
  105. /// </summary>
  106. internal bool Dispose()
  107. {
  108. if (this.Closed) {
  109. return false;
  110. }
  111. Close(); // mark our side closed before waking up peer
  112. NotifyPeer();
  113. return true;
  114. }
  115. internal virtual void Connect(DeliveryImpl expDi,
  116. Allocation* /*EndpointCore* opt(ExHeap)!*/ securityEp)
  117. {
  118. // security principals are held in the delivery impl, not the endpoint core
  119. // since this allows them to be kept out of user memory in paging builds
  120. if (securityEp != null) {
  121. DeliveryImpl secImpl =
  122. EndpointCore.AllocationEndpointDeliveryImpl(securityEp);
  123. if (secImpl != null &&
  124. secImpl.OwnerDelegationState == DelegationState.Mediated)
  125. {
  126. this.OwnerPrincipalHandle = secImpl.OwnerPrincipalHandle;
  127. }
  128. }
  129. int newChannelId = EndpointCore.GetNextChannelId();
  130. this.ChannelId = -newChannelId;
  131. expDi.ChannelId = newChannelId;
  132. this.Closed = false;
  133. expDi.Closed = false;
  134. }
  135. /// <summary>
  136. /// Set this end to closed
  137. /// </summary>
  138. public abstract void Close();
  139. /// <summary>
  140. /// Notify the owner of this endpoint that a message is ready.
  141. /// Notifies the set owner if this endpoint is part of a set.
  142. /// </summary>
  143. public void Notify() {
  144. this.receiveCount++;
  145. Tracing.Log(Tracing.Debug, "Endpoint Notify");
  146. // NB: Cache the collection event to prevent
  147. // a race with the receiver.
  148. AutoResetEventHandle cached_collEvent = endpoint->CollectionEvent;
  149. if (cached_collEvent.id != UIntPtr.Zero) {
  150. AutoResetEventHandle.Set(cached_collEvent);
  151. }
  152. AutoResetEventHandle.Set(this.AreHandle);
  153. }
  154. private static SystemType EndpointCoreSystemType =
  155. typeof(Microsoft.Singularity.V1.Services.EndpointCore).GetSystemType();
  156. /// <summary>
  157. /// Generic copy (either from kernel or to kernel)
  158. /// Determines if the thing we are moving is an endpoint and copies it accordingly.
  159. /// </summary>
  160. public static Allocation* MoveData(SharedHeap fromHeap,
  161. SharedHeap toHeap,
  162. Process newOwner,
  163. Allocation* data)
  164. {
  165. if (data == null) return data;
  166. if (!fromHeap.Validate(data)) {
  167. throw new ArgumentException("Bad argument. Not visible");
  168. }
  169. // We can only transfer either into our out of the kernel's heap
  170. DebugStub.Assert(fromHeap == SharedHeap.KernelSharedHeap ||
  171. toHeap == SharedHeap.KernelSharedHeap);
  172. if (SystemType.IsSubtype(data, EndpointCoreSystemType)) {
  173. // we have an endpoint
  174. DeliveryImpl di = EndpointCore.AllocationEndpointDeliveryImpl(data);
  175. return di.MoveEndpoint(fromHeap, toHeap, newOwner);
  176. }
  177. else {
  178. // we have a NON-endpoint
  179. // TODO FIX this!
  180. return null; // MoveNonEndpoint(fromHeap, toHeap, newOwner, data);
  181. }
  182. }
  183. internal void AcceptDelegation(DeliveryImpl expDi, DeliveryImpl epDi)
  184. {
  185. if (epDi.OwnerDelegationState == DelegationState.Mediated) {
  186. OwnerPrincipalHandle = epDi.OwnerPrincipalHandle;
  187. PeerPrincipalHandle = epDi.OwnerPrincipalHandle;
  188. }
  189. }
  190. internal void EnableDelegation(bool allowMediation)
  191. {
  192. if (allowMediation)
  193. OwnerDelegationState = DelegationState.ByMediation;
  194. else
  195. OwnerDelegationState = DelegationState.ByCapability;
  196. }
  197. //
  198. // Getters and setters for fields which are shadowed in EndpointCore
  199. //
  200. internal bool Closed
  201. {
  202. [NoHeapAllocation]
  203. get {
  204. return shadowClosed;
  205. }
  206. set {
  207. shadowClosed = value;
  208. endpoint->SetCachedClose(value);
  209. }
  210. }
  211. internal int ChannelId {
  212. [NoHeapAllocation]
  213. get {
  214. return shadowChannelId;
  215. }
  216. set {
  217. shadowChannelId = value;
  218. endpoint->SetCachedChannelId(value);
  219. }
  220. }
  221. internal int ProcessId {
  222. [NoHeapAllocation]
  223. get {
  224. return shadowProcessId;
  225. }
  226. set {
  227. shadowProcessId = value;
  228. endpoint->SetCachedProcessId(value);
  229. }
  230. }
  231. internal int ReceiveCount {
  232. [NoHeapAllocation]
  233. get {
  234. return receiveCount;
  235. }
  236. }
  237. internal bool Marshall {
  238. [NoHeapAllocation]
  239. get {
  240. return shadowMarshall;
  241. }
  242. set {
  243. shadowMarshall = value;
  244. endpoint->SetCachedMarshall(value);
  245. }
  246. }
  247. internal AutoResetEventHandle AreHandle {
  248. get {
  249. return shadowMessageEvent;
  250. }
  251. }
  252. internal SyncHandle MessageEvent {
  253. get {
  254. return shadowMessageEvent;
  255. }
  256. }
  257. public Allocation * /* EndpointCore */ EndpointAlloc {
  258. get {
  259. return endpointAlloc;
  260. }
  261. }
  262. private void setMessageEvent(AutoResetEventHandle value) {
  263. shadowMessageEvent = value;
  264. endpoint->SetCachedMessageEvent(value);
  265. }
  266. internal Allocation* Peer(out bool marshall) {
  267. marshall = Marshall;
  268. return Peer();
  269. }
  270. internal EndpointCore.DelegationState OwnerDelegationState {
  271. [NoHeapAllocation]
  272. get {
  273. return delegationState;
  274. }
  275. set {
  276. delegationState = value;
  277. }
  278. }
  279. internal PrincipalHandle OwnerPrincipalHandle {
  280. [NoHeapAllocation]
  281. get {
  282. return principalHandle;
  283. }
  284. set {
  285. principalHandle = value;
  286. }
  287. }
  288. //
  289. // abstract methods which must be defined by actual delivery implementations
  290. //
  291. internal abstract void Initialize(DeliveryImpl peerDi);
  292. /// <summary>
  293. /// Return the associated peer of this endpoint
  294. /// </summary>
  295. [NoHeapAllocation]
  296. public abstract Allocation* Peer();
  297. /// <summary>
  298. /// Move endpoint data to a new process
  299. /// </summary>
  300. internal abstract Allocation* MoveEndpoint(SharedHeap fromHeap,
  301. SharedHeap toHeap,
  302. Process newOwner);
  303. // <summary>
  304. // Move non endpoint data to a new process
  305. // </summary>
  306. //internal abstract Allocation* MoveNonEndpoint(SharedHeap fromHeap,
  307. // SharedHeap toHeap,
  308. // Process newOwner);
  309. /// <summary>
  310. /// Returns true if this delivery mechanism has been initialised and
  311. /// can be used for channel transport.
  312. /// </summary>
  313. internal abstract bool IsMechanismInitialized();
  314. /// <summary>
  315. /// Returns the name of the delivery implementation actually being used
  316. /// </summary>
  317. internal abstract string GetImplName();
  318. /// <summary>
  319. /// Notify the peer that a message is ready.
  320. /// </summary>
  321. internal abstract void NotifyPeer();
  322. /// <summary>
  323. /// Close peer endpoint.
  324. /// </summary>
  325. internal abstract bool ClosePeer();
  326. /// <summary>
  327. /// Is peer endpoint closed.
  328. /// </summary>
  329. internal abstract bool PeerClosed();
  330. internal abstract int PeerProcessId {
  331. [NoHeapAllocation]
  332. get;
  333. }
  334. internal abstract int PeerReceiveCount {
  335. [NoHeapAllocation]
  336. get;
  337. }
  338. internal abstract PrincipalHandle PeerPrincipalHandle {
  339. [NoHeapAllocation]
  340. get;
  341. set;
  342. }
  343. //methods used for structures that contain pointers greater than one level deep
  344. internal abstract void BeginUpdate(byte* basep, byte* source, int* tagAddress, int msgSize);
  345. unsafe internal abstract void MarshallPointer(byte* basep, byte** target, SystemType type, byte* parent, int offset);
  346. ///////////////////////////////////////////////////////////////////
  347. }
  348. }