mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	[ruby/io-wait] Fix backward compatibility with earlier versions
898248931fThis commit is contained in:
		
							parent
							
								
									d305ae5f04
								
							
						
					
					
						commit
						db71a04c2e
					
				
					 2 changed files with 108 additions and 7 deletions
				
			
		|  | @ -2,6 +2,7 @@ | |||
| require 'mkmf' | ||||
| target = "io/wait" | ||||
| 
 | ||||
| have_func("rb_io_wait") | ||||
| unless macro_defined?("DOSISH", "#include <ruby.h>") | ||||
|   have_header(ioctl_h = "sys/ioctl.h") or ioctl_h = nil | ||||
|   fionread = %w[sys/ioctl.h sys/filio.h sys/socket.h].find do |h| | ||||
|  |  | |||
|  | @ -40,6 +40,37 @@ | |||
| #define FIONREAD_POSSIBLE_P(fd) ((void)(fd),Qtrue) | ||||
| #endif | ||||
| 
 | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
| static VALUE io_ready_p _((VALUE io)); | ||||
| static VALUE io_wait_readable _((int argc, VALUE *argv, VALUE io)); | ||||
| static VALUE io_wait_writable _((int argc, VALUE *argv, VALUE io)); | ||||
| void Init_wait _((void)); | ||||
| 
 | ||||
