singrdk/base/Services/RamDisk/Disk/Main.sg

123 lines
4.0 KiB
Plaintext

///////////////////////////////////////////////////////////////////////////////
//
// 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<ServiceProviderContract.Exp:Start> service;
[Endpoint]
internal TRef<RamDiskClientContract.Exp:Start> 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);
}
}
}