@@ -150,12 +150,14 @@ mod address {
150150}
151151
152152mod socket {
153+ use crate :: SocketReadinessMode ;
153154 use crate :: error:: { ErrorKind , IoError , IoOperation } ;
154155 use crate :: error:: { IoResult , Result } ;
155156 use crate :: net:: socket:: { Socket , SocketError } ;
156157 use itertools:: Itertools ;
157158 use nix:: {
158159 Error ,
160+ poll:: { PollFd , PollFlags , PollTimeout , poll} ,
159161 sys:: select:: FdSet ,
160162 sys:: time:: { TimeVal , TimeValLike } ,
161163 } ;
@@ -227,6 +229,66 @@ mod socket {
227229 . map_err ( |err| IoError :: Other ( err, IoOperation :: LocalAddr ) ) ?
228230 . as_socket ( ) )
229231 }
232+
233+ fn is_readable_select ( & self , timeout : Duration ) -> IoResult < bool > {
234+ let mut read = FdSet :: new ( ) ;
235+ read. insert ( self . inner . as_fd ( ) ) ;
236+ let readable = nix:: sys:: select:: select (
237+ None ,
238+ Some ( & mut read) ,
239+ None ,
240+ None ,
241+ Some ( & mut TimeVal :: milliseconds ( timeout. as_millis ( ) as i64 ) ) ,
242+ ) ;
243+ match readable {
244+ Ok ( readable) => Ok ( readable == 1 ) ,
245+ Err ( Error :: EINTR ) => Ok ( false ) ,
246+ Err ( err) => Err ( IoError :: Other ( io:: Error :: from ( err) , IoOperation :: Select ) ) ,
247+ }
248+ }
249+
250+ fn is_writable_select ( & self ) -> IoResult < bool > {
251+ let mut write = FdSet :: new ( ) ;
252+ write. insert ( self . inner . as_fd ( ) ) ;
253+ let writable = nix:: sys:: select:: select (
254+ None ,
255+ None ,
256+ Some ( & mut write) ,
257+ None ,
258+ Some ( & mut TimeVal :: zero ( ) ) ,
259+ ) ;
260+ match writable {
261+ Ok ( writable) => Ok ( writable == 1 ) ,
262+ Err ( Error :: EINTR ) => Ok ( false ) ,
263+ Err ( err) => Err ( IoError :: Other ( io:: Error :: from ( err) , IoOperation :: Select ) ) ,
264+ }
265+ }
266+
267+ fn is_readable_poll ( & self , timeout : Duration ) -> IoResult < bool > {
268+ let timeout = PollTimeout :: try_from ( timeout) . map_err ( |err| {
269+ IoError :: Other (
270+ io:: Error :: new ( io:: ErrorKind :: InvalidInput , err) ,
271+ IoOperation :: Poll ,
272+ )
273+ } ) ?;
274+ self . is_ready_poll ( PollFlags :: POLLIN , timeout)
275+ }
276+
277+ fn is_writable_poll ( & self ) -> IoResult < bool > {
278+ self . is_ready_poll ( PollFlags :: POLLOUT , PollTimeout :: ZERO )
279+ }
280+
281+ fn is_ready_poll ( & self , events : PollFlags , timeout : PollTimeout ) -> IoResult < bool > {
282+ let mut fds = [ PollFd :: new ( self . inner . as_fd ( ) , events) ] ;
283+ match poll ( & mut fds, timeout) {
284+ Ok ( ready) => Ok ( ready == 1
285+ && fds[ 0 ] . revents ( ) . is_some_and ( |revents| {
286+ revents. intersects ( events | PollFlags :: POLLERR | PollFlags :: POLLHUP )
287+ } ) ) ,
288+ Err ( Error :: EINTR ) => Ok ( false ) ,
289+ Err ( err) => Err ( IoError :: Other ( io:: Error :: from ( err) , IoOperation :: Poll ) ) ,
290+ }
291+ }
230292 }
231293
232294 impl Socket for SocketImpl {
@@ -386,43 +448,17 @@ mod socket {
386448 Ok ( ( ) )
387449 }
388450 #[ instrument( skip( self ) , level = "trace" ) ]
389- fn is_readable ( & mut self , timeout : Duration ) -> IoResult < bool > {
390- let mut read = FdSet :: new ( ) ;
391- read. insert ( self . inner . as_fd ( ) ) ;
392- let readable = nix:: sys:: select:: select (
393- None ,
394- Some ( & mut read) ,
395- None ,
396- None ,
397- Some ( & mut TimeVal :: milliseconds ( timeout. as_millis ( ) as i64 ) ) ,
398- ) ;
399- match readable {
400- Ok ( readable) => Ok ( readable == 1 ) ,
401- Err ( Error :: EINTR ) => Ok ( false ) ,
402- Err ( err) => Err ( IoError :: Other (
403- std:: io:: Error :: from ( err) ,
404- IoOperation :: Select ,
405- ) ) ,
451+ fn is_readable ( & mut self , timeout : Duration , mode : SocketReadinessMode ) -> IoResult < bool > {
452+ match mode {
453+ SocketReadinessMode :: Select => self . is_readable_select ( timeout) ,
454+ SocketReadinessMode :: Poll => self . is_readable_poll ( timeout) ,
406455 }
407456 }
408457 #[ instrument( skip( self ) , level = "trace" ) ]
409- fn is_writable ( & mut self ) -> IoResult < bool > {
410- let mut write = FdSet :: new ( ) ;
411- write. insert ( self . inner . as_fd ( ) ) ;
412- let writable = nix:: sys:: select:: select (
413- None ,
414- None ,
415- Some ( & mut write) ,
416- None ,
417- Some ( & mut TimeVal :: zero ( ) ) ,
418- ) ;
419- match writable {
420- Ok ( writable) => Ok ( writable == 1 ) ,
421- Err ( Error :: EINTR ) => Ok ( false ) ,
422- Err ( err) => Err ( IoError :: Other (
423- std:: io:: Error :: from ( err) ,
424- IoOperation :: Select ,
425- ) ) ,
458+ fn is_writable ( & mut self , mode : SocketReadinessMode ) -> IoResult < bool > {
459+ match mode {
460+ SocketReadinessMode :: Select => self . is_writable_select ( ) ,
461+ SocketReadinessMode :: Poll => self . is_writable_poll ( ) ,
426462 }
427463 }
428464 #[ instrument( skip( self , buf) , level = "trace" ) ]
0 commit comments