@@ -65,12 +65,15 @@ struct C.picoev_loop {}
65
65
66
66
struct Picoev {
67
67
loop & C.picoev_loop
68
+ is_async bool
69
+ is_cloop bool
68
70
cb fn (req picohttpparser.Request, mut res picohttpparser.Response)
69
71
cb1 fn (req picohttpparser.Request, fd int , pv voidptr )
70
72
open_cb fn (fd int ) voidptr
71
73
close_cb fn (fd int , fd_data voidptr )
72
74
cb_ext_fd_cb fn (int , voidptr )
73
75
pub mut :
76
+ cloop & C.picoev_loop
74
77
date byteptr
75
78
buf byteptr
76
79
idx [2048 ]int
@@ -213,6 +216,15 @@ fn accept_callback(loop &C.picoev_loop, fd, events int, cb_arg voidptr) {
213
216
}
214
217
}
215
218
219
+ fn accept_callback_cloop (loop & C.picoev_loop, fd, events int , cb_arg voidptr ) {
220
+ newfd := C.accept (fd, 0 , 0 )
221
+ if newfd != - 1 {
222
+ setup_sock (newfd)
223
+ mut p := & Picoev (cb_arg)
224
+ C.picoev_add (p.cloop, newfd, C.PICOEV_READ, timeout_secs, rw_callback, cb_arg)
225
+ }
226
+ }
227
+
216
228
pub fn external_fd_rw_callback (loop & C.picoev_loop, fd, events int , cb_arg voidptr ) {
217
229
if (events & C.PICOEV_READ) != 0 {
218
230
pv.cb_ext_fd_cb (fd, cb_arg)
@@ -302,8 +314,18 @@ fn accept_callback_async(loop &C.picoev_loop, fd, events int, cb_arg voidptr) {
302
314
}
303
315
}
304
316
317
+ fn accept_callback_async_cloop (loop & C.picoev_loop, fd, events int , cb_arg voidptr ) {
318
+ newfd := C.accept (fd, 0 , 0 )
319
+ if newfd != - 1 {
320
+ setup_sock (newfd)
321
+ mut p := & Picoev (cb_arg)
322
+ p.data[newfd] = p.open_cb (newfd)
323
+ C.picoev_add (p.cloop, newfd, C.PICOEV_READ, timeout_secs, rw_callback_async, cb_arg)
324
+ }
325
+ }
326
+
305
327
__global pv Picoev
306
- pub fn (pv Picoev) listen (port int , is_async bool ) {
328
+ pub fn (pv Picoev) listen (port int ) {
307
329
fd := C.socket (C.AF_INET, C.SOCK_STREAM, 0 )
308
330
assert fd != - 1
309
331
@@ -331,74 +353,75 @@ pub fn (pv Picoev) listen(port int, is_async bool) {
331
353
332
354
setup_sock (fd)
333
355
334
- if ! is_async {
335
- C.picoev_add (pv.loop, fd, C.PICOEV_READ, 0 , accept_callback, & pv)
356
+ if ! pv.is_async {
357
+ if ! pv.is_cloop {
358
+ C.picoev_add (pv.loop, fd, C.PICOEV_READ, 0 , accept_callback, & pv)
359
+ } else {
360
+ C.picoev_add (pv.loop, fd, C.PICOEV_READ, 0 , accept_callback_cloop, & pv)
361
+ }
336
362
} else {
337
- C.picoev_add (pv.loop, fd, C.PICOEV_READ, 0 , accept_callback_async, & pv)
363
+ if ! pv.is_cloop {
364
+ C.picoev_add (pv.loop, fd, C.PICOEV_READ, 0 , accept_callback_async, & pv)
365
+ } else {
366
+ C.picoev_add (pv.loop, fd, C.PICOEV_READ, 0 , accept_callback_async_cloop, & pv)
367
+ }
338
368
}
339
369
}
340
- pub fn new (port int , cb voidptr , open_cb voidptr , close_cb voidptr , cb_ext_fd_cb voidptr , is_async bool ) & Picoev {
341
- /* fd := C.socket(C.AF_INET, C.SOCK_STREAM, 0)
342
- assert fd != -1
343
-
344
- flag := 1
345
- assert C.setsockopt(fd, C.SOL_SOCKET, C.SO_REUSEADDR, &flag, sizeof(int)) == 0
346
- assert C.setsockopt(fd, C.SOL_SOCKET, C.SO_REUSEPORT, &flag, sizeof(int)) == 0
347
- $if linux {
348
- assert C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_QUICKACK, &flag, sizeof(int)) == 0
349
- timeout := 10
350
- assert C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_DEFER_ACCEPT, &timeout, sizeof(int)) == 0
351
- queue_len := 4096
352
- assert C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_FASTOPEN, &queue_len, sizeof(int)) == 0
353
- }
354
-
355
- mut addr := C.sockaddr_in{}
356
- addr.sin_family = C.AF_INET
357
- addr.sin_port = C.htons(port)
358
- addr.sin_addr.s_addr = C.htonl(C.INADDR_ANY)
359
- size := 16 // sizeof(C.sockaddr_in)
360
- bind_res := C.bind(fd, &addr, size)
361
- assert bind_res == 0
362
-
363
- listen_res := C.listen(fd, C.SOMAXCONN)
364
- assert listen_res == 0
365
-
366
- setup_sock(fd)*/
367
-
370
+ pub fn new (port int , cb voidptr , open_cb voidptr , close_cb voidptr , cb_ext_fd_cb voidptr , is_async bool , is_cloop bool ) & Picoev {
368
371
C.picoev_init (max_fds)
369
372
loop := C.picoev_create_loop (max_timeout)
370
373
if ! is_async {
371
374
mut pv := & Picoev{
372
375
loop: loop
376
+ cloop: 0
377
+ is_async: is_async
378
+ is_cloop: is_cloop
373
379
cb: cb
374
380
date: C.get_date ()
375
381
buf: malloc (max_fds * max_read + 1 )
376
382
out: malloc (max_fds * max_write + 1 )
377
383
}
378
- // C.picoev_add(loop, fd, C.PICOEV_READ, 0, accept_callback, pv)
384
+ if is_cloop {
385
+ pv.cloop = C.picoev_create_loop (max_timeout)
386
+ }
379
387
go update_date (mut pv)
380
388
return pv
381
389
} else {
382
390
mut pv := & Picoev{
383
391
loop: loop
392
+ cloop: 0
384
393
cb1 : cb
394
+ is_async: is_async
395
+ is_cloop: is_cloop
385
396
open_cb: open_cb
386
397
close_cb: close_cb
387
398
cb_ext_fd_cb: cb_ext_fd_cb
388
399
buf: malloc (max_fds * max_read + 1 )
389
400
out: malloc (max_fds * max_write + 1 )
390
401
}
391
- // C.picoev_add(loop, fd, C.PICOEV_READ, 0, accept_callback_async, pv)
402
+ if is_cloop {
403
+ pv.cloop = C.picoev_create_loop (max_timeout)
404
+ }
392
405
return pv
393
406
}
394
407
}
395
408
409
+ pub fn (p Picoev) serve_c () {
410
+ for {
411
+ C.picoev_loop_once (p.cloop, 1 )
412
+ }
413
+ }
414
+
396
415
pub fn (p Picoev) serve () {
416
+ if p.is_cloop {
417
+ go p.serve_c ()
418
+ }
397
419
for {
398
420
C.picoev_loop_once (p.loop, 1 )
399
421
}
400
422
}
401
423
424
+
402
425
fn update_date (mut p Picoev) {
403
426
for {
404
427
p.date = C.get_date ()
0 commit comments