| static struct timeval * | ||||
| get_timeout(int argc, VALUE *argv, struct timeval *timerec) | ||||
| { | ||||
|     VALUE timeout = Qnil; | ||||
|     rb_check_arity(argc, 0, 1); | ||||
|     if (!argc || NIL_P(timeout = argv[0])) { | ||||
| 	return NULL; | ||||
|     } | ||||
|     else { | ||||
| 	*timerec = rb_time_interval(timeout); | ||||
| 	return timerec; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| wait_for_single_fd(rb_io_t *fptr, int events, struct timeval *tv) | ||||
| { | ||||
|     int i = rb_wait_for_single_fd(fptr->fd, events, tv); | ||||
|     if (i < 0) | ||||
| 	rb_sys_fail(0); | ||||
|     rb_io_check_closed(fptr); | ||||
|     return (i & events); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * call-seq: | ||||
|  *   io.nread -> int | ||||
|  | @ -51,12 +82,13 @@ | |||
| static VALUE | ||||
| io_nread(VALUE io) | ||||
| { | ||||
|     rb_io_t *fptr = NULL; | ||||
|     rb_io_t *fptr; | ||||
|     int len; | ||||
|     ioctl_arg n; | ||||
| 
 | ||||
|     GetOpenFile(io, fptr); | ||||
|     rb_io_check_readable(fptr); | ||||
|     int len = rb_io_read_pending(fptr); | ||||
|     len = rb_io_read_pending(fptr); | ||||
|     if (len > 0) return INT2FIX(len); | ||||
|     if (!FIONREAD_POSSIBLE_P(fptr->fd)) return INT2FIX(0); | ||||
|     if (ioctl(fptr->fd, FIONREAD, &n)) return INT2FIX(0); | ||||
|  | @ -64,6 +96,7 @@ io_nread(VALUE io) | |||
|     return INT2FIX(0); | ||||
| } | ||||
| 
 | ||||
| #ifdef HAVE_RB_IO_WAIT | ||||
| static VALUE | ||||
| io_wait_event(VALUE io, int event, VALUE timeout) | ||||
| { | ||||
|  | @ -82,6 +115,7 @@ io_wait_event(VALUE io, int event, VALUE timeout) | |||
| 	return Qfalse; | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| /*
 | ||||
|  * call-seq: | ||||
|  | @ -94,12 +128,22 @@ static VALUE | |||
| io_ready_p(VALUE io) | ||||
| { | ||||
|     rb_io_t *fptr; | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     struct timeval tv = {0, 0}; | ||||
| #endif | ||||
| 
 | ||||
|     GetOpenFile(io, fptr); | ||||
|     rb_io_check_readable(fptr); | ||||
|     if (rb_io_read_pending(fptr)) return Qtrue; | ||||
| 
 | ||||
|     return io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0)); | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     if (wait_for_single_fd(fptr, RB_WAITFD_IN, &tv)) | ||||
| 	return Qtrue; | ||||
| #else | ||||
|     if (RTEST(io_wait_event(io, RUBY_IO_READABLE, RB_INT2NUM(0)))) | ||||
| 	return Qtrue; | ||||
| #endif | ||||
|     return Qfalse; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -115,17 +159,31 @@ io_ready_p(VALUE io) | |||
| static VALUE | ||||
| io_wait_readable(int argc, VALUE *argv, VALUE io) | ||||
| { | ||||
|     rb_io_t *fptr = NULL; | ||||
|     rb_io_t *fptr; | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     struct timeval timerec; | ||||
|     struct timeval *tv; | ||||
| #endif | ||||
| 
 | ||||
|     RB_IO_POINTER(io, fptr); | ||||
|     GetOpenFile(io, fptr); | ||||
|     rb_io_check_readable(fptr); | ||||
| 
 | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     tv = get_timeout(argc, argv, &timerec); | ||||
| #endif | ||||
|     if (rb_io_read_pending(fptr)) return Qtrue; | ||||
| 
 | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     if (wait_for_single_fd(fptr, RB_WAITFD_IN, tv)) { | ||||
| 	return io; | ||||
|     } | ||||
|     return Qnil; | ||||
| #else | ||||
|     rb_check_arity(argc, 0, 1); | ||||
|     VALUE timeout = (argc == 1 ? argv[0] : Qnil); | ||||
| 
 | ||||
|     return io_wait_event(io, RUBY_IO_READABLE, timeout); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -139,17 +197,30 @@ io_wait_readable(int argc, VALUE *argv, VALUE io) | |||
| static VALUE | ||||
| io_wait_writable(int argc, VALUE *argv, VALUE io) | ||||
| { | ||||
|     rb_io_t *fptr = NULL; | ||||
|     rb_io_t *fptr; | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     struct timeval timerec; | ||||
|     struct timeval *tv; | ||||
| #endif | ||||
| 
 | ||||
|     RB_IO_POINTER(io, fptr); | ||||
|     GetOpenFile(io, fptr); | ||||
|     rb_io_check_writable(fptr); | ||||
| 
 | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     tv = get_timeout(argc, argv, &timerec); | ||||
|     if (wait_for_single_fd(fptr, RB_WAITFD_OUT, tv)) { | ||||
| 	return io; | ||||
|     } | ||||
|     return Qnil; | ||||
| #else | ||||
|     rb_check_arity(argc, 0, 1); | ||||
|     VALUE timeout = (argc == 1 ? argv[0] : Qnil); | ||||
| 
 | ||||
|     return io_wait_event(io, RUBY_IO_WRITABLE, timeout); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #ifdef HAVE_RB_IO_WAIT | ||||
| /*
 | ||||
|  * call-seq: | ||||
|  *   io.wait_priority          -> true or false | ||||
|  | @ -173,6 +244,7 @@ io_wait_priority(int argc, VALUE *argv, VALUE io) | |||
| 
 | ||||
|     return io_wait_event(io, RUBY_IO_PRIORITY, timeout); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static int | ||||
| wait_mode_sym(VALUE mode) | ||||
|  | @ -228,6 +300,31 @@ wait_mode_sym(VALUE mode) | |||
| static VALUE | ||||
| io_wait(int argc, VALUE *argv, VALUE io) | ||||
| { | ||||
| #ifndef HAVE_RB_IO_WAIT | ||||
|     rb_io_t *fptr; | ||||
|     struct timeval timerec; | ||||
|     struct timeval *tv = NULL; | ||||
|     int event = 0; | ||||
|     int i; | ||||
| 
 | ||||
|     GetOpenFile(io, fptr); | ||||
|     for (i = 0; i < argc; ++i) { | ||||
| 	if (SYMBOL_P(argv[i])) { | ||||
| 	    event |= wait_mode_sym(argv[i]); | ||||
| 	} | ||||
| 	else { | ||||
| 	    *(tv = &timerec) = rb_time_interval(argv[i]); | ||||
| 	} | ||||
|     } | ||||
|     /* rb_time_interval() and might_mode() might convert the argument */ | ||||
|     rb_io_check_closed(fptr); | ||||
|     if (!event) event = RB_WAITFD_IN; | ||||
|     if ((event & RB_WAITFD_IN) && rb_io_read_pending(fptr)) | ||||
| 	return Qtrue; | ||||
|     if (wait_for_single_fd(fptr, event, tv)) | ||||
| 	return io; | ||||
|     return Qnil; | ||||
| #else | ||||
|     VALUE timeout = Qundef; | ||||
|     rb_io_event_t events = 0; | ||||
| 
 | ||||
|  | @ -264,6 +361,7 @@ io_wait(int argc, VALUE *argv, VALUE io) | |||
|     } | ||||
| 
 | ||||
|     return io_wait_event(io, events, timeout); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | @ -284,5 +382,7 @@ Init_wait(void) | |||
| 
 | ||||
|     rb_define_method(rb_cIO, "wait_readable", io_wait_readable, -1); | ||||
|     rb_define_method(rb_cIO, "wait_writable", io_wait_writable, -1); | ||||
| #ifdef HAVE_RB_IO_WAIT | ||||
|     rb_define_method(rb_cIO, "wait_priority", io_wait_priority, -1); | ||||
| #endif | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Nobuyoshi Nakada
						Nobuyoshi Nakada