nio4r 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/ext/libev/ev.h CHANGED
@@ -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-
@@ -185,6 +185,12 @@ struct ev_loop;
185
185
  # define EV_INLINE static
186
186
  #endif
187
187
 
188
+ #ifdef EV_API_STATIC
189
+ # define EV_API_DECL static
190
+ #else
191
+ # define EV_API_DECL extern
192
+ #endif
193
+
188
194
  /* EV_PROTOTYPES can be used to switch of prototype declarations */
189
195
  #ifndef EV_PROTOTYPES
190
196
  # define EV_PROTOTYPES 1
@@ -193,7 +199,7 @@ struct ev_loop;
193
199
  /*****************************************************************************/
194
200
 
195
201
  #define EV_VERSION_MAJOR 4
196
- #define EV_VERSION_MINOR 4
202
+ #define EV_VERSION_MINOR 11
197
203
 
198
204
  /* eventmask, revents, events... */
199
205
  enum {
@@ -508,15 +514,15 @@ enum {
508
514
  };
509
515
 
510
516
  #if EV_PROTOTYPES
511
- int ev_version_major (void);
512
- int ev_version_minor (void);
517
+ EV_API_DECL int ev_version_major (void);
518
+ EV_API_DECL int ev_version_minor (void);
513
519
 
514
- unsigned int ev_supported_backends (void);
515
- unsigned int ev_recommended_backends (void);
516
- unsigned int ev_embeddable_backends (void);
520
+ EV_API_DECL unsigned int ev_supported_backends (void);
521
+ EV_API_DECL unsigned int ev_recommended_backends (void);
522
+ EV_API_DECL unsigned int ev_embeddable_backends (void);
517
523
 
518
- ev_tstamp ev_time (void);
519
- void ev_sleep (ev_tstamp delay); /* sleep for a while */
524
+ EV_API_DECL ev_tstamp ev_time (void);
525
+ EV_API_DECL void ev_sleep (ev_tstamp delay); /* sleep for a while */
520
526
 
521
527
  /* Sets the allocation function to use, works like realloc.
522
528
  * It is used to allocate and free memory.
@@ -524,19 +530,23 @@ void ev_sleep (ev_tstamp delay); /* sleep for a while */
524
530
  * or take some potentially destructive action.
525
531
  * The default is your system realloc function.
526
532
  */
527
- void ev_set_allocator (void *(*cb)(void *ptr, long size));
533
+ EV_API_DECL void ev_set_allocator (void *(*cb)(void *ptr, long size));
528
534
 
529
535
  /* set the callback function to call on a
530
536
  * retryable syscall error
531
537
  * (such as failed select, poll, epoll_wait)
532
538
  */
533
- void ev_set_syserr_cb (void (*cb)(const char *msg));
539
+ EV_API_DECL void ev_set_syserr_cb (void (*cb)(const char *msg));
534
540
 
535
541
  #if EV_MULTIPLICITY
536
542
 
537
543
  /* the default loop is the only one that handles signals and child watchers */
538
544
  /* you can call this as often as you like */
539
- struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
545
+ EV_API_DECL struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
546
+
547
+ #ifdef EV_API_STATIC
548
+ EV_API_DECL struct ev_loop *ev_default_loop_ptr;
549
+ #endif
540
550
 
541
551
  EV_INLINE struct ev_loop *
542
552
  ev_default_loop_uc_ (void)
@@ -553,19 +563,19 @@ ev_is_default_loop (EV_P)
553
563
  }
554
564
 
555
565
  /* create and destroy alternative loops that don't handle signals */
556
- struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
566
+ EV_API_DECL struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
557
567
 
558
- ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
568
+ EV_API_DECL ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
559
569
 
560
570
  #else
561
571
 
562
- int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
572
+ EV_API_DECL int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
573
+
574
+ EV_API_DECL ev_tstamp ev_rt_now;
563
575
 
564
576
  EV_INLINE ev_tstamp
565
577
  ev_now (void)
566
578
  {
567
- extern ev_tstamp ev_rt_now;
568
-
569
579
  return ev_rt_now;
570
580
  }
571
581
 
@@ -579,23 +589,23 @@ ev_is_default_loop (void)
579
589
  #endif /* multiplicity */
580
590
 
581
591
  /* destroy event loops, also works for the default loop */
