1 using System;
2 using System.Threading.Fibers;
3
4 public class Context
5 {
6 public nothrow Context() : mainFiber(null), otherFiber(null), runningFiber(null), otherFiberRunning(false)
7 {
8 }
9 public nothrow void SetFibers(Fiber* mainFiber_, Fiber* otherFiber_)
10 {
11 mainFiber = mainFiber_;
12 otherFiber = otherFiber_;
13 runningFiber = mainFiber;
14 }
15 public nothrow void SetOtherFiberRunning(bool running)
16 {
17 otherFiberRunning = running;
18 }
19 public nothrow bool IsOtherFiberRunning() const
20 {
21 return otherFiberRunning;
22 }
23 public nothrow void Switch()
24 {
25 if (runningFiber == mainFiber)
26 {
27 runningFiber = otherFiber;
28 SwitchToFiber(*otherFiber);
29 }
30 else
31 {
32 runningFiber = mainFiber;
33 SwitchToFiber(*mainFiber);
34 }
35 }
36 private Fiber* mainFiber;
37 private Fiber* otherFiber;
38 private Fiber* runningFiber;
39 private bool otherFiberRunning;
40 }
41
42 public void FiberHelper(Context* context)
43 {
44 Console.Out() << "in fiber helper" << endl();
45 int count = 1;
46 while (count <= 3)
47 {
48 Console.Out() << "switching context from fiber helper, count = " << count << endl();
49 context->Switch();
50 Console.Out() << "back in fiber helper, count = " << count << endl();
51 ++count;
52 }
53 Console.Out() << "exiting fiber helper" << endl();
54 }
55
56 public void FiberFunc(void* data)
57 {
58 Console.Out() << "in fiber" << endl();
59 Context* context = cast<Context*>(data);
60 try
61 {
62 context->SetOtherFiberRunning(true);
63 context->Switch();
64 FiberHelper(context);
65 context->SetOtherFiberRunning(false);
66 Console.Out() << "fiber exiting" << endl();
67 }
68 catch (const Exception& ex)
69 {
70 Console.Error() << "fiber got exception: " << ex.Message() << endl();
71 context->SetOtherFiberRunning(false);
72 }
73 context->Switch();
74 }
75
76 public int main()
77 {
78 try
79 {
80 Context context;
81 Fiber mainFiber = Fiber.FromCurrentThread();
82 FiberFunction fiberFunction = FiberFunc;
83 Fiber otherFiber(fiberFunction, &context);
84 context.SetFibers(&mainFiber, &otherFiber);
85 context.Switch();
86 Console.Out() << "back in main fiber" << endl();
87 while (context.IsOtherFiberRunning())
88 {
89 Console.Out() << "switch context from main fiber" << endl();
90 context.Switch();
91 Console.Out() << "back in main fiber" << endl();
92 }
93 Console.Out() << "exiting main" << endl();
94 }
95 catch (const Exception& ex)
96 {
97 Console.Error() << "main got exception: " << ex.Message() << endl();
98 return 1;
99 }
100 return 0;
101 }