require_relative '../../spec_helper' require_relative 'fixtures/classes' describe "Thread.new" do it "creates a thread executing the given block" do c = Channel.new Thread.new { c << true }.join c << false c.receive.should == true end it "can pass arguments to the thread block" do arr = [] a, b, c = 1, 2, 3 t = Thread.new(a,b,c) {|d,e,f| arr << d << e << f } t.join arr.should == [a,b,c] end it "raises an exception when not given a block" do lambda { Thread.new }.should raise_error(ThreadError) end it "creates a subclass of thread calls super with a block in initialize" do arr = [] t = ThreadSpecs::SubThread.new(arr) t.join arr.should == [1] end it "calls #initialize and raises an error if super not used" do c = Class.new(Thread) do def initialize end end lambda { c.new }.should raise_error(ThreadError) end it "calls and respects #initialize for the block to use" do c = Class.new(Thread) do def initialize ScratchPad.record [:good] super { ScratchPad << :in_thread } end end t = c.new t.join ScratchPad.recorded.should == [:good, :in_thread] end it "releases Mutexes held by the Thread when the Thread finishes" do m1 = Mutex.new m2 = Mutex.new t = Thread.new { m1.lock m1.locked?.should == true m2.lock m2.locked?.should == true } t.join m1.locked?.should == false m2.locked?.should == false end it "releases Mutexes held by the Thread when the Thread finishes, also with Mutex#synchronize" do m = Mutex.new t = Thread.new { m.synchronize { m.unlock m.lock } m.lock m.locked?.should == true } t.join m.locked?.should == false end end