mattn/mruby-thread — pull request #26 by sdottaka (2014-11-21 09:11:41+00:00)
Title: Fix crashes

I'm not familiar with PR. So I could not create separated PRs Sorry for that.

# The first fix

The fix solves crash when calling Thread#new without a block .

# The second fix

Fix crash when calling Thread#new on mruby with mruby-io

mruby with mruby-io dumps core when executing the code below.

~~~
10.times { th = Thread.new { }; th.join; }
~~~
mruby-io defines global variables like `$stdout` or `$stderr`.

mruby-thread migrates global variables to created thread, but the above global variables are not safe to migrate.

This fix tries to solve this problem by migrating only migratable variables to new thread.

# The third fix
Avoid unexpected behavior when accessing symbols in new thread. (migrate all symbols to new thread)

mruby-thread does not migrate all symbols to new thread. It causes various problems

For example:
e.g. 1)

~~~
Thread.new { puts :hoge }
~~~

Expected output:

~~~
hoge
~~~

Actual output:
~~~
$5
~~~

e.g. 2)

~~~
Thread.new {
class A; end
puts A.new.class
}
~~~

Expected output:

~~~
A
~~~

Actual output:

~~~
$5
~~~

Unfortunately, this fix causes performance regression.

Test script:
~~~
nsymbols = ARGV[0].to_i

(1..nsymbols).each {|i| i.to_s.intern }
puts "symbol count=#{Symbol.all_symbols.count}"

start = Time.now
(1..1000).each {
th = Thread.new { 1 }
th.join
}
puts "elapsed time=#{Time.now - start}"
~~~

Before fix:
~~~
$ ./mruby thread_test.rb 1
symbol count=1129
elapsed time=4.3401540

$ ./mruby thread_test.rb 1000
symbol count=2128
elapsed time=4.2053690

$ ./mruby thread_test.rb 10000
symbol count=11128
elapsed time=4.14965199999999

$ ./mruby thread_test.rb 100000
symbol count=101128
elapsed time=4.0745670
~~~

After fix:

~~~
$ ./mruby-new thread_test.rb 1
symbol count=1129
elapsed time=4.58120499999999

$ ./mruby-new thread_test.rb 1000
symbol count=2128
elapsed time=4.88455399999999

$ ./mruby-new thread_test.rb 10000
symbol count=11128
elapsed time=7.42716099999999

$ ./mruby-new thread_test.rb 100000
symbol count=101128
elapsed time=63.4792210
~~~