[#27919] 1.8.4 Preview2 検証 — "URABE Shyouhei aka. mput" <root@...>
卜部です。
まつもと ゆきひろです
[#27944] Ruby 1.8.3 on FreeBSD — Masayoshi Takahashi <maki@...>
高橋征義です。
[#27991] GC.always — Tanaka Akira <akr@...17n.org>
というように、GC を常に動かすというのは GC 関連の問題を発見
まつもと ゆきひろです
In article <1134314081.457781.8573.nullmailer@x31.priv.netlab.jp>,
[#27997] 1.8.4 documents? — "URABE Shyouhei aka. mput" <root@...>
卜部です。
新井です。
新井です。
[#28010] IA64 BSPSTORE — Tanaka Akira <akr@...17n.org>
そういえば、IA64 で gc.c や eval.c に BSPSTORE レジスタの値
まつもと ゆきひろです
In article <1134478762.181062.2779.nullmailer@x31.priv.netlab.jp>,
[#28045] 1.8.4 what remains? — "URABE Shyouhei aka. mput" <root@...>
卜部です。
[#28082] ruby_1_8 Segmentation fault on Cygwin — yanagi@...
柳田です。
山本です。
こんにちは、なかむら(う)です。
山本です。
こんにちは、なかむら(う)です。
柳田です。
山本です。
[#28087] test(?-, file1, file2) — Tanaka Akira <akr@...17n.org>
マニュアルの test(?-, file1, file2) の説明に、
[#28109] Kernel#fail — "URABE Shyouhei aka. mput" <root@...>
さすがにもう誰も使ってないのではないかと思います。Kernel#failは廃止にし
[#28121] post_connection_check with javacc.dev.java.net — Tanaka Akira <akr@...17n.org>
ふと、https://javacc.dev.java.net/ を open-uri でアクセスすると、
[#28127] Intel C++ Compiler and HP aC++/ANSI C on IA64 — Tanaka Akira <akr@...17n.org>
TestDrive で IA64 上の Intel C++ Compiler and HP aC++/ANSI C
渡辺哲也です。
[#28140] ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError) — Tanaka Akira <akr@...17n.org>
HP-UX で HP aC++/ANSI C を使って作った ruby で、openssl や drb のテストをすると、
渡辺哲也です。
In article <200512280307.jBS37nnj005909@pbsg500.nifty.com>,
In message "[ruby-dev:28142] Re: ia64-hpux11.23/socket.sl: this executable file can't load extension libraries (LoadError)"
山本です。
In article <20051228210640.13C71A10.ocean@m2.ccsnet.ne.jp>,
渡辺哲也です。
山本です。
山本です。
In article <20051229114438.44D19F00.ocean@m2.ccsnet.ne.jp>,
なかだです。
In article <ypvtr77wv7q9.wl%nobuyoshi.nakada@ge.com>,
なかだです。
In article <ypvtoe30v1zk.wl%nobuyoshi.nakada@ge.com>,
なかだです。
In article <ypvtmzikv11x.wl%nobuyoshi.nakada@ge.com>,
なかだです。
In article <ypvtwthol15x.wl%nobuyoshi.nakada@ge.com>,
[#28177] Generator dumps core — "H.Yamamoto" <ocean@...2.ccsnet.ne.jp>
山本です。
[#28178] accessing ruby_cbase (nil) dumps core — SASADA Koichi <ko1@...>
ささだです。
[#28181] zsuper (with define_method) dumps core — SASADA Koichi <ko1@...>
ささだです。
[#28182] generator.rb deadlocks — Tanaka Akira <akr@...17n.org>
RUBY_ALWAYS_GC= つきで test_generator.rb を動かすと deadlock が起きます。
[#28184] test_each(TC_SyncEnumerator) fails. — Tanaka Akira <akr@...17n.org>
deadlock は解決しましたが次のようにテストが失敗します。
[ruby-dev:28157] Re: thread based generator.rb
山本です。
>> http://rubyforge.org/tracker/index.php?func=detail&aid=1364&group_id=426&atid=1698 を閉じようと
>> 思って試したら、まだメモリリークしますね。--;;
>>
>> よく考えると Thread は参照が切れても生きつづけるので、Generator の参照が切れたときに Thread も
>> 終了させないと駄目なのか・・・もう少し考えてみます。
>
>おぉ、それは気がついていませんでした。
>
>ふむ。ちょっとした思い付きですが、他のスレッドから操作されな
>い限り動き出さない thread は GC の root にしない、というアイ
>デアはどうでしょう?
こちらはインタプリタの話になるので私にはわかりませんが、
ファイナライザでどうにかできないかといじってみた結果、それらしく動くように
なりました。(まだ適当なコードで、コミットできる状態ではありません)
ただ、
require 'generator'
while true
g = Generator.new { yield 1 }
GC.start
# p Thread.list
# sleep 1
end
でいずれかのコメントを外すとメモリリークしなくなるのですが、
何もウェイトのない状態だと、メモリ使用量がどんどん増えていきます。
ファイナライザで @loop_thread.join してみましたが変わりません。
また、以前スコープの話がありましたが、
g = Generator.new { |g2|
for i in 'A'..'C'
g2.yield i
end
g2.yield 'Z'
}
というように変えないと、ブロック引数の g が外部に渡ってしまうのは
やっぱり違和感を覚えます。(g2 よりも g に代入されるのが後だけに)
Index: generator.rb
===================================================================
RCS file: /src/ruby/lib/generator.rb,v
retrieving revision 1.5
diff -u -w -b -p -r1.5 generator.rb
--- generator.rb 29 Dec 2005 02:29:26 -0000 1.5
+++ generator.rb 29 Dec 2005 04:26:30 -0000
@@ -56,16 +56,11 @@
class Generator
include Enumerable
- # Creates a new generator either from an Enumerable object or from a
- # block.
- #
- # In the former, block is ignored even if given.
- #
- # In the latter, the given block is called with the generator
- # itself, and expected to call the +yield+ method for each element.
+ class GeneratorProxy
+
def initialize(enum = nil, &block)
if enum
- @block = proc{|g| enum.each{|value| g.yield value}}
+ @block = proc{|proxy| enum.each{|value| proxy.yield value}}
else
@block = block
end
@@ -83,10 +78,8 @@ class Generator
Thread.critical = false
end
end
- self
end
- # Yields an element to the generator.
def yield(value)
if Thread.current != @loop_thread
raise RuntimeError.new("Generator#yield must be called in Generator.new{|g| ... }")
@@ -95,10 +88,8 @@ class Generator
@main_thread.wakeup
Thread.stop
Thread.critical = true
- self
end
- # Returns true if the generator has reached the end.
def end?
if @queue.empty?
Thread.critical = true
@@ -116,37 +107,83 @@ class Generator
@queue.empty?
end
+ def index
+ @index
+ end
+
+ def next
+ raise EOFError.new("no more elements available") if end?
+ @index += 1
+ @queue.shift
+ end
+
+ def current
+ raise EOFError.new("no more elements available") if end?
+ @queue.first
+ end
+
+ def rewind
+ initialize(nil, &@block) if @index.nonzero?
+ end
+
+ def create_finalizer
+ proc { @loop_thread.kill; @loop_thread.join }
+ end
+
+ end
+
+ # Creates a new generator either from an Enumerable object or from a
+ # block.
+ #
+ # In the former, block is ignored even if given.
+ #
+ # In the latter, the given block is called with the generator
+ # itself, and expected to call the +yield+ method for each element.
+ def initialize(enum = nil, &block)
+ @proxy = GeneratorProxy.new(enum, &block)
+ ObjectSpace.define_finalizer(self, @proxy.create_finalizer)
+ self
+ end
+
+ # Yields an element to the generator.
+ def yield(value)
+ @proxy.yield(value)
+ self
+ end
+
+ # Returns true if the generator has reached the end.
+ def end?
+ @proxy.end?
+ end
+
# Returns true if the generator has not reached the end yet.
def next?
- !end?
+ !@proxy.end?
end
# Returns the current index (position) counting from zero.
def index
- @index
+ @proxy.index
end
# Returns the current index (position) counting from zero.
def pos
- @index
+ @proxy.index
end
# Returns the element at the current position and moves forward.
def next
- raise EOFError.new("no more elements available") if end?
- @index += 1
- @queue.shift
+ @proxy.next
end
# Returns the element at the current position.
def current
- raise EOFError.new("no more elements available") if end?
- @queue.first
+ @proxy.current
end
# Rewinds the generator.
def rewind
- initialize(nil, &@block) if @index.nonzero?
+ @proxy.rewind
self
end
@@ -251,12 +288,12 @@ class TC_Generator < Test::Unit::TestCas
end
def test_block2
- g = Generator.new { |g|
+ g = Generator.new { |g2|
for i in 'A'..'C'
- g.yield i
+ g2.yield i
end
- g.yield 'Z'
+ g2.yield 'Z'
}
assert_equal(0, g.pos)