diff options
-rw-r--r-- | ChangeLog | 32 | ||||
-rw-r--r-- | configure | 4 | ||||
-rw-r--r-- | configure.in | 4 | ||||
-rw-r--r-- | eval.c | 106 | ||||
-rw-r--r-- | ext/socket/socket.c | 11 | ||||
-rw-r--r-- | file.c | 6 | ||||
-rw-r--r-- | gc.c | 10 | ||||
-rw-r--r-- | instruby.rb | 2 | ||||
-rw-r--r-- | intern.h | 2 | ||||
-rw-r--r-- | io.c | 18 | ||||
-rw-r--r-- | lib/weakref.rb | 7 | ||||
-rw-r--r-- | marshal.c | 4 | ||||
-rw-r--r-- | parse.c | 15 | ||||
-rw-r--r-- | parse.y | 15 | ||||
-rw-r--r-- | regex.c | 3 | ||||
-rw-r--r-- | regex.h | 15 | ||||
-rw-r--r-- | sample/test.rb | 16 | ||||
-rw-r--r-- | string.c | 4 | ||||
-rw-r--r-- | version.h | 2 |
19 files changed, 212 insertions, 64 deletions
@@ -1,3 +1,35 @@ +Fri Feb 12 16:16:47 1999 Yasuhiro Fukuma <yasuf@big.or.jp> + + * string.c (rb_str_inspect): wrong mbc position. + +Fri Feb 12 16:21:17 1999 Yukihiro Matsumoto <matz@netlab.co.jp> + + * eval.c (rb_thread_fd_close): + + * io.c (rb_io_fptr_close): tell scheduler that fd is closed. + + * io.c (rb_io_reopen): ditto. + + * io.c (READ_CHECK): check if closed after thread context switch. + + * ext/socket/socket.c (bsock_close_read): do not check + the return value from shutdown(2). + + * ext/socket/socket.c (bsock_close_write): ditto. + + * ext/socket/socket.c (sock_new): need to dup(fd) for close_read + and close_write. + + * parse.y (here_document): handle newlines within #{}. + + * regex.h: should replace symbols for ruby. + +Fri Feb 12 00:46:28 1999 Shugo Maeda <shugo@netlab.co.jp> + + * marshal.c (r_object): should update the method name in message. + + * marshal.c (w_object): limit should be converted into Fixnum. + Wed Feb 10 15:20:03 1999 Yukihiro Matsumoto <matz@netlab.co.jp> * regex.c (re_match): empty pattern should not cause infinite @@ -3801,7 +3801,7 @@ echo "configure:3765: checking whether OS depend dynamic link works" >&5 rb_cv_dlopen=yes ;; freebsd*) LDSHARED="gcc -shared" if test -x /usr/bin/objformat && \ - test `/ust/bin/objformat` = "elf" ; then + test `/usr/bin/objformat` = "elf" ; then LDFLAGS="-rdynamic" DLDFLAGS='-Wl,-soname,$(.TARGET)' rb_cv_freebsd_elf=yes @@ -4306,7 +4306,7 @@ ri_prefix= test "$program_prefix" != NONE && ri_prefix=$program_prefix -ri_suffix= +ri_suffix="${MAJOR}.${MINOR}" test "$program_suffix" != NONE && ri_suffix=$program_suffix diff --git a/configure.in b/configure.in index 95bbe7d210..069cffba8e 100644 --- a/configure.in +++ b/configure.in @@ -416,7 +416,7 @@ if test "$with_dln_a_out" != yes; then rb_cv_dlopen=yes ;; freebsd*) LDSHARED="gcc -shared" if test -x /usr/bin/objformat && \ - test `/ust/bin/objformat` = "elf" ; then + test `/usr/bin/objformat` = "elf" ; then LDFLAGS="-rdynamic" DLDFLAGS='-Wl,-soname,$(.TARGET)' rb_cv_freebsd_elf=yes @@ -681,7 +681,7 @@ ri_prefix= test "$program_prefix" != NONE && ri_prefix=$program_prefix -ri_suffix= +ri_suffix="${MAJOR}.${MINOR}" test "$program_suffix" != NONE && ri_suffix=$program_suffix @@ -2054,9 +2054,6 @@ rb_eval(self, node) case NODE_DOT2: case NODE_DOT3: result = rb_range_new(rb_eval(self, node->nd_beg), rb_eval(self, node->nd_end)); -#if 0 - break; -#else result = rb_range_new(rb_eval(self, node->nd_beg), rb_eval(self, node->nd_end)); if (node->nd_state) break; if (nd_type(node->nd_beg) == NODE_LIT && FIXNUM_P(node->nd_beg->nd_lit) && @@ -2068,7 +2065,6 @@ rb_eval(self, node) else { node->nd_state = 1; } -#endif break; case NODE_FLIP2: /* like AWK */ @@ -5974,6 +5970,12 @@ static int th_raise_line; static VALUE th_cmd; static int th_sig; +#define RESTORE_NORMAL 0 +#define RESTORE_FATAL 1 +#define RESTORE_INTERRUPT 2 +#define RESTORE_TRAP 3 +#define RESTORE_RAISE 4 + static void rb_thread_restore_context(th, exit) thread_t th; @@ -6022,26 +6024,27 @@ rb_thread_restore_context(th, exit) rb_backref_set(tmp->last_match); switch (ex) { - case 1: + case RESTORE_FATAL: JUMP_TAG(TAG_FATAL); break; - case 2: + case RESTORE_INTERRUPT: rb_interrupt(); break; - case 3: + case RESTORE_TRAP: rb_trap_eval(th_cmd, th_sig); errno = EINTR; break; - case 4: + case RESTORE_RAISE: ruby_frame->last_func = 0; ruby_sourcefile = th_raise_file; ruby_sourceline = th_raise_line; rb_f_raise(th_raise_argc, th_raise_argv); break; + case RESTORE_NORMAL: default: longjmp(tmp->context, 1); } @@ -6081,15 +6084,69 @@ rb_thread_dead(th) return th->status == THREAD_KILLED; } +void +rb_thread_fd_close(fd) + int fd; +{ + thread_t th; + + FOREACH_THREAD(th) { + if ((th->wait_for & WAIT_FD) && th->fd == fd) { + th_raise_argc = 1; + th_raise_argv[0] = rb_exc_new2(rb_eIOError, "stream closed"); + th_raise_file = ruby_sourcefile; + th_raise_line = ruby_sourceline; + curr_thread = th; + rb_thread_restore_context(main_thread, RESTORE_RAISE); + } + } + END_FOREACH(th); +} + +static void +rb_thread_badf() +{ + thread_t th; + int max; + struct timeval delay_tv; + fd_set readfds; + + delay_tv.tv_sec = 0; + delay_tv.tv_usec = 0; + FOREACH_THREAD(th) { + if (th->wait_for & WAIT_FD) { + FD_ZERO(&readfds); + FD_SET(th->fd, &readfds); + if (select(th->fd+1, &readfds, 0, 0, &delay_tv) < 0 && + errno == EBADF) { + rb_thread_ready(th); + th->status = THREAD_TO_KILL; + } + } + } + END_FOREACH(th); +} + static void rb_thread_deadlock() { + static int invoked = 0; + + if (invoked) return; + invoked = 1; curr_thread = main_thread; +#if 0 th_raise_argc = 1; th_raise_argv[0] = rb_exc_new2(rb_eFatal, "Thread: deadlock"); th_raise_file = ruby_sourcefile; th_raise_line = ruby_sourceline; + rb_thread_restore_context(main_thread, RESTORE_RAISE); +#else + rb_prohibit_interrupt = 1; + ruby_errinfo = rb_exc_new2(rb_eFatal, "Thread: deadlock"); + set_backtrace(ruby_errinfo, make_backtrace()); rb_abort(); +#endif } void @@ -6191,7 +6248,15 @@ rb_thread_schedule() n = select(max+1, &readfds, 0, 0, delay_ptr); if (n < 0) { if (rb_trap_pending) rb_trap_exec(); - goto select_err; + switch (errno) { + case EBADF: + rb_thread_badf(); + case ENOMEM: + n = 0; + break; + default: + goto select_err; + } } if (n > 0) { /* Some descriptors are ready. @@ -6223,10 +6288,15 @@ rb_thread_schedule() fprintf(stderr, "%s:%d:deadlock 0x%x: %d:%d %s\n", th->file, th->line, th->thread, th->status, th->wait_for, th==main_thread?"(main)":""); + if (th->status == THREAD_STOPPED) { + next = th; + } } END_FOREACH_FROM(curr, th); /* raise fatal error to main thread */ rb_thread_deadlock(); + rb_thread_ready(next); + next->status = THREAD_TO_KILL; } if (next->status == THREAD_RUNNABLE && next == curr_thread) { return; @@ -6243,9 +6313,9 @@ rb_thread_schedule() curr_thread = next; if (next->status == THREAD_TO_KILL) { /* execute ensure-clause if any */ - rb_thread_restore_context(next, 1); + rb_thread_restore_context(next, RESTORE_FATAL); } - rb_thread_restore_context(next, 0); + rb_thread_restore_context(next, RESTORE_NORMAL); } void @@ -6261,20 +6331,20 @@ rb_thread_wait_fd(fd) rb_thread_schedule(); } -void +int rb_thread_fd_writable(fd) int fd; { struct timeval zero; fd_set fds; - if (curr_thread == curr_thread->next) return; + if (curr_thread == curr_thread->next) return 1; zero.tv_sec = zero.tv_usec = 0; for (;;) { FD_ZERO(&fds); FD_SET(fd, &fds); - if (select(fd+1, 0, &fds, 0, &zero) == 1) break; + if (select(fd+1, 0, &fds, 0, &zero) == 1) return 0; rb_thread_schedule(); } } @@ -6895,7 +6965,7 @@ rb_thread_interrupt() return; } curr_thread = main_thread; - rb_thread_restore_context(curr_thread, 2); + rb_thread_restore_context(curr_thread, RESTORE_INTERRUPT); } void @@ -6917,7 +6987,7 @@ rb_thread_trap_eval(cmd, sig) th_cmd = cmd; th_sig = sig; curr_thread = main_thread; - rb_thread_restore_context(curr_thread, 3); + rb_thread_restore_context(curr_thread, RESTORE_TRAP); } static VALUE @@ -6946,7 +7016,7 @@ rb_thread_raise(argc, argv, thread) th_raise_argc = argc; th_raise_file = ruby_sourcefile; th_raise_line = ruby_sourceline; - rb_thread_restore_context(curr_thread, 4); + rb_thread_restore_context(curr_thread, RESTORE_RAISE); return Qnil; /* not reached */ } @@ -7086,7 +7156,7 @@ rb_continuation_call(argc, argv, cont) th->result = rb_ary_new4(argc, argv); break; } - rb_thread_restore_context(th, 0); + rb_thread_restore_context(th, RESTORE_NORMAL); return Qnil; } diff --git a/ext/socket/socket.c b/ext/socket/socket.c index e9bdbc9e8c..875c8aa5fb 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -96,6 +96,8 @@ sock_new(class, fd) fp->f = rb_fdopen(fd, "r"); #ifdef NT fp->finalize = sock_finalize; +#else + fd = dup(fd); #endif fp->f2 = rb_fdopen(fd, "w"); fp->mode = FMODE_READWRITE; @@ -140,11 +142,13 @@ bsock_close_read(sock) rb_secure(4); GetOpenFile(sock, fptr); + shutdown(fileno(fptr->f), 0); if (fptr->f2 == 0) { return rb_io_close(sock); } - if (shutdown(fileno(fptr->f), 0) == -1) - rb_sys_fail(0); +#ifdef USE_THREAD + rb_thread_fd_close(fileno(fptr->f)); +#endif fptr->mode &= ~FMODE_READABLE; #ifdef NT free(fptr->f); @@ -168,8 +172,7 @@ bsock_close_write(sock) if (fptr->f2 == 0) { return rb_io_close(sock); } - if (shutdown(fileno(fptr->f), 1) == -1) - rb_sys_fail(0); + shutdown(fileno(fptr->f2), 1); fptr->mode &= ~FMODE_WRITABLE; #ifdef NT free(fptr->f2); @@ -1302,8 +1302,9 @@ rb_file_truncate(obj, len) #if defined(USE_THREAD) && defined(EWOULDBLOCK) static int -rb_thread_flock(fd, op) +rb_thread_flock(fd, op, fptr) int fd, op; + OpenFile *fptr; { if (rb_thread_alone() || (op & LOCK_NB)) { return flock(fd, op); @@ -1314,6 +1315,7 @@ rb_thread_flock(fd, op) case EINTR: /* can be happen? */ case EWOULDBLOCK: rb_thread_schedule(); /* busy wait */ + rb_io_check_closed(fptr); break; default: return -1; @@ -1321,7 +1323,7 @@ rb_thread_flock(fd, op) } return 0; } -#define flock rb_thread_flock +#define flock(fd, op) rb_thread_flock(fd, op, fptr) #endif static VALUE @@ -389,10 +389,10 @@ rb_gc_mark(ptr) register RVALUE *obj = RANY(ptr); Top: - if (FIXNUM_P(obj)) return; /* fixnum not marked */ + if (FIXNUM_P(obj)) return; /* fixnum not marked */ if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */ - if (obj->as.basic.flags == 0) return; /* free cell */ - if (obj->as.basic.flags & FL_MARK) return; /* already marked */ + if (obj->as.basic.flags == 0) return; /* free cell */ + if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; @@ -770,10 +770,10 @@ obj_free(obj) } break; case T_MATCH: - if (RANY(obj)->as.match.regs) + if (RANY(obj)->as.match.regs) { re_free_registers(RANY(obj)->as.match.regs); - if (RANY(obj)->as.match.regs) free(RANY(obj)->as.match.regs); + } break; case T_FILE: if (RANY(obj)->as.file.fptr) { diff --git a/instruby.rb b/instruby.rb index f01dae9004..6f46f86ee2 100644 --- a/instruby.rb +++ b/instruby.rb @@ -24,7 +24,7 @@ mandir = destdir+CONFIG["mandir"] + "/man1" wdir = Dir.getwd File.makedirs bindir, true -File.install "ruby#{binsuffix}", +File.install ruby_install_name+binsuffix, "#{bindir}/#{ruby_install_name}#{binsuffix}", 0755, true for dll in Dir['*.dll'] File.install dll, "#{bindir}/#{dll}", 0755, true @@ -127,7 +127,7 @@ void rb_thread_start_timer _((void)); void rb_thread_stop_timer _((void)); void rb_thread_schedule _((void)); void rb_thread_wait_fd _((int)); -void rb_thread_fd_writable _((int)); +int rb_thread_fd_writable _((int)); int rb_thread_alone _((void)); void rb_thread_sleep _((int)); void rb_thread_sleep_forever _((void)); @@ -111,7 +111,10 @@ extern int ReadDataPending(); # define READ_CHECK(fp) 0 #else # define READ_CHECK(fp) do {\ - if (!READ_DATA_PENDING(fp)) rb_thread_wait_fd(fileno(fp));\ + if (!READ_DATA_PENDING(fp)) {\ + rb_thread_wait_fd(fileno(fp));\ + rb_io_check_closed(fptr);\ + }\ } while(0) #endif @@ -841,8 +844,14 @@ static void rb_io_fptr_close(fptr) OpenFile *fptr; { + int fd; + if (fptr->f == NULL && fptr->f2 == NULL) return; +#ifdef USE_THREAD + rb_thread_fd_close(fileno(fptr->f)); +#endif + if (fptr->finalize) { (*fptr->finalize)(fptr); } @@ -954,7 +963,9 @@ rb_io_syswrite(io, str) f = GetWriteFile(fptr); #ifdef USE_THREAD - rb_thread_fd_writable(fileno(f)); + if (!rb_thread_fd_writable(fileno(f))) { + rb_io_check_closed(fptr); + } #endif n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len); @@ -1588,6 +1599,9 @@ rb_io_reopen(io, nfile) else if (orig->mode & FMODE_WRITABLE) { fflush(orig->f); } +#ifdef USE_THREAD + rb_thread_fd_close(fileno(fptr->f)); +#endif /* copy OpenFile structure */ fptr->mode = orig->mode; diff --git a/lib/weakref.rb b/lib/weakref.rb index c31e959e74..d53aa15c71 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -60,10 +60,11 @@ class WeakRef<Delegator end if __FILE__ == $0 + require 'thread' foo = Object.new - p foo.hash # original's hash value + p foo.to_s # original's class foo = WeakRef.new(foo) - p foo.hash # should be same hash value + p foo.to_s # should be same class ObjectSpace.garbage_collect - p foo.hash # should raise exception (recycled) + p foo.to_s # should raise exception (recycled) end @@ -253,7 +253,7 @@ w_object(obj, arg, limit) w_byte(TYPE_USERDEF, arg); w_unique(rb_class2name(CLASS_OF(obj)), arg); - v = rb_funcall(obj, s_dump, 1, limit); + v = rb_funcall(obj, s_dump, 1, INT2NUM(limit)); if (TYPE(v) != T_STRING) { rb_raise(rb_eTypeError, "_dump_to must return String"); } @@ -755,7 +755,7 @@ r_object(arg) v = rb_funcall(klass, s_load, 1, r_string(arg)); return r_regist(v, arg); } - rb_raise(rb_eTypeError, "class %s needs to have method `_load_from'", + rb_raise(rb_eTypeError, "class %s needs to have method `_load'", rb_class2name(klass)); } break; @@ -5204,7 +5204,7 @@ here_document(term, indent) char *eos, *p; int len; VALUE str; - volatile VALUE line; + volatile VALUE line = 0; VALUE lastline_save; int offset_save; NODE *list = 0; @@ -5243,15 +5243,15 @@ here_document(term, indent) str = rb_str_new(0,0); for (;;) { - line = (*lex_gets)(lex_input); + lex_lastline = line = (*lex_gets)(lex_input); if (NIL_P(line)) { error: ruby_sourceline = linesave; rb_compile_error("can't find string \"%s\" anywhere before EOF", eos); - free(eos); - return 0; + free(eos); + return 0; } - normalize_newline(line); + normalize_newline(line); ruby_sourceline++; p = RSTRING(line)->ptr; if (indent) { @@ -5272,6 +5272,7 @@ here_document(term, indent) } } #endif + retry: switch (parse_string(term, '\n', '\n')) { case tSTRING: case tXSTRING: @@ -5296,6 +5297,10 @@ here_document(term, indent) case 0: goto error; } + if (lex_lastline != line) { + line = lex_lastline; + goto retry; + } } free(eos); lex_lastline = lastline_save; @@ -2293,7 +2293,7 @@ here_document(term, indent) char *eos, *p; int len; VALUE str; - volatile VALUE line; + volatile VALUE line = 0; VALUE lastline_save; int offset_save; NODE *list = 0; @@ -2332,15 +2332,15 @@ here_document(term, indent) str = rb_str_new(0,0); for (;;) { - line = (*lex_gets)(lex_input); + lex_lastline = line = (*lex_gets)(lex_input); if (NIL_P(line)) { error: ruby_sourceline = linesave; rb_compile_error("can't find string \"%s\" anywhere before EOF", eos); - free(eos); - return 0; + free(eos); + return 0; } - normalize_newline(line); + normalize_newline(line); ruby_sourceline++; p = RSTRING(line)->ptr; if (indent) { @@ -2361,6 +2361,7 @@ here_document(term, indent) } } #endif + retry: switch (parse_string(term, '\n', '\n')) { case tSTRING: case tXSTRING: @@ -2385,6 +2386,10 @@ here_document(term, indent) case 0: goto error; } + if (lex_lastline != line) { + line = lex_lastline; + goto retry; + } } free(eos); lex_lastline = lastline_save; @@ -43,6 +43,9 @@ #endif #include "config.h" +#ifdef RUBY_PLATFORM +# define RUBY +#endif void *xmalloc P((unsigned long)); void *xcalloc P((unsigned long,unsigned long)); @@ -17,11 +17,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto) Last change: May 21, 1993 by t^2 */ -/* modifis for Ruby by matz@caelum.co.jp */ +/* modified for Ruby by matz@netlab.co.jp */ #ifndef __REGEXP_LIBRARY #define __REGEXP_LIBRARY +/* symbol mangling for ruby */ +#ifdef RUBY +# define re_compile_fastmap rb_re_compile_fastmap +# define re_compile_pattern rb_re_compile_pattern +# define re_copy_registers rb_re_copy_registers +# define re_free_pattern rb_re_free_pattern +# define re_free_registers rb_re_free_registers +# define re_match rb_re_match +# define re_mbcinit rb_re_mbcinit +# define re_search rb_re_search +# define re_set_casetable rb_re_set_casetable +#endif + #include <stddef.h> /* Define number of parens for which we record the beginnings and ends. diff --git a/sample/test.rb b/sample/test.rb index bc136eb1d4..ad4cf20269 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -867,21 +867,21 @@ ok(i6 == nil) check "system" ok(`echo foobar` == "foobar\n") -ok(`./ruby -e 'print "foobar"'` == 'foobar') +ok(`./miniruby -e 'print "foobar"'` == 'foobar') tmp = open("script_tmp", "w") tmp.print "print $zzz\n"; tmp.close -ok(`./ruby -s script_tmp -zzz` == 'true') -ok(`./ruby -s script_tmp -zzz=555` == '555') +ok(`./miniruby -s script_tmp -zzz` == 'true') +ok(`./miniruby -s script_tmp -zzz=555` == '555') tmp = open("script_tmp", "w") tmp.print "#! /usr/local/bin/ruby -s\n"; tmp.print "print $zzz\n"; tmp.close -ok(`./ruby script_tmp -zzz=678` == '678') +ok(`./miniruby script_tmp -zzz=678` == '678') tmp = open("script_tmp", "w") tmp.print "this is a leading junk\n"; @@ -891,8 +891,8 @@ tmp.print "__END__\n"; tmp.print "this is a trailing junk\n"; tmp.close -ok(`./ruby -x script_tmp` == 'nil') -ok(`./ruby -x script_tmp -zzz=555` == '555') +ok(`./miniruby -x script_tmp` == 'nil') +ok(`./miniruby -x script_tmp -zzz=555` == '555') tmp = open("script_tmp", "w") for i in 1..5 @@ -900,7 +900,7 @@ for i in 1..5 end tmp.close -`./ruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp` +`./miniruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp` done = true tmp = open("script_tmp", "r") while tmp.gets @@ -917,7 +917,7 @@ File.unlink "script_tmp.bak" or `/bin/rm -f "script_tmp.bak"` $bad = false for script in Dir["{lib,sample}/*.rb"] - unless `./ruby -c #{script}`.chomp == "Syntax OK" + unless `./miniruby -c #{script}`.chomp == "Syntax OK" $bad = true end end @@ -1365,11 +1365,11 @@ rb_str_inspect(str) while (p < pend) { char c = *p++; if (ismbchar(c) && p < pend) { - int len = mbclen(c)-1; + int len = mbclen(c); CHECK(len); *b++ = c; - while (len--) { + while (--len) { *b++ = *p++; } } @@ -1,2 +1,2 @@ #define RUBY_VERSION "1.3.1" -#define VERSION_DATE "99/02/10" +#define VERSION_DATE "99/02/12" |