singrdk/base/Applications/Tests/ChannelDemo/ChannelDemo.sg

157 lines
4.8 KiB
Plaintext

////////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: ChannelDemo.cs
//
// Note: Simple Singularity test program.
//
using System;
using System.Threading;
using Microsoft.Singularity.V1.Services;
using Microsoft.Singularity.Channels;
using Microsoft.Contracts;
using Microsoft.SingSharp.Reflection;
using Microsoft.Singularity.Applications;
using Microsoft.Singularity.Io;
using Microsoft.Singularity.Configuration;
[assembly: Transform(typeof(ApplicationResourceTransform))]
namespace Microsoft.Singularity.Applications {
[ConsoleCategory(DefaultAction=true)]
internal class Parameters {
[InputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Exp:READY> Stdin;
[OutputEndpoint("data")]
public readonly TRef<UnicodePipeContract.Imp:READY> Stdout;
reflective internal Parameters();
internal int AppMain() {
return ChannelDemo.AppMain(this);
}
}
public class ChannelDemo
{
public contract ChannelTest {
in message Hi(int x);
out message Ack();
state Start: Hi? -> Ack! -> Start;
}
private static TRef<ChannelTest.Exp:Start>! endpoint1;
private static TRef<ChannelTest.Imp:Start>! endpoint2;
public static void ChannelThread1()
{
ChannelTest.Exp e1 = endpoint1.Acquire();
for (int i = 1; i <= 3; i++) {
Console.WriteLine("Thread 1 receiving message {0}...", i);
DebugStub.Print("Thread 1 receiving message {0}...\n", __arglist(i));
int len;
e1.RecvHi(out len);
e1.SendAck();
Console.WriteLine("Thread 1 received Hi message {0}.", len);
DebugStub.Print("Thread 1 received Hi message {0}.\n", __arglist(len));
}
delete e1;
}
public static void ChannelThread2()
{
ChannelTest.Imp e2 = endpoint2.Acquire();
Console.WriteLine("Thread 2 sending message 1...");
DebugStub.Print("Thread 2 sending message 1...\n");
e2.SendHi(1);
e2.RecvAck();
Thread.Yield();
Console.WriteLine("Thread 2 sending message 2...");
DebugStub.Print("Thread 2 sending message 2...\n");
e2.SendHi(2);
e2.RecvAck();
Console.WriteLine("Thread 2 sending message 3...");
DebugStub.Print("Thread 2 sending message 3...\n");
e2.SendHi(3);
e2.RecvAck();
delete e2;
}
static TimeSpan TwoSecondTimeout = new TimeSpan(0, 0, 0, 2);
public static void TimeoutDemo() {
ChannelTest.Exp! exp;
ChannelTest.Imp! imp;
ChannelTest.NewChannel(out imp, out exp);
Console.WriteLine("Timeout test");
Console.WriteLine("Time now: {0}", DateTime.Now);
Console.WriteLine("Timeout: {0}", TwoSecondTimeout);
switch receive {
case exp.Hi(x):
Console.WriteLine("Got Hi, but shouldn't have");
DebugService.Break();
break;
case timeout(TwoSecondTimeout):
Console.WriteLine("Got timeout");
Console.WriteLine("Time now: {0}", DateTime.Now);
break;
}
delete exp;
delete imp;
}
//[ShellCommand("channel", "Run channel demo")]
internal static int AppMain(Parameters! config)
{
// Now test timeout feature
TimeoutDemo();
// Make a new channel.
ChannelTest.Imp! e2;
ChannelTest.Exp! e1;
ChannelTest.NewChannel(out e2, out e1);
// Endpoints are initially owned by the creating thread.
// We're going to transfer ownership to other threads, so
// we release them here.
endpoint1 = new TRef<ChannelTest.Exp:Start>(e1);
endpoint2 = new TRef<ChannelTest.Imp:Start>(e2);
// Create our two threads.
Thread t1 = new Thread(new ThreadStart(ChannelThread1));
t1.Start();
Thread t2 = new Thread(new ThreadStart(ChannelThread2));
t2.Start();
// Yield a bunch of times to give our threads a chance to
// do their work.
for (int i = 0; i < 10; i++) {
Thread.Yield();
}
return 0;
}
}
}