cool.io 1.1.1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev native API header
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011,2012 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
@@ -46,6 +46,8 @@
46
46
  # define EV_CPP(x)
47
47
  #endif
48
48
 
49
+ #define EV_THROW EV_CPP(throw())
50
+
49
51
  EV_CPP(extern "C" {)
50
52
 
51
53
  /*****************************************************************************/
@@ -56,7 +58,11 @@ EV_CPP(extern "C" {)
56
58
  #endif
57
59
 
58
60
  #ifndef EV_FEATURES
59
- # define EV_FEATURES 0x7f
61
+ # if defined __OPTIMIZE_SIZE__
62
+ # define EV_FEATURES 0x7c
63
+ # else
64
+ # define EV_FEATURES 0x7f
65
+ # endif
60
66
  #endif
61
67
 
62
68
  #define EV_FEATURE_CODE ((EV_FEATURES) & 1)
@@ -185,6 +191,12 @@ struct ev_loop;
185
191
  # define EV_INLINE static
186
192
  #endif
187
193
 
194
+ #ifdef EV_API_STATIC
195
+ # define EV_API_DECL static
196
+ #else
197
+ # define EV_API_DECL extern
198
+ #endif
199
+
188
200
  /* EV_PROTOTYPES can be used to switch of prototype declarations */
189
201
  #ifndef EV_PROTOTYPES
190
202
  # define EV_PROTOTYPES 1
@@ -193,33 +205,33 @@ struct ev_loop;
193
205
  /*****************************************************************************/
194
206
 
195
207
  #define EV_VERSION_MAJOR 4
196
- #define EV_VERSION_MINOR 4
208
+ #define EV_VERSION_MINOR 15
197
209
 
198
210
  /* eventmask, revents, events... */
199
211
  enum {
200
- EV_UNDEF = 0xFFFFFFFF, /* guaranteed to be invalid */
201
- EV_NONE = 0x00, /* no events */
202
- EV_READ = 0x01, /* ev_io detected read will not block */
203
- EV_WRITE = 0x02, /* ev_io detected write will not block */
204
- EV__IOFDSET = 0x80, /* internal use only */
205
- EV_IO = EV_READ, /* alias for type-detection */
206
- EV_TIMER = 0x00000100, /* timer timed out */
212
+ EV_UNDEF = (int)0xFFFFFFFF, /* guaranteed to be invalid */
213
+ EV_NONE = 0x00, /* no events */
214
+ EV_READ = 0x01, /* ev_io detected read will not block */
215
+ EV_WRITE = 0x02, /* ev_io detected write will not block */
216
+ EV__IOFDSET = 0x80, /* internal use only */
217
+ EV_IO = EV_READ, /* alias for type-detection */
218
+ EV_TIMER = 0x00000100, /* timer timed out */
207
219
  #if EV_COMPAT3
208
- EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
209
- #endif
210
- EV_PERIODIC = 0x00000200, /* periodic timer timed out */
211
- EV_SIGNAL = 0x00000400, /* signal was received */
212
- EV_CHILD = 0x00000800, /* child/pid had status change */
213
- EV_STAT = 0x00001000, /* stat data changed */
214
- EV_IDLE = 0x00002000, /* event loop is idling */
215
- EV_PREPARE = 0x00004000, /* event loop about to poll */
216
- EV_CHECK = 0x00008000, /* event loop finished poll */
217
- EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
218
- EV_FORK = 0x00020000, /* event loop resumed in child */
219
- EV_CLEANUP = 0x00040000, /* event loop resumed in child */
220
- EV_ASYNC = 0x00080000, /* async intra-loop signal */
221
- EV_CUSTOM = 0x01000000, /* for use by user code */
222
- EV_ERROR = 0x80000000 /* sent when an error occurs */
220
+ EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
221
+ #endif
222
+ EV_PERIODIC = 0x00000200, /* periodic timer timed out */
223
+ EV_SIGNAL = 0x00000400, /* signal was received */
224
+ EV_CHILD = 0x00000800, /* child/pid had status change */
225
+ EV_STAT = 0x00001000, /* stat data changed */
226
+ EV_IDLE = 0x00002000, /* event loop is idling */
227
+ EV_PREPARE = 0x00004000, /* event loop about to poll */
228
+ EV_CHECK = 0x00008000, /* event loop finished poll */
229
+ EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
230
+ EV_FORK = 0x00020000, /* event loop resumed in child */
231
+ EV_CLEANUP = 0x00040000, /* event loop resumed in child */
232
+ EV_ASYNC = 0x00080000, /* async intra-loop signal */
233
+ EV_CUSTOM = 0x01000000, /* for use by user code */
234
+ EV_ERROR = (int)0x80000000 /* sent when an error occurs */
223
235
  };
224
236
 
225
237
  /* can be used to add custom fields to all watchers, while losing binary compatibility */
@@ -321,7 +333,7 @@ typedef struct ev_periodic
321
333
 
322
334
  ev_tstamp offset; /* rw */
323
335
  ev_tstamp interval; /* rw */
324
- ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); /* rw */
336
+ ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now) EV_THROW; /* rw */
325
337
  } ev_periodic;
