@@ -315,6 +315,12 @@ void c_tcp_close(Int handle, Stack stack) {
315
315
uv_close (uv_handle , c_tcp_close_cb );
316
316
}
317
317
318
+
319
+ typedef struct {
320
+ Stack stack ;
321
+ struct Pos handler ;
322
+ } tcp_accept_closure_t ;
323
+
318
324
void c_tcp_listen (String host , Int port , Int backlog , Stack stack ) {
319
325
// TODO make non-async
320
326
char * host_str = c_bytearray_into_nullterminated_string (host );
@@ -358,57 +364,82 @@ void c_tcp_listen(String host, Int port, Int backlog, Stack stack) {
358
364
}
359
365
360
366
void c_tcp_accept_cb (uv_stream_t * server , int status ) {
361
- Stack stack = (Stack )server -> data ;
367
+ tcp_accept_closure_t * accept_closure = (tcp_accept_closure_t * )server -> data ;
362
368
363
369
if (status < 0 ) {
364
- resume_Int (stack , status );
370
+ // TODO resume last
371
+ erasePositive (accept_closure -> handler );
372
+ resume_Int (accept_closure -> stack , status );
373
+ free (accept_closure );
374
+ server -> data = NULL ;
365
375
return ;
366
376
}
367
377
368
378
uv_tcp_t * client = malloc (sizeof (uv_tcp_t ));
369
379
int result = uv_tcp_init (uv_default_loop (), client );
370
380
371
381
if (result < 0 ) {
382
+ // TODO resume last
372
383
free (client );
373
- // TODO share stack?
374
- resume_Int (stack , result );
384
+ erasePositive (accept_closure -> handler );
385
+ resume_Int (accept_closure -> stack , result );
386
+ free (accept_closure );
387
+ server -> data = NULL ;
375
388
return ;
376
389
}
377
390
378
391
result = uv_accept (server , (uv_stream_t * )client );
379
392
if (result < 0 ) {
393
+ // TODO resume last
380
394
uv_close ((uv_handle_t * )client , NULL );
381
395
free (client );
382
- // TODO share stack?
383
- resume_Int (stack , result );
396
+ erasePositive (accept_closure -> handler );
397
+ resume_Int (accept_closure -> stack , result );
398
+ free (accept_closure );
399
+ server -> data = NULL ;
384
400
return ;
385
401
}
386
402
387
- // TODO share resumption
388
- // shareStack(stack);
389
- resume_Int (stack , (int64_t )client );
403
+ // Call the handler with the new client connection
404
+ run_Int (unbox (accept_closure -> handler ), (int64_t )client );
390
405
}
391
406
392
- void c_tcp_accept (Int server_handle , Stack stack ) {
393
- uv_stream_t * server = (uv_stream_t * )server_handle ;
394
- server -> data = stack ; // Store stack for multiple resumes
407
+ void c_tcp_accept (Int listener , struct Pos handler , Stack stack ) {
408
+ uv_stream_t * server = (uv_stream_t * )listener ;
409
+
410
+ tcp_accept_closure_t * accept_closure = malloc (sizeof (tcp_accept_closure_t ));
411
+ accept_closure -> stack = stack ;
412
+ accept_closure -> handler = handler ;
413
+ server -> data = accept_closure ;
395
414
396
415
int result = uv_listen (server , 0 , c_tcp_accept_cb );
397
416
if (result < 0 ) {
417
+ free (accept_closure );
418
+ erasePositive (handler );
398
419
resume_Int (stack , result );
420
+ return ;
399
421
}
400
422
}
401
423
402
- void c_tcp_close_listener (Int handle , Stack stack ) {
424
+ void c_tcp_shutdown_cb (uv_handle_t * handle ) {
425
+ Stack stack = (Stack )handle -> data ;
426
+ free (handle );
427
+ // TODO resume_Pos Unit
428
+ resume_Int (stack , 0 );
429
+ }
430
+
431
+ void c_tcp_shutdown (Int handle , Stack stack ) {
403
432
uv_handle_t * uv_handle = (uv_handle_t * )handle ;
404
433
405
- Stack registered_stack = (Stack )uv_handle -> data ;
406
- if (registered_stack ) {
407
- eraseStack (registered_stack );
434
+ tcp_accept_closure_t * accept_closure = (tcp_accept_closure_t * )uv_handle -> data ;
435
+ if (accept_closure ) {
436
+ eraseStack (accept_closure -> stack );
437
+ erasePositive (accept_closure -> handler );
438
+ free (accept_closure );
408
439
}
409
440
410
441
uv_handle -> data = stack ;
411
- uv_close (uv_handle , c_tcp_close_cb );
442
+ uv_close (uv_handle , c_tcp_shutdown_cb );
412
443
}
413
444
414
445
0 commit comments