diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | eval.c | 247 | ||||
-rw-r--r-- | file.c | 4 | ||||
-rw-r--r-- | gc.c | 2 | ||||
-rw-r--r-- | intern.h | 1 | ||||
-rw-r--r-- | io.c | 2 | ||||
-rw-r--r-- | parse.y | 5 | ||||
-rw-r--r-- | process.c | 4 | ||||
-rw-r--r-- | sample/rbc.rb | 8 | ||||
-rw-r--r-- | version.h | 4 |
10 files changed, 160 insertions, 136 deletions
@@ -1,3 +1,14 @@ +Wed May 17 02:22:03 2000 Yukihiro Matsumoto <matz@netlab.co.jp> + + * eval.c (rb_thread_polling): wait 0.06 second to let other + processes run. + + * process.c (rb_waitpid): avoid busy wait using rb_thread_polling. + + * file.c (rb_thread_flock): ditto. + + * parse.y (expr): avoid calling value_expr() twice. + Wed May 17 00:45:57 2000 WATANABE Hirofumi <eban@os.rim.or.jp> * io.c (rb_io_binmode): should check PLATFORMs, not O_BINARY, sigh... @@ -10,6 +21,14 @@ Wed May 17 00:40:15 2000 Katsuyuki Komatsu <komatsu@sarion.co.jp> * win32/ruby.def: add symbol "rb_big_divmod". +Tue May 16 17:00:05 2000 Masaki Fukushima <fukusima@goto.info.waseda.ac.jp> + + * eval.c (rb_thread_select): should check whether fds are null. + +Tue May 16 11:51:31 2000 Yukihiro Matsumoto <matz@netlab.co.jp> + + * io.c (pipe_open): syncronize subprocess stdout/stderr. + Mon May 15 15:38:09 2000 Yukihiro Matsumoto <matz@netlab.co.jp> * ruby.h: exported symbols should be for xmalloc etc. are now @@ -6689,8 +6689,13 @@ rb_thread_schedule() thread_t curr; int found = 0; - int waiting_on_fd = 0; - int waiting_on_timer = 0; + fd_set readfds; + fd_set writefds; + fd_set exceptfds; + struct timeval delay_tv, *delay_ptr; + double delay, now; /* OK */ + int n, max; + int need_select = 0; select_err: rb_thread_pending = 0; @@ -6705,8 +6710,15 @@ rb_thread_schedule() curr = curr->prev; } + max = 0; + FD_ZERO(&readfds); + FD_ZERO(&writefds); + FD_ZERO(&exceptfds); + delay = DELAY_INFTY; + now = timeofday(); + FOREACH_THREAD_FROM(curr, th) { - if (!found && (th->status == THREAD_RUNNABLE || th->status == THREAD_TO_KILL)) { + if (!next && (th->status == THREAD_RUNNABLE || th->status == THREAD_TO_KILL)) { found = 1; } if ((th->wait_for&WAIT_JOIN) && rb_thread_dead(th->join)) { @@ -6715,129 +6727,104 @@ rb_thread_schedule() th->status = THREAD_RUNNABLE; found = 1; } - if (th->wait_for&(WAIT_FD|WAIT_SELECT)) waiting_on_fd = 1; - if (th->wait_for&WAIT_TIME) waiting_on_timer = 1; + if (th->wait_for & WAIT_FD) { + FD_SET(th->fd, &readfds); + if (max < th->fd) max = th->fd; + need_select = 1; + } + if (th->wait_for & WAIT_SELECT) { + copy_fds(&readfds, &th->readfds, th->fd); + copy_fds(&writefds, &th->writefds, th->fd); + copy_fds(&exceptfds, &th->exceptfds, th->fd); + th->fd = 0; + if (max < th->fd) max = th->fd; + need_select = 1; + } + if (th->wait_for & WAIT_TIME) { + if (th->delay <= now) { + th->delay = 0.0; + th->wait_for = 0; + th->status = THREAD_RUNNABLE; + found = 1; + } else if (th->delay < delay) { + delay = th->delay; + need_select = 1; + } + } } END_FOREACH_FROM(curr, th); - - if (waiting_on_fd || waiting_on_timer) { - fd_set readfds; - fd_set writefds; - fd_set exceptfds; - struct timeval delay_tv, *delay_ptr; - double delay, now; /* OK */ - int n, max; - - + + /* Do the select if needed */ + if (need_select || !found) { do { - max = 0; - FD_ZERO(&readfds); - FD_ZERO(&writefds); - FD_ZERO(&exceptfds); - if (waiting_on_fd) { - FOREACH_THREAD_FROM(curr, th) { - if (max < th->fd) max = th->fd; - if (th->wait_for & WAIT_FD) { - FD_SET(th->fd, &readfds); - } - if (th->wait_for & WAIT_SELECT) { - copy_fds(&readfds, &th->readfds, th->fd); - copy_fds(&writefds, &th->writefds, th->fd); - copy_fds(&exceptfds, &th->exceptfds, th->fd); - th->fd = 0; - } - } - END_FOREACH_FROM(curr, th); + /* Convert delay to a timeval */ + /* If a thread is runnable, just poll */ + if (found) { + delay_tv.tv_sec = 0; + delay_tv.tv_usec = 0; + delay_ptr = &delay_tv; + } + else if (delay == DELAY_INFTY) { + delay_ptr = 0; + } + else { + delay -= now; + delay_tv.tv_sec = (unsigned int)delay; + delay_tv.tv_usec = (long)((delay-(double)delay_tv.tv_sec)*1e6); + delay_ptr = &delay_tv; } - delay = DELAY_INFTY; - if (waiting_on_timer) { - now = timeofday(); - FOREACH_THREAD_FROM(curr, th) { - if (th->wait_for & WAIT_TIME) { - if (th->delay <= now) { - th->delay = 0.0; - th->wait_for = 0; - th->status = THREAD_RUNNABLE; - found = 1; - } else if (th->delay < delay) { - delay = th->delay; - } - } + n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr); + if (n < 0) { + if (rb_trap_pending) rb_trap_exec(); + switch (errno) { + case EBADF: + /* xxx */ + case ENOMEM: + n = 0; + break; + default: + goto select_err; } - END_FOREACH_FROM(curr, th); } - /* Do the select if needed */ - if (waiting_on_fd || !found) { - /* Convert delay to a timeval */ - /* If a thread is runnable, just poll */ - if (found) { - delay_tv.tv_sec = 0; - delay_tv.tv_usec = 0; - delay_ptr = &delay_tv; - } - else if (delay == DELAY_INFTY) { - delay_ptr = 0; - } - else { - delay -= now; - delay_tv.tv_sec = (unsigned int)delay; - delay_tv.tv_usec = (long)((delay-(double)delay_tv.tv_sec)*1e6); - delay_ptr = &delay_tv; - } - - n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr); - if (n < 0) { - if (rb_trap_pending) rb_trap_exec(); - switch (errno) { - case EBADF: - /* xxx */ - case ENOMEM: - n = 0; - break; - default: - goto select_err; + if (n > 0) { + /* Some descriptors are ready. + Make the corresponding threads runnable. */ + FOREACH_THREAD_FROM(curr, th) { + if ((th->wait_for&WAIT_FD) && FD_ISSET(th->fd, &readfds)) { + /* Wake up only one thread per fd. */ + FD_CLR(th->fd, &readfds); + th->status = THREAD_RUNNABLE; + th->fd = 0; + th->wait_for = 0; + found = 1; } - } - if (n > 0) { - /* Some descriptors are ready. - Make the corresponding threads runnable. */ - FOREACH_THREAD_FROM(curr, th) { - if ((th->wait_for&WAIT_FD) && FD_ISSET(th->fd, &readfds)) { - /* Wake up only one thread per fd. */ - FD_CLR(th->fd, &readfds); - th->status = THREAD_RUNNABLE; - th->fd = 0; - th->wait_for = 0; - found = 1; - } - if ((th->wait_for&WAIT_SELECT) && - (match_fds(&readfds, &th->readfds, max) || - match_fds(&writefds, &th->writefds, max) || - match_fds(&exceptfds, &th->exceptfds, max))) { - /* Wake up only one thread per fd. */ - th->status = THREAD_RUNNABLE; - th->wait_for = 0; - intersect_fds(&readfds, &th->readfds, max); - intersect_fds(&writefds, &th->writefds, max); - intersect_fds(&exceptfds, &th->exceptfds, max); - th->fd = n; - found = 1; - } + if ((th->wait_for&WAIT_SELECT) && + (match_fds(&readfds, &th->readfds, max) || + match_fds(&writefds, &th->writefds, max) || + match_fds(&exceptfds, &th->exceptfds, max))) { + /* Wake up only one thread per fd. */ + th->status = THREAD_RUNNABLE; + th->wait_for = 0; + intersect_fds(&readfds, &th->readfds, max); + intersect_fds(&writefds, &th->writefds, max); + intersect_fds(&exceptfds, &th->exceptfds, max); + th->fd = n; + found = 1; } - END_FOREACH_FROM(curr, th); } + END_FOREACH_FROM(curr, th); } - /* The delays for some of the threads should have expired. - Go through the loop once more, to check the delays. */ } while (!found && delay != DELAY_INFTY); + /* The delays for some of the threads should have expired. + Go through the loop once more, to check the delays. */ } FOREACH_THREAD_FROM(curr, th) { - if (th->status == THREAD_RUNNABLE || th->status == THREAD_TO_KILL) { - if (!next || next->priority < th->priority) + if (th->status == THREAD_RUNNABLE || th->status == THREAD_TO_KILL) { + if (!next || next->priority < th->priority) next = th; - } + } } END_FOREACH_FROM(curr, th); @@ -6884,8 +6871,8 @@ rb_thread_wait_fd(fd) if (curr_thread == curr_thread->next) return; curr_thread->status = THREAD_STOPPED; - FD_SET(fd, &curr_thread->readfds); - curr_thread->wait_for |= WAIT_FD; + curr_thread->fd = fd; + curr_thread->wait_for = WAIT_FD; rb_thread_schedule(); } @@ -6900,7 +6887,7 @@ rb_thread_fd_writable(fd) FD_ZERO(&curr_thread->writefds); FD_ZERO(&curr_thread->exceptfds); FD_SET(fd, &curr_thread->writefds); - curr_thread->wait_for |= WAIT_SELECT; + curr_thread->wait_for = WAIT_SELECT; rb_thread_schedule(); } @@ -6939,7 +6926,7 @@ rb_thread_wait_for(time) date = timeofday() + (double)time.tv_sec + (double)time.tv_usec*1e-6; curr_thread->status = THREAD_STOPPED; curr_thread->delay = date; - curr_thread->wait_for |= WAIT_TIME; + curr_thread->wait_for = WAIT_TIME; rb_thread_schedule(); } @@ -7013,20 +7000,23 @@ rb_thread_select(max, read, write, except, timeout) } curr_thread->status = THREAD_STOPPED; - curr_thread->readfds = *read; - curr_thread->writefds = *write; - curr_thread->exceptfds = *except; + if (read) curr_thread->readfds = *read; + else FD_ZERO(&curr_thread->readfds); + if (write) curr_thread->writefds = *write; + else FD_ZERO(&curr_thread->writefds); + if (except) curr_thread->exceptfds = *except; + else FD_ZERO(&curr_thread->exceptfds); curr_thread->fd = max; curr_thread->wait_for = WAIT_SELECT; if (timeout) { curr_thread->delay = timeofday() + (double)timeout->tv_sec + (double)timeout->tv_usec*1e-6; - curr_thread->wait_for |= WAIT_TIME; + curr_thread->wait_for = WAIT_TIME; } rb_thread_schedule(); - *read = curr_thread->readfds; - *write = curr_thread->writefds; - *except = curr_thread->exceptfds; + if (read) *read = curr_thread->readfds; + if (write) *write = curr_thread->writefds; + if (except) *except = curr_thread->exceptfds; return curr_thread->fd; } @@ -7043,7 +7033,7 @@ rb_thread_join(thread) rb_raise(rb_eThreadError, "Thread#join: deadlock - mutual join"); curr_thread->status = THREAD_STOPPED; curr_thread->join = th; - curr_thread->wait_for |= WAIT_JOIN; + curr_thread->wait_for = WAIT_JOIN; rb_thread_schedule(); } @@ -7172,6 +7162,17 @@ rb_thread_stop() struct timeval rb_time_timeval(); void +rb_thread_polling() +{ + if (curr_thread != curr_thread->next) { + curr_thread->status = THREAD_STOPPED; + curr_thread->delay = timeofday() + (double)0.06; + curr_thread->wait_for = WAIT_TIME; + rb_thread_schedule(); + } +} + +void rb_thread_sleep(sec) int sec; { @@ -7195,7 +7196,7 @@ rb_thread_sleep_forever() } curr_thread->delay = DELAY_INFTY; - curr_thread->wait_for |= WAIT_TIME; + curr_thread->wait_for = WAIT_TIME; curr_thread->status = THREAD_STOPPED; rb_thread_schedule(); } @@ -1468,9 +1468,9 @@ rb_thread_flock(fd, op, fptr) op |= LOCK_NB; while (flock(fd, op) < 0) { switch (errno) { - case EINTR: /* can be happen? */ + case EINTR: /* can be happen? */ case EWOULDBLOCK: - rb_thread_schedule(); /* busy wait */ + rb_thread_polling(); /* busy wait */ rb_io_check_closed(fptr); break; default: @@ -1250,6 +1250,6 @@ void xfree(ptr) void *ptr; { - return ruby_xfree(ptr); + ruby_xfree(ptr); } @@ -149,6 +149,7 @@ void rb_thread_wait_fd _((int)); int rb_thread_fd_writable _((int)); void rb_thread_fd_close _((int)); int rb_thread_alone _((void)); +void rb_thread_polling _((void)); void rb_thread_sleep _((int)); void rb_thread_sleep_forever _((void)); VALUE rb_thread_stop _((void)); @@ -1527,6 +1527,8 @@ pipe_open(pname, mode) ruby_sourcefile, ruby_sourceline, pname); _exit(127); } + rb_io_synchronized(RFILE(orig_stdout)->fptr); + rb_io_synchronized(RFILE(orig_stderr)->fptr); return Qnil; case -1: /* fork failed */ @@ -401,14 +401,12 @@ expr : mlhs '=' mrhs } | kRETURN ret_args { - value_expr($2); if (!compile_for_eval && !cur_mid && !in_single) yyerror("return appeared outside of method"); $$ = NEW_RETURN($2); } | kYIELD ret_args { - value_expr($2); $$ = NEW_YIELD($2); } | command_call @@ -4095,6 +4093,9 @@ value_expr(node) } return value_expr(node->nd_head); + case NODE_BEGIN: + return value_expr(node->nd_body); + case NODE_IF: return value_expr(node->nd_body) && value_expr(node->nd_else); @@ -93,14 +93,14 @@ rb_waitpid(pid, flags, st) #endif if (result < 0) { if (errno == EINTR) { - rb_thread_schedule(); + rb_thread_polling(); goto retry; } return -1; } if (result == 0) { if (oflags & WNOHANG) return 0; - rb_thread_schedule(); + rb_thread_polling(); if (rb_thread_alone()) flags = oflags; goto retry; } diff --git a/sample/rbc.rb b/sample/rbc.rb index 2c18d823a1..c1b2999bdf 100644 --- a/sample/rbc.rb +++ b/sample/rbc.rb @@ -127,7 +127,7 @@ module BC_APPLICATION__ else print((cont._=eval(line, bind)), "\n") end - rescue + rescue StandardError, ScriptError # $! = 'exception raised' unless $! # print "ERR: ", $!, "\n" $! = RuntimeError.new("exception raised") unless $! @@ -929,7 +929,7 @@ module BC_APPLICATION__ if File.exists?(rc) begin load rc - rescue + rescue LoadError print "load error: #{rc}\n" print $!.type, ": ", $!, "\n" for err in $@[0, $@.size - 2] @@ -946,7 +946,7 @@ module BC_APPLICATION__ for m in CONFIG[:LOAD_MODULES] begin require m - rescue + rescue LoadError print $@[0], ":", $!.type, ": ", $!, "\n" end end @@ -1004,7 +1004,7 @@ module BC_APPLICATION__ end end end - rescue + rescue LoadError CONFIG[:USE_READLINE] = FALSE end end @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.5.4" -#define RUBY_RELEASE_DATE "2000-05-16" +#define RUBY_RELEASE_DATE "2000-05-17" #define RUBY_VERSION_CODE 154 -#define RUBY_RELEASE_CODE 20000515 +#define RUBY_RELEASE_CODE 20000517 |