326
338
 
327
339
  /* invoked when the given signal has been received */
@@ -508,15 +520,15 @@ enum {
508
520
  };
509
521
 
510
522
  #if EV_PROTOTYPES
511
- int ev_version_major (void);
512
- int ev_version_minor (void);
523
+ EV_API_DECL int ev_version_major (void) EV_THROW;
524
+ EV_API_DECL int ev_version_minor (void) EV_THROW;
513
525
 
514
- unsigned int ev_supported_backends (void);
515
- unsigned int ev_recommended_backends (void);
516
- unsigned int ev_embeddable_backends (void);
526
+ EV_API_DECL unsigned int ev_supported_backends (void) EV_THROW;
527
+ EV_API_DECL unsigned int ev_recommended_backends (void) EV_THROW;
528
+ EV_API_DECL unsigned int ev_embeddable_backends (void) EV_THROW;
517
529
 
518
- ev_tstamp ev_time (void);
519
- void ev_sleep (ev_tstamp delay); /* sleep for a while */
530
+ EV_API_DECL ev_tstamp ev_time (void) EV_THROW;
531
+ EV_API_DECL void ev_sleep (ev_tstamp delay) EV_THROW; /* sleep for a while */
520
532
 
521
533
  /* Sets the allocation function to use, works like realloc.
522
534
  * It is used to allocate and free memory.
@@ -524,22 +536,26 @@ void ev_sleep (ev_tstamp delay); /* sleep for a while */
524
536
  * or take some potentially destructive action.
525
537
  * The default is your system realloc function.
526
538
  */
527
- void ev_set_allocator (void *(*cb)(void *ptr, long size));
539
+ EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW;
528
540
 
529
541
  /* set the callback function to call on a
530
542
  * retryable syscall error
531
543
  * (such as failed select, poll, epoll_wait)
532
544
  */
533
- void ev_set_syserr_cb (void (*cb)(const char *msg));
545
+ EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW;
534
546
 
535
547
  #if EV_MULTIPLICITY
536
548
 
537
549
  /* the default loop is the only one that handles signals and child watchers */
538
550
  /* you can call this as often as you like */
539
- struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
551
+ EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW;
552
+
553
+ #ifdef EV_API_STATIC
554
+ EV_API_DECL struct ev_loop *ev_default_loop_ptr;
555
+ #endif
540
556
 
541
557
  EV_INLINE struct ev_loop *
542
- ev_default_loop_uc_ (void)
558
+ ev_default_loop_uc_ (void) EV_THROW
543
559
  {
544
560
  extern struct ev_loop *ev_default_loop_ptr;
545
561
 
@@ -547,31 +563,31 @@ ev_default_loop_uc_ (void)
547
563
  }
