-redef interface Object
- # returns first available stream to read or write to
- # return null on interruption (possibly a signal)
- protected fun poll( streams : Sequence[FDStream] ) : nullable FDStream
- do
- var in_fds = new Array[Int]
- var out_fds = new Array[Int]
- var fd_to_stream = new HashMap[Int,FDStream]
- for s in streams do
- var fd = s.fd
- if s isa FDIStream then in_fds.add( fd )
- if s isa FDOStream then out_fds.add( fd )
-
- fd_to_stream[fd] = s
- end
-
- var polled_fd = intern_poll( in_fds, out_fds )
-
- if polled_fd == null then
- return null
- else
- return fd_to_stream[polled_fd]
- end
- end
-
- private fun intern_poll(in_fds: Array[Int], out_fds: Array[Int]) : nullable Int is extern import Array[Int].length, Array[Int].[], Int.as(nullable Int) `{
- int in_len, out_len, total_len;
- struct pollfd *c_fds;
- sigset_t sigmask;
- int i;
- int first_polled_fd = -1;
- int result;
-
- in_len = Array_of_Int_length( in_fds );
- out_len = Array_of_Int_length( out_fds );
- total_len = in_len + out_len;
- c_fds = malloc( sizeof(struct pollfd) * total_len );
-
- /* input streams */
- for ( i=0; i<in_len; i ++ ) {
- int fd;
- fd = Array_of_Int__index( in_fds, i );
-
- c_fds[i].fd = fd;
- c_fds[i].events = POLLIN;
- }
-
- /* output streams */
- for ( i=0; i<out_len; i ++ ) {
- int fd;
- fd = Array_of_Int__index( out_fds, i );
-
- c_fds[i].fd = fd;
- c_fds[i].events = POLLOUT;
- }
-
- /* poll all fds, unlimited timeout */
- result = poll( c_fds, total_len, -1 );
-
- if ( result > 0 ) {
- /* analyse results */
- for ( i=0; i<total_len; i++ )
- if ( c_fds[i].revents & c_fds[i].events || /* awaited event */
- c_fds[i].revents & POLLHUP ) /* closed */
- {
- first_polled_fd = c_fds[i].fd;
- break;
- }
-
- return Int_as_nullable( first_polled_fd );
- }
- else if ( result < 0 )
- fprintf( stderr, "Error in Stream:poll: %s\n", strerror( errno ) );
-
- return null_Int();
- `}
-end
-
-# Stream to a String.