@@ -90,13 +90,28 @@ netio_remove_handler(netio_type *netio, netio_handler_type *handler)
90
90
}
91
91
}
92
92
93
+ const struct timespec *
94
+ netio_current_time (netio_type * netio )
95
+ {
96
+ assert (netio );
97
+
98
+ if (!netio -> have_current_time ) {
99
+ struct timeval current_timeval ;
100
+ if (gettimeofday (& current_timeval , NULL ) == -1 ) {
101
+ return NULL ;
102
+ }
103
+ timeval_to_timespec (& netio -> cached_current_time , & current_timeval );
104
+ netio -> have_current_time = 1 ;
105
+ }
106
+
107
+ return & netio -> cached_current_time ;
108
+ }
109
+
93
110
int
94
111
netio_dispatch (netio_type * netio , const struct timespec * timeout , const sigset_t * sigmask )
95
112
{
96
113
fd_set readfds , writefds , exceptfds ;
97
114
int max_fd ;
98
- struct timeval current_timeval ;
99
- struct timespec current_time ;
100
115
int have_timeout = 0 ;
101
116
struct timespec minimum_timeout ;
102
117
netio_handler_type * timeout_handler = NULL ;
@@ -107,14 +122,10 @@ netio_dispatch(netio_type *netio, const struct timespec *timeout, const sigset_t
107
122
assert (netio );
108
123
109
124
/*
110
- * Retrieve the current time to convert all absolute handler
111
- * timeouts to a relative timeout.
125
+ * Clear the cached current time.
112
126
*/
113
- if (gettimeofday (& current_timeval , NULL ) == -1 ) {
114
- return -1 ;
115
- }
116
- timeval_to_timespec (& current_time , & current_timeval );
117
-
127
+ netio -> have_current_time = 0 ;
128
+
118
129
/*
119
130
* Initialize the minimum timeout with the timeout parameter.
120
131
*/
@@ -153,7 +164,7 @@ netio_dispatch(netio_type *netio, const struct timespec *timeout, const sigset_t
153
164
154
165
relative .tv_sec = handler -> timeout -> tv_sec ;
155
166
relative .tv_nsec = handler -> timeout -> tv_nsec ;
156
- timespec_subtract (& relative , & current_time );
167
+ timespec_subtract (& relative , netio_current_time ( netio ) );
157
168
158
169
if (!have_timeout ||
159
170
timespec_compare (& relative , & minimum_timeout ) < 0 )
@@ -186,11 +197,11 @@ netio_dispatch(netio_type *netio, const struct timespec *timeout, const sigset_t
186
197
return -1 ;
187
198
}
188
199
189
- /* Initialize the current time member of netio. */
190
- if ( gettimeofday ( & current_timeval , NULL ) == -1 ) {
191
- return -1 ;
192
- }
193
- timeval_to_timespec ( & netio -> current_time , & current_timeval ) ;
200
+ /*
201
+ * Clear the cached current_time (pselect(2) may block for
202
+ * some time so the cached value is likely to be old).
203
+ */
204
+ netio -> have_current_time = 0 ;
194
205
195
206
if (rc == 0 ) {
196
207
/*
0 commit comments