ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/libev/ev_linuxaio.c
(Generate patch)

Comparing libev/ev_linuxaio.c (file contents):
Revision 1.43 by root, Mon Jul 1 21:47:42 2019 UTC vs.
Revision 1.44 by root, Tue Jul 2 06:07:54 2019 UTC

321/* get any events from ring buffer, return true if any were handled */ 321/* get any events from ring buffer, return true if any were handled */
322static int 322static int
323linuxaio_get_events_from_ring (EV_P) 323linuxaio_get_events_from_ring (EV_P)
324{ 324{
325 struct aio_ring *ring = (struct aio_ring *)linuxaio_ctx; 325 struct aio_ring *ring = (struct aio_ring *)linuxaio_ctx;
326 unsigned head, tail;
326 327
327 /* the kernel reads and writes both of these variables, */ 328 /* the kernel reads and writes both of these variables, */
328 /* as a C extension, we assume that volatile use here */ 329 /* as a C extension, we assume that volatile use here */
329 /* both makes reads atomic and once-only */ 330 /* both makes reads atomic and once-only */
330 unsigned head = *(volatile unsigned *)&ring->head; 331 head = *(volatile unsigned *)&ring->head;
332 ECB_MEMORY_FENCE_ACQUIRE;
331 unsigned tail = *(volatile unsigned *)&ring->tail; 333 tail = *(volatile unsigned *)&ring->tail;
332 334
333 if (head == tail) 335 if (head == tail)
334 return 0; 336 return 0;
335
336 /* make sure the events up to tail are visible */
337 ECB_MEMORY_FENCE_ACQUIRE;
338 337
339 /* parse all available events, but only once, to avoid starvation */ 338 /* parse all available events, but only once, to avoid starvation */
340 if (tail > head) /* normal case around */ 339 if (tail > head) /* normal case around */
341 linuxaio_parse_events (EV_A_ ring->io_events + head, tail - head); 340 linuxaio_parse_events (EV_A_ ring->io_events + head, tail - head);
342 else /* wrapped around */ 341 else /* wrapped around */
394 { 393 {
395 int res; 394 int res;
396 395
397 EV_RELEASE_CB; 396 EV_RELEASE_CB;
398 397
399 ts.tv_sec = (long)timeout; 398 EV_TS_SET (ts, timeout);
400 ts.tv_nsec = (long)((timeout - ts.tv_sec) * 1e9);
401
402 res = evsys_io_getevents (linuxaio_ctx, 1, want, ioev, &ts); 399 res = evsys_io_getevents (linuxaio_ctx, 1, want, ioev, &ts);
403 400
404 EV_ACQUIRE_CB; 401 EV_ACQUIRE_CB;
405 402
406 if (res < 0) 403 if (res < 0)
492 } 489 }
493 490
494 ++linuxaio_iteration; 491 ++linuxaio_iteration;
495 if (linuxaio_io_setup (EV_A) < 0) 492 if (linuxaio_io_setup (EV_A) < 0)
496 { 493 {
494 /* TODO: rearm all and recreate epoll backend from scratch */
495 /* TODO: might be more prudent? */
496
497 /* to bad, we can't get a new aio context, go 100% epoll */ 497 /* to bad, we can't get a new aio context, go 100% epoll */
498 linuxaio_free_iocbp (EV_A); 498 linuxaio_free_iocbp (EV_A);
499 ev_io_stop (EV_A_ &linuxaio_epoll_w); 499 ev_io_stop (EV_A_ &linuxaio_epoll_w);
500 ev_ref (EV_A); 500 ev_ref (EV_A);
501 linuxaio_ctx = 0; 501 linuxaio_ctx = 0;
502
503 backend = EVBACKEND_EPOLL;
502 backend_modify = epoll_modify; 504 backend_modify = epoll_modify;
503 backend_poll = epoll_poll; 505 backend_poll = epoll_poll;
504 } 506 }
505 507
506 timeout = 0; 508 timeout = 0;
515 res = 1; /* skip this iocb */ 517 res = 1; /* skip this iocb */
516 } 518 }
517 else if (errno == EINTR) /* not seen in reality, not documented */ 519 else if (errno == EINTR) /* not seen in reality, not documented */
518 res = 0; /* silently ignore and retry */ 520 res = 0; /* silently ignore and retry */
519 else 521 else
522 {
520 ev_syserr ("(libev) linuxaio io_submit"); 523 ev_syserr ("(libev) linuxaio io_submit");
524 res = 0;
525 }
521 526
522 submitted += res; 527 submitted += res;
523 } 528 }
524 529
525 linuxaio_submitcnt = 0; 530 linuxaio_submitcnt = 0;
553 ev_io_init (EV_A_ &linuxaio_epoll_w, linuxaio_epoll_cb, backend_fd, EV_READ); 558 ev_io_init (EV_A_ &linuxaio_epoll_w, linuxaio_epoll_cb, backend_fd, EV_READ);
554 ev_set_priority (&linuxaio_epoll_w, EV_MAXPRI); 559 ev_set_priority (&linuxaio_epoll_w, EV_MAXPRI);
555 ev_io_start (EV_A_ &linuxaio_epoll_w); 560 ev_io_start (EV_A_ &linuxaio_epoll_w);
556 ev_unref (EV_A); /* watcher should not keep loop alive */ 561 ev_unref (EV_A); /* watcher should not keep loop alive */
557 562
558 backend_modify = linuxaio_modify; 563 backend_modify = linuxaio_modify;
559 backend_poll = linuxaio_poll; 564 backend_poll = linuxaio_poll;
560 565
561 linuxaio_iocbpmax = 0; 566 linuxaio_iocbpmax = 0;
562 linuxaio_iocbps = 0; 567 linuxaio_iocbps = 0;
563 568
564 linuxaio_submits = 0; 569 linuxaio_submits = 0;
575 epoll_destroy (EV_A); 580 epoll_destroy (EV_A);
576 linuxaio_free_iocbp (EV_A); 581 linuxaio_free_iocbp (EV_A);
577 evsys_io_destroy (linuxaio_ctx); /* fails in child, aio context is destroyed */ 582 evsys_io_destroy (linuxaio_ctx); /* fails in child, aio context is destroyed */
578} 583}
579 584
580inline_size 585ecb_cold
581void 586static void
582linuxaio_fork (EV_P) 587linuxaio_fork (EV_P)
583{ 588{
584 /* this frees all iocbs, which is very heavy-handed */ 589 /* this frees all iocbs, which is very heavy-handed */
585 linuxaio_destroy (EV_A); 590 linuxaio_destroy (EV_A);
586 linuxaio_submitcnt = 0; /* all pointers were invalidated */ 591 linuxaio_submitcnt = 0; /* all pointers were invalidated */
590 while (linuxaio_io_setup (EV_A) < 0) 595 while (linuxaio_io_setup (EV_A) < 0)
591 ev_syserr ("(libev) linuxaio io_setup"); 596 ev_syserr ("(libev) linuxaio io_setup");
592 597
593 /* forking epoll should also effectively unregister all fds from the backend */ 598 /* forking epoll should also effectively unregister all fds from the backend */
594 epoll_fork (EV_A); 599 epoll_fork (EV_A);
600 /* epoll_fork already did this. hopefully */
601 /*fd_rearm_all (EV_A);*/
595 602
596 ev_io_stop (EV_A_ &linuxaio_epoll_w); 603 ev_io_stop (EV_A_ &linuxaio_epoll_w);
597 ev_io_set (EV_A_ &linuxaio_epoll_w, backend_fd, EV_READ); 604 ev_io_set (EV_A_ &linuxaio_epoll_w, backend_fd, EV_READ);
598 ev_io_start (EV_A_ &linuxaio_epoll_w); 605 ev_io_start (EV_A_ &linuxaio_epoll_w);
599
600 /* epoll_fork already did this. hopefully */
601 /*fd_rearm_all (EV_A);*/
602} 606}
603 607

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines