1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <atomic.h>
32
33 #include "../util/io.h"
34
35 #include "event_solaris.h"
36
37 EVHandler* evhandler_create(EventHandlerConfig *cfg) {
38 EVHandler *ev = malloc(
sizeof(EVHandler));
39 ev->current =
0;
40 ev->instances = calloc(cfg->nthreads,
sizeof(
void*));
41 ev->numins = cfg->nthreads;
42
43 for(
int i=
0;i<cfg->nthreads;i++) {
44 EventHandler *handler = malloc(
sizeof(EventHandler));
45 ev->instances[i] = handler;
46
47 handler->port = port_create();
48 if(handler->port ==
0) {
49
50 return NULL;
51 }
52
53 SYS_THREAD t = systhread_start(
54 0,
55 0,
56 (thrstartfunc)ev_handle_events,
57 handler);
58 systhread_detach(t);
59 }
60
61 return ev;
62 }
63
64 void ev_handle_events(EventHandler *ev) {
65 port_event_t events[
64];
66 struct timespec timeout;
67 timeout.tv_nsec =
0;
68 timeout.tv_sec =
600;
69
70 for(;;) {
71
72 uint_t nev =
1;
73 int ret = port_getn(ev->port, events,
64, &nev, &timeout);
74 if(ret == -
1) {
75
76 perror(
"port_getn");
77 continue;
78 }
79
80 for(
int i=
0;i<nev;i++) {
81 Event *event = events[i].portev_user;
82 if(events[i].portev_source ==
PORT_SOURCE_AIO) {
83 aiocb_t *aiocb = (
aiocb_t*)events[i].portev_object;
84 if(event) {
85 aiocb_s *aio = (aiocb_s*)event->object;
86 aio->result = aiocb->aio_resultp.aio_return;
87 aio->result_errno = aiocb->aio_resultp.aio_errno;
88 if(event->fn) {
89 if(!event->fn(ev, event) && event->finish) {
90 event->finish(ev, event);
91 }
92 }
93 }
94 free(aiocb);
95 }
else {
96 if(event->fn) {
97 if(event->fn(ev, event)) {
98
99
100
101
102
103 if(port_associate(
104 ev->port,
105 PORT_SOURCE_FD,
106 (
uintptr_t)event->object,
107 ev_convert2sys_events(event->events),
108 event))
109 {
110 perror(
"port_associate");
111 }
112 }
else if(event->finish) {
113 event->finish(ev, event);
114 }
115 }
116 }
117 }
118 }
119 }
120
121 int ev_convert2sys_events(
int events) {
122 int e =
0;
123 if((events &
EVENT_POLLIN) ==
EVENT_POLLIN) {
124 e |=
POLLIN;
125 }
126 if((events &
EVENT_POLLOUT) ==
EVENT_POLLOUT) {
127 e |=
POLLOUT;
128 }
129 return e;
130 }
131
132
133 int ev_pollin(EventHandler *h,
int fd, Event *event) {
134 event->object = (
intptr_t)fd;
135 event->events =
EVENT_POLLIN;
136 return port_associate(
137 h->port,
138 PORT_SOURCE_FD,
139 (
uintptr_t)fd,
140 POLLIN,
141 event);
142 }
143
144 int ev_pollout(EventHandler *h,
int fd, Event *event) {
145 event->object = (
intptr_t)fd;
146 event->events =
EVENT_POLLOUT;
147 return port_associate(
148 h->port,
149 PORT_SOURCE_FD,
150 (
uintptr_t)fd,
151 POLLOUT,
152 event);
153 }
154
155 int ev_remove_poll(EventHandler *h,
int fd) {
156 return port_dissociate(h->port,
PORT_SOURCE_FD, (
uintptr_t)fd);
157 }
158
159 int event_send(EventHandler *h, Event *event) {
160 event->object =
0;
161 event->events =
0;
162 return port_send(h->port,
0, event);
163 }
164
165 static int ev_aio(
int fd, aiocb_s *cb, WSBool read) {
166 EventHandler *ev = cb->evhandler;
167 if(!ev) {
168 return -
1;
169 }
170
171 aiocb_t *aiocb = malloc(
sizeof(
aiocb_t));
172 if(!aiocb) {
173 return -
1;
174 }
175 ZERO(aiocb,
sizeof(
aiocb_t));
176
177 aiocb->aio_fildes = fd;
178 aiocb->aio_buf = cb->buf;
179 aiocb->aio_nbytes = cb->nbytes;
180 aiocb->aio_offset = cb->offset;
181
182 port_notify_t *portnotify = malloc(
sizeof(
port_notify_t));
183 if(!portnotify) {
184 free(aiocb);
185 return -
1;
186 }
187 portnotify->portnfy_port = ev->port;
188 portnotify->portnfy_user = cb->event;
189 aiocb->aio_sigevent.sigev_notify =
SIGEV_PORT;
190 aiocb->aio_sigevent.sigev_value.sival_ptr = portnotify;
191
192 if(read) {
193 return aio_read(aiocb);
194 }
else {
195 return aio_write(aiocb);
196 }
197 }
198
199 int ev_aioread(
int fd, aiocb_s *cb) {
200 return ev_aio(fd, cb,
TRUE);
201 }
202
203 int ev_aiowrite(
int fd, aiocb_s *cb) {
204 return ev_aio(fd, cb,
FALSE);
205 }
206
207
208 int event_pollin(EventHandler *ev,
SYS_NETFD fd, Event *event) {
209 return ((IOStream*)fd)->poll(fd, ev,
IO_POLL_IN, event);
210 }
211
212 int event_pollout(EventHandler *ev,
SYS_NETFD fd, Event *event) {
213 return ((IOStream*)fd)->poll(fd, ev,
IO_POLL_OUT, event);
214 }
215
216 int event_removepoll(EventHandler *ev,
SYS_NETFD fd) {
217 return ((IOStream*)fd)->poll(fd, ev,
IO_POLL_NONE,
NULL);
218 }
219