summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--eval.c247
-rw-r--r--file.c4
-rw-r--r--gc.c2
-rw-r--r--intern.h1
-rw-r--r--io.c2
-rw-r--r--parse.y5
-rw-r--r--process.c4
-rw-r--r--sample/rbc.rb8
-rw-r--r--version.h4
10 files changed, 160 insertions, 136 deletions
diff --git a/ChangeLog b/ChangeLog
index 7a3007bf7e..9377e48555 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/eval.c b/eval.c
index 7b672d992b..d39557d2c0 100644
--- a/eval.c
+++ b/eval.c
@@ -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();
}
diff --git a/file.c b/file.c
index 0c5b148020..90e3e4d640 100644
--- a/file.c
+++ b/file.c
@@ -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:
diff --git a/gc.c b/gc.c
index 33e864d24c..7964d0df94 100644
--- a/gc.c
+++ b/gc.c
@@ -1250,6 +1250,6 @@ void
xfree(ptr)
void *ptr;
{
- return ruby_xfree(ptr);
+ ruby_xfree(ptr);
}
diff --git a/intern.h b/intern.h
index e0c365fdca..1c16c548d5 100644
--- a/intern.h
+++ b/intern.h
@@ -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));
diff --git a/io.c b/io.c
index 2ffb174675..405aa7d2d2 100644
--- a/io.c
+++ b/io.c
@@ -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 */
diff --git a/parse.y b/parse.y
index a34c5aabf3..b4a96de5c2 100644
--- a/parse.y
+++ b/parse.y
@@ -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);
diff --git a/process.c b/process.c
index a8409e4ce5..37299174fb 100644
--- a/process.c
+++ b/process.c
@@ -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
diff --git a/version.h b/version.h
index 975ae1f94b..9171d5212d 100644
--- a/version.h
+++ b/version.h
@@ -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