@@ -94,7 +94,6 @@ static ID id_locals;
9494static void sleep_timeval (rb_thread_t * th , struct timeval time , int spurious_check );
9595static void sleep_forever (rb_thread_t * th , int nodeadlock , int spurious_check );
9696static void rb_thread_sleep_deadly_allow_spurious_wakeup (void );
97- static double timeofday (void );
9897static int rb_threadptr_dead (rb_thread_t * th );
9998static void rb_check_deadlock (rb_vm_t * vm );
10099static int rb_threadptr_pending_interrupt_empty_p (const rb_thread_t * th );
@@ -201,6 +200,17 @@ vm_living_thread_num(rb_vm_t *vm)
201200 return vm -> living_thread_num ;
202201}
203202
203+ static inline struct timespec *
204+ timespec_for (struct timespec * ts , const struct timeval * tv )
205+ {
206+ if (tv ) {
207+ ts -> tv_sec = tv -> tv_sec ;
208+ ts -> tv_nsec = tv -> tv_usec * 1000 ;
209+ return ts ;
210+ }
211+ return 0 ;
212+ }
213+
204214#if THREAD_DEBUG
205215#ifdef HAVE_VA_ARGS_MACRO
206216void rb_thread_debug (const char * file , int line , const char * fmt , ...);
@@ -1245,24 +1255,6 @@ rb_thread_sleep_deadly_allow_spurious_wakeup(void)
12451255 sleep_forever (GET_THREAD (), TRUE, FALSE);
12461256}
12471257
1248- static double
1249- timeofday (void )
1250- {
1251- #if defined(HAVE_CLOCK_GETTIME ) && defined(CLOCK_MONOTONIC )
1252- struct timespec tp ;
1253-
1254- if (clock_gettime (CLOCK_MONOTONIC , & tp ) == 0 ) {
1255- return (double )tp .tv_sec + (double )tp .tv_nsec * 1e-9 ;
1256- }
1257- else
1258- #endif
1259- {
1260- struct timeval tv ;
1261- gettimeofday (& tv , NULL );
1262- return (double )tv .tv_sec + (double )tv .tv_usec * 1e-6 ;
1263- }
1264- }
1265-
12661258void
12671259rb_thread_wait_for (struct timeval time )
12681260{
@@ -3763,17 +3755,20 @@ retryable(int e)
37633755#define restore_fdset (fds1 , fds2 ) \
37643756 ((fds1) ? rb_fd_dup(fds1, fds2) : (void)0)
37653757
3766- static inline void
3767- update_timeval (struct timeval * timeout , double limit )
3758+ static inline int
3759+ update_timeval (struct timeval * timeout , const struct timeval * to )
37683760{
37693761 if (timeout ) {
3770- double d = limit - timeofday ();
3762+ struct timeval tvn ;
3763+
3764+ getclockofday (& tvn );
3765+ * timeout = * to ;
3766+ timeval_sub (timeout , & tvn );
37713767
3772- timeout -> tv_sec = (time_t )d ;
3773- timeout -> tv_usec = (int )((d - (double )timeout -> tv_sec )* 1e6 );
3774- if (timeout -> tv_sec < 0 ) timeout -> tv_sec = 0 ;
3775- if (timeout -> tv_usec < 0 ) timeout -> tv_usec = 0 ;
3768+ if (timeout -> tv_sec < 0 ) timeout -> tv_sec = 0 ;
3769+ if (timeout -> tv_usec < 0 ) timeout -> tv_usec = 0 ;
37763770 }
3771+ return TRUE;
37773772}
37783773
37793774static int
@@ -3785,22 +3780,18 @@ do_select(int n, rb_fdset_t *const readfds, rb_fdset_t *const writefds,
37853780 rb_fdset_t MAYBE_UNUSED (orig_read );
37863781 rb_fdset_t MAYBE_UNUSED (orig_write );
37873782 rb_fdset_t MAYBE_UNUSED (orig_except );
3788- double limit = 0 ;
3789- struct timeval wait_rest ;
3783+ struct timeval to ;
37903784 rb_thread_t * th = GET_THREAD ();
37913785
37923786#define do_select_update () \
37933787 (restore_fdset(readfds, &orig_read), \
37943788 restore_fdset(writefds, &orig_write), \
37953789 restore_fdset(exceptfds, &orig_except), \
3796- update_timeval(timeout, limit), \
3797- TRUE)
3790+ update_timeval(timeout, &to))
37983791
37993792 if (timeout ) {
3800- limit = timeofday ();
3801- limit += (double )timeout -> tv_sec + (double )timeout -> tv_usec * 1e-6 ;
3802- wait_rest = * timeout ;
3803- timeout = & wait_rest ;
3793+ getclockofday (& to );
3794+ timeval_add (& to , timeout );
38043795 }
38053796
38063797#define fd_init_copy (f ) \
@@ -3934,57 +3925,37 @@ ppoll(struct pollfd *fds, nfds_t nfds,
39343925}
39353926#endif
39363927
3937- static inline void
3938- update_timespec (struct timespec * timeout , double limit )
3939- {
3940- if (timeout ) {
3941- double d = limit - timeofday ();
3942-
3943- timeout -> tv_sec = (long )d ;
3944- timeout -> tv_nsec = (long )((d - (double )timeout -> tv_sec )* 1e9 );
3945- if (timeout -> tv_sec < 0 ) timeout -> tv_sec = 0 ;
3946- if (timeout -> tv_nsec < 0 ) timeout -> tv_nsec = 0 ;
3947- }
3948- }
3949-
39503928/*
39513929 * returns a mask of events
39523930 */
39533931int
3954- rb_wait_for_single_fd (int fd , int events , struct timeval * tv )
3932+ rb_wait_for_single_fd (int fd , int events , struct timeval * timeout )
39553933{
39563934 struct pollfd fds ;
39573935 int result = 0 , lerrno ;
3958- double limit = 0 ;
39593936 struct timespec ts ;
3960- struct timespec * timeout = NULL ;
3937+ struct timeval to ;
39613938 rb_thread_t * th = GET_THREAD ();
39623939
3963- #define poll_update () \
3964- (update_timespec(timeout, limit), \
3965- TRUE)
3966-
3967- if (tv ) {
3968- ts .tv_sec = tv -> tv_sec ;
3969- ts .tv_nsec = tv -> tv_usec * 1000 ;
3970- limit = timeofday ();
3971- limit += (double )tv -> tv_sec + (double )tv -> tv_usec * 1e-6 ;
3972- timeout = & ts ;
3940+ if (timeout ) {
3941+ getclockofday (& to );
3942+ timeval_add (& to , timeout );
39733943 }
39743944
39753945 fds .fd = fd ;
39763946 fds .events = (short )events ;
39773947
39783948 do {
3979- fds .revents = 0 ;
3980- lerrno = 0 ;
3981- BLOCKING_REGION ({
3982- result = ppoll (& fds , 1 , timeout , NULL );
3983- if (result < 0 ) lerrno = errno ;
3984- }, ubf_select , th , FALSE);
3985-
3986- RUBY_VM_CHECK_INTS_BLOCKING (th -> ec );
3987- } while (result < 0 && retryable (errno = lerrno ) && poll_update ());
3949+ fds .revents = 0 ;
3950+ lerrno = 0 ;
3951+ BLOCKING_REGION ({
3952+ result = ppoll (& fds , 1 , timespec_for (& ts , timeout ), NULL );
3953+ if (result < 0 ) lerrno = errno ;
3954+ }, ubf_select , th , FALSE);
3955+
3956+ RUBY_VM_CHECK_INTS_BLOCKING (th -> ec );
3957+ } while (result < 0 && retryable (errno = lerrno ) &&
3958+ update_timeval (timeout , & to ));
39883959 if (result < 0 ) return -1 ;
39893960
39903961 if (fds .revents & POLLNVAL ) {
0 commit comments