582
- void ev_loop_destroy (EV_P);
592
+ EV_API_DECL void ev_loop_destroy (EV_P);
583
593
 
584
594
  /* this needs to be called after fork, to duplicate the loop */
585
595
  /* when you want to re-use it in the child */
586
596
  /* you can call it in either the parent or the child */
587
597
  /* you can actually call it at any time, anywhere :) */
588
- void ev_loop_fork (EV_P);
598
+ EV_API_DECL void ev_loop_fork (EV_P);
589
599
 
590
- unsigned int ev_backend (EV_P); /* backend in use by loop */
600
+ EV_API_DECL unsigned int ev_backend (EV_P); /* backend in use by loop */
591
601
 
592
- void ev_now_update (EV_P); /* update event loop time */
602
+ EV_API_DECL void ev_now_update (EV_P); /* update event loop time */
593
603
 
594
604
  #if EV_WALK_ENABLE
595
605
  /* walk (almost) all watchers in the loop of a given type, invoking the */
596
606
  /* callback on every such watcher. The callback might stop the watcher, */
597
607
  /* but do nothing else with the loop */
598
- void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
608
+ EV_API_DECL void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
599
609
  #endif
600
610
 
601
611
  #endif /* prototypes */
@@ -614,45 +624,45 @@ enum {
614
624
  };
615
625
 
616
626
  #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 */
627
+ EV_API_DECL void ev_run (EV_P_ int flags EV_CPP (= 0));
628
+ EV_API_DECL void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */
619
629
 
620
630
  /*
621
631
  * ref/unref can be used to add or remove a refcount on the mainloop. every watcher
622
632
  * keeps one reference. if you have a long-running watcher you never unregister that
623
633
  * should not keep ev_loop from running, unref() after starting, and ref() before stopping.
624
634
  */
625
- void ev_ref (EV_P);
626
- void ev_unref (EV_P);
635
+ EV_API_DECL void ev_ref (EV_P);
636
+ EV_API_DECL void ev_unref (EV_P);
627
637
 
628
638
  /*
629
639
  * convenience function, wait for a single event, without registering an event watcher
630
640
  * if timeout is < 0, do wait indefinitely
631
641
  */
632
- void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
642
+ EV_API_DECL void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
633
643
 
634
644
  # 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 */
645
+ EV_API_DECL unsigned int ev_iteration (EV_P); /* number of loop iterations */
646
+ EV_API_DECL unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */
647
+ EV_API_DECL void ev_verify (EV_P); /* abort if loop data corrupted */
638
648
 
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 */
649
+ EV_API_DECL void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
650
+ EV_API_DECL void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
641
651
 
642
652
  /* 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));
653
+ EV_API_DECL void ev_set_userdata (EV_P_ void *data);
654
+ EV_API_DECL void *ev_userdata (EV_P);
655
+ EV_API_DECL void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P));
656
+ EV_API_DECL void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));
647
657
 
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 */
658
+ EV_API_DECL unsigned int ev_pending_count (EV_P); /* number of pending events, if any */
659
+ EV_API_DECL void ev_invoke_pending (EV_P); /* invoke all pending watchers */
650
660
 
651
661
  /*
652
662
  * stop/start the timer handling.
653
663
  */
654
- void ev_suspend (EV_P);
655
- void ev_resume (EV_P);
664
+ EV_API_DECL void ev_suspend (EV_P);
665
+ EV_API_DECL void ev_resume (EV_P);
656
666
  #endif
657
667
 
658
668
  #endif
@@ -717,87 +727,87 @@ void ev_resume (EV_P);
717
727
  /* stopping (disabling, deleting) a watcher does nothing unless its already running */
718
728
  #if EV_PROTOTYPES
719
729
 
