123 lines
4.0 KiB
Plaintext
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);
|
||
|
}
|
||
|
}
|
||
|
}
|