diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | eval.c | 24 | ||||
-rw-r--r-- | lib/singleton.rb | 90 | ||||
-rw-r--r-- | misc/ruby-mode.el | 7 | ||||
-rw-r--r-- | util.c | 2 | ||||
-rw-r--r-- | version.h | 4 |
6 files changed, 89 insertions, 54 deletions
@@ -1,3 +1,19 @@ +Wed Nov 28 18:46:28 2001 Ville Mattila <mulperi@iki.fi> + + * eval.c (rb_thread_select): should subtract timeofday() from + limit, not reverse. + +Wed Nov 28 16:03:28 2001 K.Kosako <kosako@sofnec.co.jp> + + * util.c (scan_hex): x is not a hexadecimal digit. + +Wed Nov 28 13:38:04 2001 Yukihiro Matsumoto <matz@ruby-lang.org> + + * eval.c (rb_thread_schedule): should treat the case that + select(2) returns 0, if a thread is under both WAIT_SELECT and + WAIT_TIME. Jakub Travnik <J.Travnik@sh.cvut.cz> actually fixed + this bug. + Tue Nov 27 02:15:25 2001 Yukihiro Matsumoto <matz@ruby-lang.org> * marshal.c (w_float): must distinguish -0.0 from 0.0. @@ -7571,6 +7571,7 @@ rb_thread_schedule() double delay, now; /* OK */ int n, max; int need_select = 0; + int select_timeout = 0; rb_thread_pending = 0; if (curr_thread == curr_thread->next @@ -7615,7 +7616,7 @@ rb_thread_schedule() if (max < th->fd) max = th->fd; need_select = 1; if (th->wait_for & WAIT_TIME) { - need_select = 2; + select_timeout = 1; } th->select_value = 0; } @@ -7676,14 +7677,17 @@ rb_thread_schedule() } END_FOREACH_FROM(curr, th); } - if (n == 0 && need_select == 2) { - if (now < 0.0) now = timeofday(); - FOREACH_THREAD_FROM(curr, th) { - if ((th->wait_for & (WAIT_SELECT|WAIT_TIME)) && th->delay < now) { - th->status = THREAD_RUNNABLE; - th->wait_for = 0; - th->select_value = 0; - found = 1; + if (select_timeout && n == 0) { + if (now < 0.0) now = timeofday(); + FOREACH_THREAD_FROM(curr, th) { + if ((th->wait_for & (WAIT_SELECT|WAIT_TIME)) && th->delay < now) { + th->status = THREAD_RUNNABLE; + th->wait_for = 0; + th->select_value = 0; + found = 1; + intersect_fds(&readfds, &th->readfds, max); + intersect_fds(&writefds, &th->writefds, max); + intersect_fds(&exceptfds, &th->exceptfds, max); } } END_FOREACH_FROM(curr, th); @@ -7912,7 +7916,7 @@ rb_thread_select(max, read, write, except, timeout) case ERESTART: #endif if (timeout) { - double d = timeofday() - limit; + double d = limit - timeofday(); tv.tv_sec = (unsigned int)d; tv.tv_usec = (long)((d-(double)tv.tv_sec)*1e6); diff --git a/lib/singleton.rb b/lib/singleton.rb index 696d37c0da..3ab048f5a3 100644 --- a/lib/singleton.rb +++ b/lib/singleton.rb @@ -25,8 +25,8 @@ # # # This achieved by marking -# * Klass.new and Klass.allocate - as private and -# * Klass.inherited(sub_klass) - modifying to ensure +# * Klass.new and Klass.allocate - as private and modifying +# * Klass.inherited(sub_klass) - to ensure # that the Singleton pattern is properly inherited. # # In addition Klass is provided with the class methods @@ -39,7 +39,7 @@ # The sole instance method of Singleton is # * _dump(depth) - returning the empty string # The default Marshalling strategy is to strip all state information - i.e. -# instance variables from ``the instance''. Providing costume +# instance variables from ``the instance''. Providing custom # _dump(depth) and _load(str) method allows the (partial) resurrection # of a previous state of ``the instance'' - see third example. # @@ -53,12 +53,12 @@ module Singleton # * nil - before (and after a failed) creation # * false - during creation # * sub_class instance - after a successful creation - @__instance__ = nil + sub_klass.instance_eval { @__instance__ = nil } def sub_klass.instance unless @__instance__.nil? # is the extra flexiblity having the hook method # _wait() around ever useful? - _wait() while false.equal?(@__instance__) + _wait() # check for instance creation return @__instance__ if @__instance__ end @@ -86,7 +86,7 @@ module Singleton instance end def _wait - sleep(0.05) + sleep(0.05) while false.equal?(@__instance__) end private :new, :allocate # hook methods are also marked private @@ -115,55 +115,63 @@ rescue NoMethodError => mes puts mes end -# threaded example with exception -Thread.abort_on_exception = true -class Ups < SomeSingletonClass - @__threads__= [] - @__flip__ = nil - @@__index__ = nil +# threaded example with exception and customized hook #_wait method +Thread.abort_on_exception = false +def num_of_instances(mod) + "#{ObjectSpace.each_object(mod){}} #{mod} instance" +end +class Ups < SomeSingletonClass def initialize - sleep(rand(0.1)/10.0) - Thread.current[:index] = @@__index__ + type.__sleep + puts "initialize called by thread ##{Thread.current[:i]}" end class << self + def _wait + @enter.push Thread.current[:i] + sleep 0.02 while false.equal?(@__instance__) + @leave.push Thread.current[:i] + end + def __sleep + sleep (rand(0.1)) + end def allocate - unless @__flip__ - @__flip__ = true - raise "boom - allocation in thread ##{@@__index__} aborted" - end - super() + __sleep + def self.allocate; __sleep; super() end + raise "allocation in thread ##{Thread.current[:i]} aborted" end def instanciate_all - 1.upto(5) do |@@__index__| - sleep(rand(0.1)/10.0) - @__threads__.push Thread.new { - begin - instance - rescue RuntimeError => mes - puts mes - end - } + @enter = [] + @leave = [] + 1.upto(9) do |i| + Thread.new do + begin + Thread.current[:i] = i + __sleep + instance + rescue RuntimeError => mes + puts mes + end end end - def join - @__threads__.each do |t| - t.join - puts "initialize called by thread ##{t[:index]}" if -t[:index] - end + puts "Before there were #{num_of_instances(Ups)}s" + sleep 3 + puts "Now there is #{num_of_instances(Ups)}" + puts "#{@enter.join "; "} was the order of threads entering the waiting loop" + puts "#{@leave.join "; "} was the order of threads leaving the waiting loop" end end end - -puts "There is(are) #{ObjectSpace.each_object(Ups) {}} Ups instance(s)" - # => The is(are) 0 Ups instance(s) Ups.instanciate_all -Ups.join # => initialize called by thread # i - where i = 2 ... 5 -p Marshal.load(Marshal.dump(Ups.instance)) == Ups.instance # => true -puts "There is(are) #{ObjectSpace.each_object(Ups) {}} Ups instance(s)" - # => The is(are) 1 Ups instance(s) +# results in message like +# Before there were 0 Ups instances +# boom - allocation in thread #8 aborted +# initialize called by thread #3 +# Now there is 1 Ups instance +# 2; 3; 6; 1; 7; 5; 9; 4 was the order of threads entering the waiting loop +# 3; 2; 1; 7; 6; 5; 4; 9 was the order of threads leaving the waiting loop + # Customized marshalling class A diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index 7f7cebef75..efd61254f4 100644 --- a/misc/ruby-mode.el +++ b/misc/ruby-mode.el @@ -522,7 +522,14 @@ The variable ruby-indent-level controls the amount of indentation. (re-search-backward "#" (save-excursion (beginning-of-line) (point)) t) + (save-excursion + (forward-char -1) + (not (looking-at "\\?"))) (skip-chars-backward " \t") + (if (save-excursion + (forward-char -1) + (looking-at "\\?")) + (skip-chars-forward " \t")) (setq state (ruby-parse-region parse-start (point))) (nth 0 state) (goto-char pos))) @@ -47,7 +47,7 @@ const char *start; int len; int *retlen; { - static char hexdigit[] = "0123456789abcdef0123456789ABCDEFx"; + static char hexdigit[] = "0123456789abcdef0123456789ABCDEF"; register const char *s = start; register unsigned long retval = 0; char *tmp; @@ -1,4 +1,4 @@ #define RUBY_VERSION "1.7.2" -#define RUBY_RELEASE_DATE "2001-11-25" +#define RUBY_RELEASE_DATE "2001-11-28" #define RUBY_VERSION_CODE 172 -#define RUBY_RELEASE_CODE 20011125 +#define RUBY_RELEASE_CODE 20011128 |