548
564
 
549
565
  EV_INLINE int
550
- ev_is_default_loop (EV_P)
566
+ ev_is_default_loop (EV_P) EV_THROW
551
567
  {
552
568
  return EV_A == EV_DEFAULT_UC;
553
569
  }
554
570
 
555
571
  /* create and destroy alternative loops that don't handle signals */
556
- struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
572
+ EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0)) EV_THROW;
557
573
 
558
- ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
574
+ EV_API_DECL ev_tstamp ev_now (EV_P) EV_THROW; /* time w.r.t. timers and the eventloop, updated after each poll */
559
575
 
560
576
  #else
561
577
 
562
- int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
578
+ EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)) EV_THROW; /* returns true when successful */
579
+
580
+ EV_API_DECL ev_tstamp ev_rt_now;
563
581
 
564
582
  EV_INLINE ev_tstamp
565
- ev_now (void)
583
+ ev_now (void) EV_THROW
566
584
  {
567
- extern ev_tstamp ev_rt_now;
568
-
569
585
  return ev_rt_now;
570
586
  }
571
587
 
572
588
  /* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
573
589
  EV_INLINE int
574
- ev_is_default_loop (void)
590
+ ev_is_default_loop (void) EV_THROW
575
591
  {
576
592
  return 1;
577
593
  }
@@ -579,23 +595,23 @@ ev_is_default_loop (void)
579
595
  #endif /* multiplicity */
580
596
 
581
597
  /* destroy event loops, also works for the default loop */
582
- void ev_loop_destroy (EV_P);
598
+ EV_API_DECL void ev_loop_destroy (EV_P);
583
599
 
584
600
  /* this needs to be called after fork, to duplicate the loop */
585
601
  /* when you want to re-use it in the child */
586
602
  /* you can call it in either the parent or the child */
587
603
  /* you can actually call it at any time, anywhere :) */
588
- void ev_loop_fork (EV_P);
604
+ EV_API_DECL void ev_loop_fork (EV_P) EV_THROW;
589
605
 
590
- unsigned int ev_backend (EV_P); /* backend in use by loop */
606
+ EV_API_DECL unsigned int ev_backend (EV_P) EV_THROW; /* backend in use by loop */
591
607
 
592
- void ev_now_update (EV_P); /* update event loop time */
608
+ EV_API_DECL void ev_now_update (EV_P) EV_THROW; /* update event loop time */
593
609
 
594
610
  #if EV_WALK_ENABLE
595
611
  /* walk (almost) all watchers in the loop of a given type, invoking the */
596
612
  /* callback on every such watcher. The callback might stop the watcher, */
597
613
  /* but do nothing else with the loop */
598
- void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
614
+ EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW;
599
615
  #endif
600
616
 
601
617
  #endif /* prototypes */
@@ -614,45 +630,45 @@ enum {
614
630
  };
615
631
 
616
632
  #if EV_PROTOTYPES
617
- void ev_run (EV_P_ int flags EV_CPP (= 0));
618
- void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */
633
+ EV_API_DECL int ev_run (EV_P_ int flags EV_CPP (= 0));
634
+ EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)) EV_THROW; /* break out of the loop */
619
635
 
620
636
  /*
621
637
  * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
622
638
  * keeps one reference. if you have a long-running watcher you never unregister that
623
639
  * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
624
640
  */
625
- void ev_ref (EV_P);
626
- void ev_unref (EV_P);
641
+ EV_API_DECL void ev_ref (EV_P) EV_THROW;
642
+ EV_API_DECL void ev_unref (EV_P) EV_THROW;
627
643
 
628
644
  /*
629
645
  * convenience function, wait for a single event, without registering an event watcher
630
646
  * if timeout is < 0, do wait indefinitely
631
647
  */
632
- void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
648
+ EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW;
633
649
 
