@@ -4,51 +4,65 @@ import std::io;
4
4
import std::net;
5
5
import coroutine;
6
6
7
+ bool quit = false ;
8
+ usz server_id = 0 ;
9
+
7
10
fn void main () {
8
11
coroutine::init ();
12
+ defer coroutine::finish ();
13
+
14
+ server_id = coroutine::id ();
9
15
10
16
const String HOST = " localhost " ;
11
17
const uint PORT = 6969 ;
12
- TcpServerSocket server_sock = tcp::listen (HOST , PORT , 69 , REUSEADDR )!! ;
13
- server_sock .sock .set_non_blocking (true )!! ;
14
-
15
- io::printfn (" [%d] Listening to %s:%d " , coroutine::id (), HOST , PORT );
16
- while (true ) {
17
- coroutine::sleep_read (server_sock .sock );
18
- TcpSocket client_sock = tcp::accept (& server_sock )!! ;
19
- client_sock .sock .set_non_blocking (true )!! ;
18
+ TcpServerSocket server = tcp::listen (HOST , PORT , 69 , REUSEADDR )!! ;
19
+ server .sock .set_non_blocking (true )!! ;
20
+
21
+ io::printfn (" [%d] Server listening to %s:%d " , coroutine::id (), HOST , PORT );
22
+ while SERVER : (true ) {
23
+ coroutine::sleep_read (server .sock );
24
+ if (quit ) break SERVER ;
25
+ TcpSocket client = tcp::accept (& server )!! ;
26
+ client .sock .set_non_blocking (true )!! ;
20
27
coroutine::go (fn void (void * arg ) {
21
28
io::printfn (" [%d] Client connected! " , coroutine::id ());
22
29
23
- TcpSocket * client_sock = (TcpSocket * )arg ;
30
+ TcpSocket * client = (TcpSocket * )arg ;
24
31
char [] buf = mem::new_array (char , 1024 );
25
32
defer {
26
- client_sock .close ()!! ;
27
- free (client_sock );
33
+ client .close ()!! ;
34
+ free (client );
28
35
free (buf .ptr );
29
36
}
30
37
31
38
while OUTER : (true ) {
32
- coroutine::sleep_read (client_sock .sock );
33
- usz n = client_sock .read (buf )!! ;
39
+ coroutine::sleep_read (client .sock );
40
+ usz n = client .read (buf )!! ;
34
41
if (n == 0 ) break OUTER ;
35
42
char [] chunk = buf [0 : n ];
36
43
37
- if (((String )chunk ).trim () == " quit " ) {
38
- io::printfn (" [%d] Client requested to quit " , coroutine::id (), chunk .len );
39
- return ;
44
+ switch (((String )chunk ).trim ()) {
45
+ case " quit " :
46
+ io::printfn (" [%d] Client requested to quit " , coroutine::id (), chunk .len );
47
+ return ;
48
+ case " shutdown " :
49
+ io::printfn (" [%d] Client requested to shutdown the server " , coroutine::id ());
50
+ quit = true ;
51
+ coroutine::wake_up (server_id );
52
+ return ;
40
53
}
41
54
42
55
io::printfn (" [%d] Client sent %d bytes " , coroutine::id (), chunk .len );
43
56
44
57
while (chunk .len > 0 ) {
45
- coroutine::sleep_write (client_sock .sock );
46
- usz m = client_sock .write (chunk )!! ;
58
+ coroutine::sleep_write (client .sock );
59
+ usz m = client .write (chunk )!! ;
47
60
if (m == 0 ) break OUTER ;
48
61
chunk = chunk [m .. ];
49
62
}
50
63
}
51
64
io::printfn (" [%d] Client disconnected " , coroutine::id ());
52
- }, @clone (client_sock ));
65
+ }, @clone (client ));
53
66
}
67
+ io::printfn (" [%d] Server has been shutdown " , coroutine::id ());
54
68
}
0 commit comments