/////////////////////////////////////////////////////////////////////////////// // // Microsoft Research Singularity // // Copyright (c) Microsoft Corporation. All rights reserved. // // File: Main.sg // // Note: Entry point for RAM disk service, sets up channel. // // using Microsoft.SingSharp; using Microsoft.SingSharp.Reflection; using Microsoft.Singularity.Channels; using Microsoft.Singularity.Configuration; using Microsoft.Singularity.Directory; using Microsoft.Singularity.Extending; using Microsoft.Singularity.Io; using Microsoft.Singularity.Security; using Microsoft.Singularity.Services; using Microsoft.Singularity.Services.RamDisk.Contracts; using System; using MSD = Microsoft.Singularity.Directory; [assembly: ApplicationPublisherAttribute("singularity.microsoft.com")] [assembly: AssertPrivilegeAttribute("$register-privilege.localhost")] [assembly: Transform(typeof(ServiceResourceTransform))] namespace Microsoft.Singularity.Services.RamDisk { [Category("Service")] public sealed class DiskResources { [ServiceEndpoint(typeof(DiskDeviceContract))] public readonly TRef service; [Endpoint] internal TRef managerTRef; reflective private DiskResources(); } internal sealed class Disk { private static RamDisk ramDisk; private static string diskPath; private class RamDiskErrorException : Exception { private RamDiskContractErrorCode errorCode; internal RamDiskErrorException(RamDiskContractErrorCode errorCode) { this.errorCode = errorCode; } internal RamDiskContractErrorCode ErrorCode { get { return errorCode; } } } internal static int AppMain(DiskResources! resources) { RamDiskClientContract.Exp:Start! managerExp = resources.managerTRef.Acquire(); bool shutdown = false; RamDisk ramDisk = null; while (!shutdown) { try { switch receive { case managerExp.Create(diskName, diskSizeBytes): try { ramDisk = CreateDevice(Bitter.ToString2(diskName), diskSizeBytes, resources); managerExp.SendSuccess(); shutdown = true; } finally { delete diskName; } break; case managerExp.ChannelClosed(): shutdown = true; break; } } catch (RamDiskErrorException ex) { managerExp.SendFail(ex.ErrorCode); } catch (OutOfMemoryException) { managerExp.SendFail(RamDiskContractErrorCode.OutOfMemory); } } if (ramDisk != null) { ServiceProviderContract.Exp! service = resources.service.Acquire(); ramDisk.Run(service, managerExp); ramDisk.Finalize(); } else { delete managerExp; } return 0; } private static RamDisk! CreateDevice(string! diskName, ulong diskSizeBytes, DiskResources! resources) { ulong diskSizeSectors = (diskSizeBytes + RamDisk.SECTOR_SIZE - 1)/RamDisk.SECTOR_SIZE; if (diskSizeSectors >= uint.MaxValue) { throw new RamDiskErrorException(RamDiskContractErrorCode.InsufficientResources); } return new RamDisk(diskName, (uint)diskSizeSectors, diskName); } } }