634
650
  # if EV_FEATURE_API
635
- unsigned int ev_iteration (EV_P); /* number of loop iterations */
636
- unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */
637
- void ev_verify (EV_P); /* abort if loop data corrupted */
651
+ EV_API_DECL unsigned int ev_iteration (EV_P) EV_THROW; /* number of loop iterations */
652
+ EV_API_DECL unsigned int ev_depth (EV_P) EV_THROW; /* #ev_loop enters - #ev_loop leaves */
653
+ EV_API_DECL void ev_verify (EV_P) EV_THROW; /* abort if loop data corrupted */
638
654
 
639
- void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
640
- void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
655
+ EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
656
+ EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW; /* sleep at least this time, default 0 */
641
657
 
642
658
  /* advanced stuff for threading etc. support, see docs */
643
- void ev_set_userdata (EV_P_ void *data);
644
- void *ev_userdata (EV_P);
645
- void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P));
646
- void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));
659
+ EV_API_DECL void ev_set_userdata (EV_P_ void *data) EV_THROW;
660
+ EV_API_DECL void *ev_userdata (EV_P) EV_THROW;
661
+ EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)) EV_THROW;
662
+ EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P) EV_THROW) EV_THROW;
647
663
 
648
- unsigned int ev_pending_count (EV_P); /* number of pending events, if any */
649
- void ev_invoke_pending (EV_P); /* invoke all pending watchers */
664
+ EV_API_DECL unsigned int ev_pending_count (EV_P) EV_THROW; /* number of pending events, if any */
665
+ EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
650
666
 
651
667
  /*
652
668
  * stop/start the timer handling.
653
669
  */
654
- void ev_suspend (EV_P);
655
- void ev_resume (EV_P);
670
+ EV_API_DECL void ev_suspend (EV_P) EV_THROW;
671
+ EV_API_DECL void ev_resume (EV_P) EV_THROW;
656
672
  #endif
657
673
 
658
674
  #endif
@@ -717,87 +733,87 @@ void ev_resume (EV_P);
717
733
  /* stopping (disabling, deleting) a watcher does nothing unless its already running */
718
734
  #if EV_PROTOTYPES
719
735
 
720
- /* feeds an event into a watcher as if the event actually occured */
736
+ /* feeds an event into a watcher as if the event actually occurred */
721
737
  /* accepts any ev_watcher type */
722
- void ev_feed_event (EV_P_ void *w, int revents);
723
- void ev_feed_fd_event (EV_P_ int fd, int revents);
738
+ EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents) EV_THROW;
739
+ EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW;
724
740
  #if EV_SIGNAL_ENABLE
725
- void ev_feed_signal (int signum);
726
- void ev_feed_signal_event (EV_P_ int signum);
741
+ EV_API_DECL void ev_feed_signal (int signum) EV_THROW;
742
+ EV_API_DECL void ev_feed_signal_event (EV_P_ int signum) EV_THROW;
727
743
  #endif
728
- void ev_invoke (EV_P_ void *w, int revents);
729
- int ev_clear_pending (EV_P_ void *w);
744
+ EV_API_DECL void ev_invoke (EV_P_ void *w, int revents);
745
+ EV_API_DECL int ev_clear_pending (EV_P_ void *w) EV_THROW;
730
746
 
731
- void ev_io_start (EV_P_ ev_io *w);
732
- void ev_io_stop (EV_P_ ev_io *w);
747
+ EV_API_DECL void ev_io_start (EV_P_ ev_io *w) EV_THROW;
748
+ EV_API_DECL void ev_io_stop (EV_P_ ev_io *w) EV_THROW;
733
749
 
734
- void ev_timer_start (EV_P_ ev_timer *w);
735
- void ev_timer_stop (EV_P_ ev_timer *w);
750
+ EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w) EV_THROW;
751
+ EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w) EV_THROW;
736
752
  /* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
737
- void ev_timer_again (EV_P_ ev_timer *w);
753
+ EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w) EV_THROW;
738
754
  /* return remaining time */
