1 // `suspends` contains the types that are used by the reactor API to represent blocking tasks and their results.
2 // both this and llawait() can be considered implementation details of llevents, but are exposed nonetheless.
3 // a "suspend" refers to a reason for your fiber to be on hold by the reactor
4 // not to be confused with a "suspend send", an object representing a suspend, sent to the reactor
5 // and a "suspend return" is sent back to the fiber from the reactor once it has been fulfilled.
6 module rockhopper.core.suspends;
7 
8 import std.typecons : Tuple, tuple;
9 import taggedalgebraic : TaggedUnion, Void;
10 import eventcore.driver : FileFD, PipeFD, IOMode, StreamSocketFD, DatagramSocketFD;
11 
12 // === SENDS ===
13 
14 private
15 {
16 	struct SSRead(FD)
17 	{
18 		FD fd;
19 		ulong offset;
20 		ubyte[] buf;
21 		IOMode ioMode;
22 	}
23 
24 	struct SSWrite(FD)
25 	{
26 		FD fd;
27 		ulong offset; // only used for files, ignored for pipes
28 		const(ubyte)[] buf;
29 		IOMode ioMode;
30 	}
31 }
32 
33 public
34 {
35 	struct SSFileOpen
36 	{
37 		import eventcore.driver : FileOpenMode;
38 
39 		string path;
40 		FileOpenMode mode;
41 	}
42 
43 	struct SSStreamConnect
44 	{
45 		import std.socket : Address;
46 
47 		Address peerAddress;
48 		Address bindAddress;
49 	}
50 
51 	struct SSDgramSend
52 	{
53 		import std.socket : Address;
54 
55 		DatagramSocketFD fd;
56 		const(ubyte)[] buf;
57 		IOMode ioMode;
58 		Address targetAddress;
59 	}
60 
61 	alias SSFileRead = SSRead!FileFD;
62 	alias SSPipeRead = SSRead!PipeFD;
63 	alias SSStreamRead = SSRead!StreamSocketFD;
64 	alias SSDgramReceive = SSRead!DatagramSocketFD;
65 	alias SSFileWrite = SSWrite!FileFD;
66 	alias SSPipeWrite = SSWrite!PipeFD;
67 	alias SSStreamWrite = SSWrite!StreamSocketFD;
68 }
69 
70 
71 private union _SSRaw
72 {
73 	import eventcore.driver : TimerID, ProcessID, EventID, StreamListenSocketFD;
74 	import std.socket : Address;
75 
76 	string nsLookup;
77 	EventID threadEvent;
78 	SSFileOpen fileOpen;
79 	FileFD fileClose;
80 	SSFileRead fileRead;
81 	SSPipeRead pipeRead;
82 	SSFileWrite fileWrite;
83 	SSPipeWrite pipeWrite;
84 	ProcessID procWait;
85 	int signalTrap;
86 	SSStreamConnect streamConnect;
87 	SSStreamRead streamRead;
88 	SSDgramReceive dgramReceive;
89 	SSDgramSend dgramSend;
90 	SSStreamWrite streamWrite;
91 	TimerID sleep;
92 	// not implemented: directory watchers
93 }
94 
95 public alias SuspendSend = TaggedUnion!_SSRaw;
96 
97 // === RETURNS ===
98 
99 public
100 {
101 	struct SRNsLookup
102 	{
103 		import eventcore.driver : DNSStatus, RefAddress;
104 
105 		DNSStatus status;
106 		RefAddress[] addresses;
107 	}
108 
109 	struct SRFileOpen
110 	{
111 		import eventcore.driver : OpenStatus;
112 
113 		FileFD fd;
114 		OpenStatus status;
115 	}
116 
117 	struct SRRW
118 	{
119 		import eventcore.driver : IOStatus;
120 
121 		IOStatus status;
122 		// 0 if error
123 		ulong bytesRWd;
124 	}
125 
126 	struct SRStreamConnect
127 	{
128 		import eventcore.driver : ConnectStatus;
129 
130 		StreamSocketFD fd;
131 		ConnectStatus status;
132 	}
133 
134 	struct SRDgramSendReceive
135 	{
136 		import eventcore.driver : IOStatus, RefAddress;
137 
138 		IOStatus status;
139 		// 0 if error
140 		ulong bytesRWd;
141 		RefAddress addr;
142 	}
143 
144 	struct SRSignalTrap
145 	{
146 		import eventcore.driver : SignalListenID, SignalStatus;
147 
148 		SignalListenID slID;
149 		SignalStatus status;
150 	}
151 }
152 
153 private union _SRRaw
154 {
155 	import eventcore.driver : CloseStatus;
156 
157 	SRNsLookup nsLookup;
158 	Void threadEvent;
159 	SRFileOpen fileOpen;
160 	CloseStatus fileClose;
161 	SRRW rw;
162 	int procWait;
163 	SRSignalTrap signalTrap;
164 	SRStreamConnect streamConnect;
165 	SRDgramSendReceive dgramSendReceive;
166 	Void sleep;
167 }
168 
169 public alias SuspendReturn = TaggedUnion!_SRRaw;