720
- /* feeds an event into a watcher as if the event actually occured */
730
+ /* feeds an event into a watcher as if the event actually occurred */
721
731
  /* 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);
732
+ EV_API_DECL void ev_feed_event (EV_P_ void *w, int revents);
733
+ EV_API_DECL void ev_feed_fd_event (EV_P_ int fd, int revents);
724
734
  #if EV_SIGNAL_ENABLE
725
- void ev_feed_signal (int signum);
726
- void ev_feed_signal_event (EV_P_ int signum);
735
+ EV_API_DECL void ev_feed_signal (int signum);
736
+ EV_API_DECL void ev_feed_signal_event (EV_P_ int signum);
727
737
  #endif
728
- void ev_invoke (EV_P_ void *w, int revents);
729
- int ev_clear_pending (EV_P_ void *w);
738
+ EV_API_DECL void ev_invoke (EV_P_ void *w, int revents);
739
+ EV_API_DECL int ev_clear_pending (EV_P_ void *w);
730
740
 
731
- void ev_io_start (EV_P_ ev_io *w);
732
- void ev_io_stop (EV_P_ ev_io *w);
741
+ EV_API_DECL void ev_io_start (EV_P_ ev_io *w);
742
+ EV_API_DECL void ev_io_stop (EV_P_ ev_io *w);
733
743
 
734
- void ev_timer_start (EV_P_ ev_timer *w);
735
- void ev_timer_stop (EV_P_ ev_timer *w);
744
+ EV_API_DECL void ev_timer_start (EV_P_ ev_timer *w);
745
+ EV_API_DECL void ev_timer_stop (EV_P_ ev_timer *w);
736
746
  /* 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);
747
+ EV_API_DECL void ev_timer_again (EV_P_ ev_timer *w);
738
748
  /* return remaining time */
739
- ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
749
+ EV_API_DECL ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
740
750
 
741
751
  #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);
752
+ EV_API_DECL void ev_periodic_start (EV_P_ ev_periodic *w);
753
+ EV_API_DECL void ev_periodic_stop (EV_P_ ev_periodic *w);
754
+ EV_API_DECL void ev_periodic_again (EV_P_ ev_periodic *w);
745
755
  #endif
746
756
 
747
757
  /* only supported in the default loop */
748
758
  #if EV_SIGNAL_ENABLE
749
- void ev_signal_start (EV_P_ ev_signal *w);
750
- void ev_signal_stop (EV_P_ ev_signal *w);
759
+ EV_API_DECL void ev_signal_start (EV_P_ ev_signal *w);
760
+ EV_API_DECL void ev_signal_stop (EV_P_ ev_signal *w);
751
761
  #endif
752
762
 
753
763
  /* only supported in the default loop */
754
764
  # if EV_CHILD_ENABLE
755
- void ev_child_start (EV_P_ ev_child *w);
756
- void ev_child_stop (EV_P_ ev_child *w);
765
+ EV_API_DECL void ev_child_start (EV_P_ ev_child *w);
766
+ EV_API_DECL void ev_child_stop (EV_P_ ev_child *w);
757
767
  # endif
758
768
 
759
769
  # 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);
770
+ EV_API_DECL void ev_stat_start (EV_P_ ev_stat *w);
771
+ EV_API_DECL void ev_stat_stop (EV_P_ ev_stat *w);
772
+ EV_API_DECL void ev_stat_stat (EV_P_ ev_stat *w);
763
773
  # endif
764
774
 
765
775
  # if EV_IDLE_ENABLE
766
- void ev_idle_start (EV_P_ ev_idle *w);
767
- void ev_idle_stop (EV_P_ ev_idle *w);
776
+ EV_API_DECL void ev_idle_start (EV_P_ ev_idle *w);
777
+ EV_API_DECL void ev_idle_stop (EV_P_ ev_idle *w);
768
778
  # endif
769
779
 
770
780
  #if EV_PREPARE_ENABLE
771
- void ev_prepare_start (EV_P_ ev_prepare *w);
772
- void ev_prepare_stop (EV_P_ ev_prepare *w);
781
+ EV_API_DECL void ev_prepare_start (EV_P_ ev_prepare *w);
782
+ EV_API_DECL void ev_prepare_stop (EV_P_ ev_prepare *w);
773
783
  #endif
774
784
 
775
785
  #if EV_CHECK_ENABLE
776
- void ev_check_start (EV_P_ ev_check *w);
777
- void ev_check_stop (EV_P_ ev_check *w);
786
+ EV_API_DECL void ev_check_start (EV_P_ ev_check *w);
787
+ EV_API_DECL void ev_check_stop (EV_P_ ev_check *w);
778
788
  #endif
779
789
 
780
790
  # if EV_FORK_ENABLE