739
- ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
755
+ EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW;
740
756
 
741
757
  #if EV_PERIODIC_ENABLE
742
- void ev_periodic_start (EV_P_ ev_periodic *w);
743
- void ev_periodic_stop (EV_P_ ev_periodic *w);
744
- void ev_periodic_again (EV_P_ ev_periodic *w);
758
+ EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW;
759
+ EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW;
760
+ EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW;
745
761
  #endif
746
762
 
747
763
  /* only supported in the default loop */
748
764
  #if EV_SIGNAL_ENABLE
749
- void ev_signal_start (EV_P_ ev_signal *w);
750
- void ev_signal_stop (EV_P_ ev_signal *w);
765
+ EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w) EV_THROW;
766
+ EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w) EV_THROW;
751
767
  #endif
752
768
 
753
769
  /* only supported in the default loop */
754
770
  # if EV_CHILD_ENABLE
755
- void ev_child_start (EV_P_ ev_child *w);
756
- void ev_child_stop (EV_P_ ev_child *w);
771
+ EV_API_DECL void ev_child_start (EV_P_ ev_child *w) EV_THROW;
772
+ EV_API_DECL void ev_child_stop (EV_P_ ev_child *w) EV_THROW;
757
773
  # endif
758
774
 
759
775
  # if EV_STAT_ENABLE
760
- void ev_stat_start (EV_P_ ev_stat *w);
761
- void ev_stat_stop (EV_P_ ev_stat *w);
762
- void ev_stat_stat (EV_P_ ev_stat *w);
776
+ EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w) EV_THROW;
777
+ EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w) EV_THROW;
778
+ EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w) EV_THROW;
763
779
  # endif
764
780
 
765
781
  # if EV_IDLE_ENABLE
766
- void ev_idle_start (EV_P_ ev_idle *w);
767
- void ev_idle_stop (EV_P_ ev_idle *w);
782
+ EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w) EV_THROW;
783
+ EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w) EV_THROW;
768
784
  # endif
769
785
 
770
786
  #if EV_PREPARE_ENABLE
771
- void ev_prepare_start (EV_P_ ev_prepare *w);
772
- void ev_prepare_stop (EV_P_ ev_prepare *w);
787
+ EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW;
788
+ EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW;
773
789
  #endif
774
790
 
775
791
  #if EV_CHECK_ENABLE
776
- void ev_check_start (EV_P_ ev_check *w);
777
- void ev_check_stop (EV_P_ ev_check *w);
792
+ EV_API_DECL void ev_check_start (EV_P_ ev_check *w) EV_THROW;
793
+ EV_API_DECL void ev_check_stop (EV_P_ ev_check *w) EV_THROW;
778
794
  #endif
779
795
 
780
796
  # if EV_FORK_ENABLE
781
- void ev_fork_start (EV_P_ ev_fork *w);
782
- void ev_fork_stop (EV_P_ ev_fork *w);
797
+ EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w) EV_THROW;
798
+ EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w) EV_THROW;
783
799
  # endif
784
800
 
785
801
  # if EV_CLEANUP_ENABLE
786
- void ev_cleanup_start (EV_P_ ev_cleanup *w);
787
- void ev_cleanup_stop (EV_P_ ev_cleanup *w);
802
+ EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW;
803
+ EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW;
788
804
  # endif
789
805
 
790
806
  # if EV_EMBED_ENABLE
791
807
  /* only supported when loop to be embedded is in fact embeddable */
792
- void ev_embed_start (EV_P_ ev_embed *w);
793
- void ev_embed_stop (EV_P_ ev_embed *w);
794
- void ev_embed_sweep (EV_P_ ev_embed *w);
808
+ EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w) EV_THROW;
809
+ EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w) EV_THROW;
810
+ EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW;
795
811
  # endif
