Mercurial > repos > tabletprog
comparison samples/epoll.tp @ 375:f8d80c16abbd
Add epoll module and a basic epoll sample
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 14 Aug 2015 23:08:54 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
374:368fbc9ea51b | 375:f8d80c16abbd |
---|---|
1 #{ | |
2 echo <- :sock { | |
3 print: "New connection\n" | |
4 data <- sock recv: 4096 | |
5 while: { (data length) > 0 } do: { | |
6 sock send: data | |
7 data <- sock recv: 4096 | |
8 } | |
9 print: "Connection closed\n" | |
10 } | |
11 continue? <- true | |
12 acceptHandler <- :sock ep { | |
13 epe <- epoll events | |
14 :_ { | |
15 (sock accept) value: :csock { | |
16 ep addFD: (csock fd) withMask: (epe in) data: (clientHandler: csock ep) | |
17 } none: { | |
18 print: "Failed to accept new connection\n" | |
19 } | |
20 } | |
21 } | |
22 | |
23 clientHandler <- :sock ep { | |
24 epe <- epoll events | |
25 _buffers <- #[] | |
26 waitingOut <- false | |
27 _me <- :eventMask { | |
28 if: eventMask and (epe in) != 0 { | |
29 _buffers append: (sock recv: 4096) | |
30 } | |
31 if: eventMask and (epe out) != 0 && (_buffers length) > 0 { | |
32 buf <- _buffers join: "" | |
33 _buffers <- #[] | |
34 sent <- sock send: buf | |
35 if: sent < (buf byte_length) { | |
36 _buffers append: (buf from: sent) | |
37 } | |
38 } | |
39 if: (_buffers length) > 0 { | |
40 if: (not: waitingOut) { | |
41 waitingOut <- true | |
42 ep modifyFD: (sock fd) setMask: (epe in) or (epe out) data: _me | |
43 } | |
44 } else: { | |
45 if: waitingOut { | |
46 waitingOut <- false | |
47 ep modifyFD: (sock fd) setMask: (epe in) data: _me | |
48 } | |
49 } | |
50 //TODO: Handle connection close/error | |
51 } | |
52 _me | |
53 } | |
54 | |
55 main <- :args { | |
56 port <- "2323" | |
57 if: (args length) > 1 { | |
58 port <- args get: 1 | |
59 } | |
60 (socket listenOnPort: port) value: :lsock { | |
61 print: "Listening on port " . port . "\n" | |
62 | |
63 epe <- epoll events | |
64 (epoll create) value: :ep { | |
65 ep addFD: (lsock fd) withMask: (epe in) data: (acceptHandler: lsock ep) | |
66 while: { continue? } do: { | |
67 (ep wait: -1 maxEvents: 16) value: :events { | |
68 foreach: events :idx ev { | |
69 handler <- ev data | |
70 handler: (ev event) | |
71 } | |
72 } none: { | |
73 print: "Failed to wait for events\n" | |
74 continue? <- false | |
75 } | |
76 } | |
77 } none: { | |
78 print: "Failed to create epoll file descriptor" | |
79 } | |
80 } none: { | |
81 print: "Failed to listen on port " . port . "\n" | |
82 } | |
83 } | |
84 } |