781
- void ev_fork_start (EV_P_ ev_fork *w);
782
- void ev_fork_stop (EV_P_ ev_fork *w);
791
+ EV_API_DECL void ev_fork_start (EV_P_ ev_fork *w);
792
+ EV_API_DECL void ev_fork_stop (EV_P_ ev_fork *w);
783
793
  # endif
784
794
 
785
795
  # if EV_CLEANUP_ENABLE
786
- void ev_cleanup_start (EV_P_ ev_cleanup *w);
787
- void ev_cleanup_stop (EV_P_ ev_cleanup *w);
796
+ EV_API_DECL void ev_cleanup_start (EV_P_ ev_cleanup *w);
797
+ EV_API_DECL void ev_cleanup_stop (EV_P_ ev_cleanup *w);
788
798
  # endif
789
799
 
790
800
  # if EV_EMBED_ENABLE
791
801
  /* 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);
802
+ EV_API_DECL void ev_embed_start (EV_P_ ev_embed *w);
803
+ EV_API_DECL void ev_embed_stop (EV_P_ ev_embed *w);
804
+ EV_API_DECL void ev_embed_sweep (EV_P_ ev_embed *w);
795
805
  # endif
796
806
 
797
807
  # 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);
808
+ EV_API_DECL void ev_async_start (EV_P_ ev_async *w);
809
+ EV_API_DECL void ev_async_stop (EV_P_ ev_async *w);
810
+ EV_API_DECL void ev_async_send (EV_P_ ev_async *w);
801
811
  # endif
802
812
 
803
813
  #if EV_COMPAT3
data/ext/libev/ev_epoll.c CHANGED
@@ -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)
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);
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev kqueue backend
3
3
  *
4
- * Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008,2009,2010,2011 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-
@@ -161,9 +161,9 @@ kqueue_init (EV_P_ int flags)
161
161
 
162
162
  fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
163
163
 
164
- backend_fudge = 0.;
165
- backend_modify = kqueue_modify;
166
- backend_poll = kqueue_poll;
164
+ backend_mintime = 1e-9; /* apparently, they did the right thing in freebsd */
165
+ backend_modify = kqueue_modify;
166
+ backend_poll = kqueue_poll;
167
167
 
168
168
  kqueue_eventmax = 64; /* initial number of events receivable per poll */
169
169
  kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
data/ext/libev/ev_poll.c CHANGED
@@ -92,7 +92,7 @@ poll_poll (EV_P_ ev_tstamp timeout)
92
92
  int res;
93
93
 
94
94
  EV_RELEASE_CB;
95
- res = poll (polls, pollcnt, ev_timeout_to_ms (timeout));
95
+ res = poll (polls, pollcnt, timeout * 1e3);
96
96
  EV_ACQUIRE_CB;
97
97
 
98
98
  if (expect_false (res < 0))
@@ -129,9 +129,9 @@ poll_poll (EV_P_ ev_tstamp timeout)
129
129
  int inline_size
130
130
  poll_init (EV_P_ int flags)
131
131
  {
132
- backend_fudge = 0.; /* posix says this is zero */
133
- backend_modify = poll_modify;
134
- backend_poll = poll_poll;
132
+ backend_mintime = 1e-3;
133
+ backend_modify = poll_modify;
134
+ backend_poll = poll_poll;
135
135
 
136
136
  pollidxs = 0; pollidxmax = 0;
137
137
  polls = 0; pollmax = 0; pollcnt = 0;
data/ext/libev/ev_port.c CHANGED
@@ -147,9 +147,15 @@ port_init (EV_P_ int flags)
147
147
 
148
148
  fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
149
149
 
150
- backend_fudge = 1e-3; /* needed to compensate for port_getn returning early */
151
- backend_modify = port_modify;
152
- backend_poll = port_poll;
150
+ /* if my reading of the opensolaris kernel sources are correct, then
151
+ * opensolaris does something very stupid: it checks if the time has already
152
+ * elapsed and doesn't round up if that is the case,m otherwise it DOES round
153
+ * up. Since we can't know what the case is, we need to guess by using a
154
+ * "large enough" timeout. Normally, 1e-9 would be correct.
155
+ */
156
+ backend_mintime = 1e-3; /* needed to compensate for port_getn returning early */
157
+ backend_modify = port_modify;
158
+ backend_poll = port_poll;
153
159
 
154
160
  port_eventmax = 64; /* initial number of events receivable per poll */
155
161
  port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);