796
812
 
797
813
  # if EV_ASYNC_ENABLE
798
- void ev_async_start (EV_P_ ev_async *w);
799
- void ev_async_stop (EV_P_ ev_async *w);
800
- void ev_async_send (EV_P_ ev_async *w);
814
+ EV_API_DECL void ev_async_start (EV_P_ ev_async *w) EV_THROW;
815
+ EV_API_DECL void ev_async_stop (EV_P_ ev_async *w) EV_THROW;
816
+ EV_API_DECL void ev_async_send (EV_P_ ev_async *w) EV_THROW;
801
817
  # endif
802
818
 
803
819
  #if EV_COMPAT3
@@ -144,11 +144,13 @@ epoll_poll (EV_P_ ev_tstamp timeout)
144
144
  int i;
145
145
  int eventcnt;
146
146
 
147
+ if (expect_false (epoll_epermcnt))
148
+ timeout = 0.;
149
+
147
150
  /* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */
148
151
  /* the default libev max wait time, however. */
149
152
  EV_RELEASE_CB;
150
- eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax,
151
- epoll_epermcnt ? 0 : ev_timeout_to_ms (timeout));
153
+ eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax, timeout * 1e3);
152
154
  EV_ACQUIRE_CB;
153
155
 
154
156
  if (expect_false (eventcnt < 0))
@@ -168,8 +170,12 @@ epoll_poll (EV_P_ ev_tstamp timeout)
168
170
  int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
169
171
  | (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
170
172
 
171
- /* check for spurious notification */
172
- /* we assume that fd is always in range, as we never shrink the anfds array */
173
+ /*
174
+ * check for spurious notification.
175
+ * this only finds spurious notifications on egen updates
176
+ * other spurious notifications will be found by epoll_ctl, below
177
+ * we assume that fd is always in range, as we never shrink the anfds array
178
+ */
173
179
  if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
174
180
  {
175
181
  /* recreate kernel state */
@@ -181,8 +187,15 @@ epoll_poll (EV_P_ ev_tstamp timeout)
181
187
  {
182
188
  anfds [fd].emask = want;
183
189
 
184
- /* we received an event but are not interested in it, try mod or del */
185
- /* I don't think we ever need MOD, but let's handle it anyways */
190
+ /*
191
+ * we received an event but are not interested in it, try mod or del
192
+ * this often happens because we optimistically do not unregister fds
193
+ * when we are no longer interested in them, but also when we get spurious
194
+ * notifications for fds from another process. this is partially handled
195
+ * above with the gencounter check (== our fd is not the event fd), and
196
+ * partially here, when epoll_ctl returns an error (== a child has the fd
197
+ * but we closed it).
198
+ */
186
199
  ev->events = (want & EV_READ ? EPOLLIN : 0)
187
200
  | (want & EV_WRITE ? EPOLLOUT : 0);
188
201
 
@@ -225,7 +238,7 @@ epoll_init (EV_P_ int flags)
225
238
  #ifdef EPOLL_CLOEXEC
226
239
  backend_fd = epoll_create1 (EPOLL_CLOEXEC);
227
240
 
228
- if (backend_fd <= 0)
241
+ if (backend_fd < 0 && (errno == EINVAL || errno == ENOSYS))
229
242
  #endif
230
243
  backend_fd = epoll_create (256);
231
244
 
@@ -234,9 +247,9 @@ epoll_init (EV_P_ int flags)
234
247
 
235
248
  fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
236
249
 
237
- backend_fudge = 0.; /* kernel sources seem to indicate this to be zero */
238
- backend_modify = epoll_modify;
239
- backend_poll = epoll_poll;
250
+ backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */
251
+ backend_modify = epoll_modify;
252
+ backend_poll = epoll_poll;
240
253
 
241
254
  epoll_eventmax = 64; /* initial number of events receivable per poll */
242
255
  epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);