1
2
3
4
5
6 using System;
7 using System.Threading;
8
9 namespace System.Threading.Fibers
10 {
11 public delegate void FiberFunction(void* param);
12
13 internal class FiberData
14 {
15 public FiberData(const FiberFunction& function_, void* param_) : function(function_), param(param_)
16 {
17 }
18 public inline FiberFunction Function() const
19 {
20 return function;
21 }
22 public inline void* Param() const
23 {
24 return param;
25 }
26 private FiberFunction function;
27 private void* param;
28 }
29
30 public class Fiber
31 {
32 public Fiber() : handle(null), main(true)
33 {
34 handle = RtmConvertThreadToFiber(null);
35 }
36 public Fiber(const FiberFunction& function) : this(cast<ulong>(1024u) * 1024u, function, null)
37 {
38 }
39 public Fiber(const FiberFunction& function, void* param) : this(cast<ulong>(1024u) * 1024u, function, param)
40 {
41 }
42 public Fiber(ulong stackSize, const FiberFunction& function) : this(stackSize, function, null)
43 {
44 }
45 public Fiber(ulong stackSize, const FiberFunction& function, void* param) : handle(null), main(false)
46 {
47 FiberRunFunction runFiber = RunFiber;
48 void* startAddress = cast<void*>(runFiber);
49 handle = RtmCreateFiber(stackSize, startAddress, new FiberData(function, param));
50 }
51 [nodiscard]
52 public Result<bool> SwitchTo()
53 {
54 if (handle != null)
55 {
56 RtmSwitchToFiber(handle);
57 }
58 else
59 {
60 string errorMessage = "could not switch to this fiber: handle is null";
61 int errorId = AllocateError(errorMessage);
62 return Result<bool>(ErrorId(errorId));
63 }
64 return Result<bool>(true);
65 }
66 public suppress Fiber(const Fiber&);
67 public suppress void operator=(const Fiber&);
68 public Fiber(Fiber&& that) : handle(that.handle), main(that.main)
69 {
70 that.handle = null;
71 that.main = false;
72 }
73 public default void operator=(Fiber&& that);
74 public ~Fiber()
75 {
76 if (handle != null)
77 {
78 if (!main)
79 {
80 RtmDeleteFiber(handle);
81 }
82 }
83 }
84 public inline void* Handle() const
85 {
86 return handle;
87 }
88 public static Fiber FromCurrentThread()
89 {
90 return Fiber();
91 }
92 private void* handle;
93 private bool main;
94 }
95
96 [nodiscard]
97 public Result<bool> SwitchToFiber(const Fiber& fiber)
98 {
99 return fiber.SwitchTo();
100 }
101
102 internal delegate void FiberRunFunction();
103
104 internal void RunFiber()
105 {
106 void* data = RtmGetFiberData();
107 UniquePtr<FiberData> fiberData(cast<FiberData*>(data));
108 FiberFunction function = fiberData->Function();
109 void* param = fiberData->Param();
110 function(param);
111 }