… | |
… | |
1496 | semantics of C<ev_stat> watchers, which means that libev sometimes needs |
1496 | semantics of C<ev_stat> watchers, which means that libev sometimes needs |
1497 | to fall back to regular polling again even with inotify, but changes are |
1497 | to fall back to regular polling again even with inotify, but changes are |
1498 | usually detected immediately, and if the file exists there will be no |
1498 | usually detected immediately, and if the file exists there will be no |
1499 | polling. |
1499 | polling. |
1500 | |
1500 | |
|
|
1501 | =head3 The special problem of stat time resolution |
|
|
1502 | |
|
|
1503 | The C<stat ()> syscall only supports full-second resolution portably, and |
|
|
1504 | even on systems where the resolution is higher, many filesystems still |
|
|
1505 | only support whole seconds. |
|
|
1506 | |
|
|
1507 | That means that, if the time is the only thing that changes, you might |
|
|
1508 | miss updates: on the first update, C<ev_stat> detects a change and calls |
|
|
1509 | your callback, which does something. When there is another update within |
|
|
1510 | the same second, C<ev_stat> will be unable to detect it. |
|
|
1511 | |
|
|
1512 | The solution to this is to delay acting on a change for a second (or till |
|
|
1513 | the next second boundary), using a roughly one-second delay C<ev_timer> |
|
|
1514 | (C<ev_timer_set (w, 0., 1.01); ev_timer_again (loop, w)>). The C<.01> |
|
|
1515 | is added to work around small timing inconsistencies of some operating |
|
|
1516 | systems. |
|
|
1517 | |
1501 | =head3 Watcher-Specific Functions and Data Members |
1518 | =head3 Watcher-Specific Functions and Data Members |
1502 | |
1519 | |
1503 | =over 4 |
1520 | =over 4 |
1504 | |
1521 | |
1505 | =item ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval) |
1522 | =item ev_stat_init (ev_stat *, callback, const char *path, ev_tstamp interval) |
… | |
… | |
1564 | } |
1581 | } |
1565 | |
1582 | |
1566 | ... |
1583 | ... |
1567 | ev_stat passwd; |
1584 | ev_stat passwd; |
1568 | |
1585 | |
1569 | ev_stat_init (&passwd, passwd_cb, "/etc/passwd"); |
1586 | ev_stat_init (&passwd, passwd_cb, "/etc/passwd", 0.); |
1570 | ev_stat_start (loop, &passwd); |
1587 | ev_stat_start (loop, &passwd); |
|
|
1588 | |
|
|
1589 | Example: Like above, but additionally use a one-second delay so we do not |
|
|
1590 | miss updates (however, frequent updates will delay processing, too, so |
|
|
1591 | one might do the work both on C<ev_stat> callback invocation I<and> on |
|
|
1592 | C<ev_timer> callback invocation). |
|
|
1593 | |
|
|
1594 | static ev_stat passwd; |
|
|
1595 | static ev_timer timer; |
|
|
1596 | |
|
|
1597 | static void |
|
|
1598 | timer_cb (EV_P_ ev_timer *w, int revents) |
|
|
1599 | { |
|
|
1600 | ev_timer_stop (EV_A_ w); |
|
|
1601 | |
|
|
1602 | /* now it's one second after the most recent passwd change */ |
|
|
1603 | } |
|
|
1604 | |
|
|
1605 | static void |
|
|
1606 | stat_cb (EV_P_ ev_stat *w, int revents) |
|
|
1607 | { |
|
|
1608 | /* reset the one-second timer */ |
|
|
1609 | ev_timer_again (EV_A_ &timer); |
|
|
1610 | } |
|
|
1611 | |
|
|
1612 | ... |
|
|
1613 | ev_stat_init (&passwd, stat_cb, "/etc/passwd", 0.); |
|
|
1614 | ev_stat_start (loop, &passwd); |
|
|
1615 | ev_timer_init (&timer, timer_cb, 0., 1.01); |
1571 | |
1616 | |
1572 | |
1617 | |
1573 | =head2 C<ev_idle> - when you've got nothing better to do... |
1618 | =head2 C<ev_idle> - when you've got nothing better to do... |
1574 | |
1619 | |
1575 | Idle watchers trigger events when no other events of the same or higher |
1620 | Idle watchers trigger events when no other events of the same or higher |
… | |
… | |
2632 | |
2677 | |
2633 | =item Starting and stopping timer/periodic watchers: O(log skipped_other_timers) |
2678 | =item Starting and stopping timer/periodic watchers: O(log skipped_other_timers) |
2634 | |
2679 | |
2635 | This means that, when you have a watcher that triggers in one hour and |
2680 | This means that, when you have a watcher that triggers in one hour and |
2636 | there are 100 watchers that would trigger before that then inserting will |
2681 | there are 100 watchers that would trigger before that then inserting will |
2637 | have to skip those 100 watchers. |
2682 | have to skip roughly seven (C<ld 100>) of these watchers. |
2638 | |
2683 | |
2639 | =item Changing timer/periodic watchers (by autorepeat, again): O(log skipped_other_timers) |
2684 | =item Changing timer/periodic watchers (by autorepeat or calling again): O(log skipped_other_timers) |
2640 | |
2685 | |
2641 | That means that for changing a timer costs less than removing/adding them |
2686 | That means that changing a timer costs less than removing/adding them |
2642 | as only the relative motion in the event queue has to be paid for. |
2687 | as only the relative motion in the event queue has to be paid for. |
2643 | |
2688 | |
2644 | =item Starting io/check/prepare/idle/signal/child watchers: O(1) |
2689 | =item Starting io/check/prepare/idle/signal/child watchers: O(1) |
2645 | |
2690 | |
2646 | These just add the watcher into an array or at the head of a list. |
2691 | These just add the watcher into an array or at the head of a list. |
|
|
2692 | |
2647 | =item Stopping check/prepare/idle watchers: O(1) |
2693 | =item Stopping check/prepare/idle watchers: O(1) |
2648 | |
2694 | |
2649 | =item Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE)) |
2695 | =item Stopping an io/signal/child watcher: O(number_of_watchers_for_this_(fd/signal/pid % EV_PID_HASHSIZE)) |
2650 | |
2696 | |
2651 | These watchers are stored in lists then need to be walked to find the |
2697 | These watchers are stored in lists then need to be walked to find the |
2652 | correct watcher to remove. The lists are usually short (you don't usually |
2698 | correct watcher to remove. The lists are usually short (you don't usually |
2653 | have many watchers waiting for the same fd or signal). |
2699 | have many watchers waiting for the same fd or signal). |
2654 | |
2700 | |
2655 | =item Finding the next timer per loop iteration: O(1) |
2701 | =item Finding the next timer in each loop iteration: O(1) |
|
|
2702 | |
|
|
2703 | By virtue of using a binary heap, the next timer is always found at the |
|
|
2704 | beginning of the storage array. |
2656 | |
2705 | |
2657 | =item Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd) |
2706 | =item Each change on a file descriptor per loop iteration: O(number_of_watchers_for_this_fd) |
2658 | |
2707 | |
2659 | A change means an I/O watcher gets started or stopped, which requires |
2708 | A change means an I/O watcher gets started or stopped, which requires |
2660 | libev to recalculate its status (and possibly tell the kernel). |
2709 | libev to recalculate its status (and possibly tell the kernel, depending |
|
|
2710 | on backend and wether C<ev_io_set> was used). |
2661 | |
2711 | |
2662 | =item Activating one watcher: O(1) |
2712 | =item Activating one watcher (putting it into the pending state): O(1) |
2663 | |
2713 | |
2664 | =item Priority handling: O(number_of_priorities) |
2714 | =item Priority handling: O(number_of_priorities) |
2665 | |
2715 | |
2666 | Priorities are implemented by allocating some space for each |
2716 | Priorities are implemented by allocating some space for each |
2667 | priority. When doing priority-based operations, libev usually has to |
2717 | priority. When doing priority-based operations, libev usually has to |
2668 | linearly search all the priorities. |
2718 | linearly search all the priorities, but starting/stopping and activating |
|
|
2719 | watchers becomes O(1) w.r.t. prioritiy handling. |
2669 | |
2720 | |
2670 | =back |
2721 | =back |
2671 | |
2722 | |
2672 | |
2723 | |
2673 | =head1 AUTHOR |
2724 | =head1 AUTHOR |