comparison modules/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 _helper <- #{
3 includeSystemHeader: "sys/epoll.h"
4 llMessage: create withVars: {
5 efd <- obj_int32 ptr
6 } andCode: {
7 efd <- make_object: (addr_of: obj_int32_meta) NULL 0
8 efd num!: (epoll_create: 8)
9 efd
10 }
11
12 llMessage: ctl withVars: {
13 oepfd <- object ptr
14 epfd <- obj_int32 ptr
15 oop <- object ptr
16 op <- obj_int32 ptr
17 ofd <- object ptr
18 fd <- obj_int32 ptr
19 omask <- object ptr
20 mask <- obj_uint32 ptr
21 data <- object ptr
22 res <- obj_int32 ptr
23 event <- struct: epoll_event
24 } andCode: :oepfd oop ofd omask data {
25 epfd <- (mcall: int32 1 oepfd) castTo: (obj_int32 ptr)
26 op <- (mcall: int32 1 oop) castTo: (obj_int32 ptr)
27 fd <- (mcall: int32 1 ofd) castTo: (obj_int32 ptr)
28 mask <- (mcall: int32 1 omask) castTo: (obj_int32 ptr)
29 res <- make_object: (addr_of: obj_int32_meta) NULL 0
30 event events!: (mask num)
31 (addr_of: (event data)) ptr!: (data)
32 res num!: (epoll_ctl: (epfd num) (op num) (fd num) (addr_of: event))
33 res
34 }
35 }
36 _constant <- macro: :name cname {
37 quote: (llMessage: name withVars: {
38 uintret <- obj_uint32 ptr
39 } andCode: {
40 uintret <- make_object: (addr_of: obj_uint32_meta) NULL 0
41 uintret num!: cname
42 uintret
43 })
44 }
45 _controlOps <- #{
46 _constant: add EPOLL_CTL_ADD
47 _constant: mod EPOLL_CTL_MOD
48 _constant: del EPOLL_CTL_DEL
49 }
50 _events <- #{
51 _constant: in EPOLLIN
52 _constant: out EPOLLOUT
53 _constant: rdhup EPOLLRDHUP
54 _constant: pri EPOLLPRI
55 _constant: err EPOLLERR
56 _constant: hup EPOLLHUP
57 _constant: et EPOLLET
58 _constant: oneshot EPOLLONESHOT
59 }
60 #{
61 events <- { _events }
62 create <- {
63 efd <- _helper create
64 if: efd >= 0 {
65 _pinData <- dict hash
66 eobj <- #{
67 llProperty: _fd withType: int32_t
68 llMessage: _set_fd withVars: {
69 ofd <- object ptr
70 ifd <- obj_int32 ptr
71 } andCode: :ofd {
72 ifd <- (mcall: int32 1 ofd) castTo: (obj_int32 ptr)
73 _fd <- ifd num
74 self
75 }
76 llMessage: fd withVars: {
77 ifd <- obj_int32 ptr
78 } andCode: {
79 ifd <- make_object: (addr_of: obj_int32_meta) NULL 0
80 ifd num!: _fd
81 ifd
82 }
83
84 addFD:withMask:data <- :nfd :mask :data {
85 if: (_helper ctl: fd (_controlOps add) nfd mask data) = 0 {
86 _pinData set: nfd data
87 true
88 }
89 }
90 deleteFD <- :dfd {
91 if: (_helper ctl: fd (_controlOps del) dfd 0u32 false) = 0 {
92 //HACK: replace data with false since we don't have a delete method on hashes yet
93 _pinData set: dfd false
94 true
95 }
96 }
97 modifyFD:setMask:data <- :mfd :mask :data {
98 if: (_helper ctl: fd (_controlOps mod) mfd mask data) = 0 {
99 _pinData set: mfd data
100 true
101 }
102 }
103
104 event:data <- :_event:_data {
105 #{
106 event <- { _event }
107 data <- { _data }
108 }
109 }
110
111 llMessage: wait:maxEvents withVars: {
112 otimeout <- object ptr
113 omaxevents <- object ptr
114 timeout <- obj_int32 ptr
115 maxevents <- obj_int32 ptr
116 events <- (struct: epoll_event) ptr
117 retarr <- array ptr
118 res <- obj_int32 ptr
119 omask <- obj_uint32 ptr
120 i <- int32_t
121 } andCode: :otimeout omaxevents {
122 timeout <- (mcall: int32 1 otimeout) castTo: (obj_int32 ptr)
123 maxevents <- (mcall: int32 1 omaxevents) castTo: (obj_int32 ptr)
124 events <- GC_MALLOC_ATOMIC: (sizeof: (struct: epoll_event)) * (maxevents num)
125 res <- make_object: (addr_of: obj_int32_meta) NULL 0
126 res num!: (epoll_wait: _fd events (maxevents num) (timeout num))
127 if: (res num) >= 0 {
128 retarr <- make_array: 0
129 mcall: resize 2 retarr res
130 i <- 0
131 while: { i < (res num) } do: {
132 omask <- make_object: (addr_of: obj_uint32_meta) NULL 0
133 omask num!: ((addr_of: (events get: i)) events)
134 mcall: append 2 retarr (mcall: event:data 3 self omask ((addr_of: ((addr_of: (events get: i)) data) ) ptr))
135 i <- i + 1
136 }
137 mcall: value 2 option retarr
138 } else: {
139 mcall: none 1 option
140 }
141 }
142
143 llMessage: close withVars: {
144 } andCode: {
145 if: (close: _fd) = 0 {
146 true
147 } else: {
148 false
149 }
150 }
151 }
152 eobj _set_fd: efd
153 option value: eobj
154 } else: {
155 option none
156 }
157 }
158 }
159 }