edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ThreadOps.cs;C695420
File: ThreadOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ThreadOps.cs;C695420  (server)    1/4/2009 11:36 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ThreadOps.cs;hangs
@@ -159,6 +159,7 @@
             internal Exception Exception { get; set; }
             internal object Result { get; set; }
             internal bool CreatedFromRuby { get; set; }
+            private bool IsSleeping { get; set; }
 
             internal bool AbortOnException {
                 get {
@@ -188,11 +189,18 @@
             /// lock which can be signalled from another thread.
             /// </summary>
             internal void Sleep() {
-                _runSignal.WaitOne();
+                try {
+                    IsSleeping = true;
+                    _runSignal.WaitOne();
+                } finally {
+                    IsSleeping = false;
+                }
             }
 
             internal void Run() {
-                _runSignal.Set();
+                if (IsSleeping) {
+                    _runSignal.Set();
+                }
             }
         }
 
@@ -490,6 +498,9 @@
             }
 
             if ((state & ThreadState.WaitSleepJoin) == ThreadState.WaitSleepJoin) {
+                // We will report a thread to be sleeping more often than in CRuby. This is because any "lock" statement
+                // can potentially cause ThreadState.WaitSleepJoin. Also, "Thread.pass" does System.Threading.Thread.Sleep(0)
+                // which also briefly changes the state to ThreadState.WaitSleepJoin
                 return RubyThreadStatus.Sleeping;
             }
 
@@ -633,6 +644,7 @@
             } catch (Exception e) {
                 if (IsRubyThreadExit(e)) {
                     Utils.Log(String.Format("Thread {0} exited.", info.Thread.ManagedThreadId), "THREAD");
+                    info.Result = false;
                 } else {
                     e = RubyOps.GetVisibleException(e);
                     RubyExceptionData.ActiveExceptionHandled(e);
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/ironruby-tags/critical_tags.txt;C691193
File: critical_tags.txt
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/ironruby-tags/critical_tags.txt;C691193  (server)    1/6/2009 11:39 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/ironruby-tags/critical_tags.txt;hangs
@@ -37,6 +37,10 @@
 core\string\hex_tags.txt:3:critical:String#hex returns 0 on error
 core\string\oct_tags.txt:3:critical:String#oct takes an optional sign
 core\string\oct_tags.txt:3:critical:String#oct returns 0 on error
+core\thread\critical_tags.txt:0:unstable:Thread.critical= does not change status of other existing threads
+core\thread\critical_tags.txt:0:critical:Thread.critical= defers exit until Thread.pass
+core\thread\critical_tags.txt:0:critical:Thread.critical= can be mismatched
+core\thread\critical_tags.txt:0:critical:Thread.critical= schedules other threads on Thread.stop
 core\thread\raise_tags.txt:0:critical:Thread#raise on another thread re-raises active exception
 language\method_tags.txt:0:critical:Calling a method fails with both lambda and block argument
 library\mathn\rational\power2_tags.txt:0:critical:Rational#power2 when passed [Rational] returns Rational.new!(1, 1) when the passed argument is 0
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/ironruby-tags/1.8/core/thread/critical_tags.txt;C695420
File: critical_tags.txt
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/ironruby-tags/1.8/core/thread/critical_tags.txt;C695420  (server)    1/6/2009 4:05 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/ironruby-tags/1.8/core/thread/critical_tags.txt;hangs
@@ -1,4 +1,5 @@
-fails:Thread.critical defers exit
-critical:Thread.critical defers exit until Thread.pass
-fails:Thread.critical is not reset if the critical thread is killed
-critical:Thread.critical can be mismatched
\ No newline at end of file
+unstable:Thread.critical= does not change status of other existing threads
+fails:Thread.critical= defers exit
+critical:Thread.critical= defers exit until Thread.pass
+critical:Thread.critical= can be mismatched
+critical:Thread.critical= schedules other threads on Thread.stop
\ No newline at end of file
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/alive_spec.rb;C544557
File: alive_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/alive_spec.rb;C544557  (server)    1/7/2009 11:49 AM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/alive_spec.rb;hangs
@@ -2,19 +2,33 @@
 require File.dirname(__FILE__) + '/fixtures/classes'
 
 describe "Thread#alive?" do
-  it "returns true as long as the thread is alive" do
-    c = Channel.new
-    t = Thread.new { c.receive }
-    begin
-      t.alive?.should == true
-    ensure
-      c << nil
-    end
+  it "can check it's own status" do
+    ThreadSpecs.get_status_of_current_thread.alive?.should == true
   end
 
-  it "returns false when the thread is finished" do
-    t = Thread.new { }
-    t.join
-    t.alive?.should == false
+  it "describes a running thread" do
+    ThreadSpecs.get_status_of_running_thread.alive?.should == true
   end
+
+  it "describes a sleeping thread" do
+    ThreadSpecs.get_status_of_sleeping_thread.alive?.should == true
+  end
+
+  it "describes a completed thread" do
+    ThreadSpecs.get_status_of_completed_thread.alive?.should == false
+  end
+
+  it "describes a killed thread" do
+    ThreadSpecs.get_status_of_killed_thread.alive?.should == false
+  end
+
+  it "describes a thread with an uncaught exception" do
+    ThreadSpecs.get_status_of_thread_with_uncaught_exception.alive?.should == false
+  end
+
+  compliant_on(:ruby) do
+    it "reports aborting on a killed thread" do
+      ThreadSpecs.get_status_of_aborting_thread.alive?.should == true
+    end
+  end
 end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/critical_spec.rb;C695420
File: critical_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/critical_spec.rb;C695420  (server)    12/31/2008 10:48 AM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/critical_spec.rb;hangs
@@ -1,7 +1,7 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
 require File.dirname(__FILE__) + '/fixtures/classes'
 
-describe "Thread.critical" do
+describe "Thread.critical=" do
 
   it "should be sticky" do
     ThreadSpecs.critical_should_be_false()
@@ -62,12 +62,12 @@
   end
 
   it "schedules other threads on sleep" do
-    ThreadSpecs.critical_thread_yields_to_main_thread { sleep }
+    ThreadSpecs.critical_thread_yields_to_main_thread(true) { sleep }
   end
     
   it "schedules other threads on Thread.stop" do
     # Note that Thread.Stop resets Thread.critical, whereas sleep does not
-    ThreadSpecs.critical_thread_yields_to_main_thread(true) { Thread.stop }
+    ThreadSpecs.critical_thread_yields_to_main_thread(false, true) { Thread.stop }
   end
     
   it "defers exit" do
@@ -84,14 +84,14 @@
     ScratchPad.recorded.should == nil
   end
 
-  not_compliant_on(:ironruby) do # requires green threads  
-  it "is not reset if the critical thread is killed" do
-    critical_thread = ThreadSpecs.create_and_kill_critical_thread(true)
-    Thread.pass while critical_thread.status != false
-    Thread.critical.should == true
+  not_compliant_on(:ironruby) do # requires green threads so that another thread can be scheduled when the critical thread is killed
+    it "is not reset if the critical thread is killed" do
+      critical_thread = ThreadSpecs.create_and_kill_critical_thread(true)
+      Thread.pass while critical_thread.status != false
+      Thread.critical.should == true
 
-    Thread.critical = false
-    ThreadSpecs.critical_should_be_false()    
+      Thread.critical = false
+      ThreadSpecs.critical_should_be_false()    
+    end
   end
-  end
 end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/inspect_spec.rb;C638190
File: inspect_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/inspect_spec.rb;C638190  (server)    1/7/2009 12:01 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/inspect_spec.rb;hangs
@@ -3,39 +3,32 @@
 
 describe "Thread#inspect" do
   it "can check it's own status" do
-    t = Thread.new { Thread.current.inspect }
-    t.value.should include('run')
+    ThreadSpecs.get_status_of_current_thread.inspect.should include('run')
   end
-  
+
+  it "describes a running thread" do
+    ThreadSpecs.get_status_of_running_thread.inspect.should include('run')
+  end
+
   it "describes a sleeping thread" do
-    c = Channel.new
-    t = Thread.new do      
-      sleep
-      c << Thread.current.inspect
-      sleep
-    end
-    
-    Thread.pass until t.status == 'sleep'
-    t.inspect.should include('sleep')
-    t.run
-    c.receive.should include('run')
-    Thread.pass until t.status == 'sleep'
-    t.inspect.should include('sleep')
-    t.run
-    t.join
-    t.inspect.should include('dead')
+    ThreadSpecs.get_status_of_sleeping_thread.inspect.should include('sleep')
   end
 
-  compliant_on(:ruby) do
+  it "describes a completed thread" do
+    ThreadSpecs.get_status_of_completed_thread.inspect.should include('dead')
+  end
+
+  it "describes a killed thread" do
+    ThreadSpecs.get_status_of_killed_thread.inspect.should include('dead')
+  end
+
+  it "describes a thread with an uncaught exception" do
+    ThreadSpecs.get_status_of_thread_with_uncaught_exception.inspect.should include('dead')
+  end
+
+  compliant_on(:ruby) do
     it "reports aborting on a killed thread" do
-      c = Channel.new
-      t = Thread.new { c << Thread.current.inspect; Thread.stop }
-      c.receive.should include('run')
-      t.inspect.should include('sleep')
-      Thread.critical = true
-      t.kill
-      t.inspect.should include('aborting')
-      Thread.critical = false
+      ThreadSpecs.get_status_of_aborting_thread.inspect.should include('aborting')
     end
   end
 end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/raise_spec.rb;C695420
File: raise_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/raise_spec.rb;C695420  (server)    12/30/2008 10:42 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/raise_spec.rb;hangs
@@ -70,7 +70,9 @@
       rescue RuntimeError => e
         $!.message.should == "Kill the thread"
         e.message.should == "Kill the thread"
-        e.backtrace.select {|b| b =~ /looping_method/ }.size().should == 1
+        frame_count = e.backtrace.select {|b| b =~ /looping_method/ }.size()
+        # There will be two occurences if "loop" is yielding to the block
+        (frame_count == 1 or frame_count == 2).should == true
       end
       102
     end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/run_spec.rb;C544557
File: run_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/run_spec.rb;C544557  (server)    1/6/2009 10:41 AM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/run_spec.rb;hangs
@@ -1,2 +1,9 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
-require File.dirname(__FILE__) + '/fixtures/classes'
\ No newline at end of file
+require File.dirname(__FILE__) + '/fixtures/classes'
+
+require File.dirname(__FILE__) + '/shared/wakeup'
+
+describe "Thread#run" do
+  it_behaves_like :thread_wakeup, :run
+end
+
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/status_spec.rb;C638190
File: status_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/status_spec.rb;C638190  (server)    1/7/2009 12:02 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/status_spec.rb;hangs
@@ -2,15 +2,33 @@
 require File.dirname(__FILE__) + '/fixtures/classes'
 
 describe "Thread#status" do
-  it "reports threads as running and returns false on correct termination" do
-    t = Thread.new { Thread.current.status }
-    t.value.should == 'run'
-    t.status.should == false
+  it "can check it's own status" do
+    ThreadSpecs.get_status_of_current_thread.status.should == 'run'
   end
 
-  it "returns nil if thread terminates with exception" do
-    t = Thread.new { raise "death to the unbelievers" }
-    lambda { t.join }.should raise_error(StandardError)
-    t.status.should == nil
+  it "describes a running thread" do
+    ThreadSpecs.get_status_of_running_thread.status.should == 'run'
   end
+
+  it "describes a sleeping thread" do
+    ThreadSpecs.get_status_of_sleeping_thread.status.should == 'sleep'
+  end
+
+  it "describes a completed thread" do
+    ThreadSpecs.get_status_of_completed_thread.status.should == false
+  end
+
+  it "describes a killed thread" do
+    ThreadSpecs.get_status_of_killed_thread.status.should == false
+  end
+
+  it "describes a thread with an uncaught exception" do
+    ThreadSpecs.get_status_of_thread_with_uncaught_exception.status.should == nil
+  end
+
+  compliant_on(:ruby) do
+    it "reports aborting on a killed thread" do
+      ThreadSpecs.get_status_of_aborting_thread.status.should == 'aborting'
+    end
+  end
 end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/stop_spec.rb;C544557
File: stop_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/stop_spec.rb;C544557  (server)    1/7/2009 12:24 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/stop_spec.rb;hangs
@@ -20,12 +20,33 @@
 end
 
 describe "Thread#stop?" do
-  it "reports if a thread has stopped due to sleeping" do
-    t = Thread.new { Thread.stop }
-    Thread.pass until t.status == 'sleep'
-    t.stop?.should == true
-    t.run
-    t.join
-    t.stop?.should == true
+  it "can check it's own status" do
+    ThreadSpecs.get_status_of_current_thread.stop?.should == false
   end
+
+  it "describes a running thread" do
+    ThreadSpecs.get_status_of_running_thread.stop?.should == false
+  end
+
+  it "describes a sleeping thread" do
+    ThreadSpecs.get_status_of_sleeping_thread.stop?.should == true
+  end
+
+  it "describes a completed thread" do
+    ThreadSpecs.get_status_of_completed_thread.stop?.should == true
+  end
+
+  it "describes a killed thread" do
+    ThreadSpecs.get_status_of_killed_thread.stop?.should == true
+  end
+
+  it "describes a thread with an uncaught exception" do
+    ThreadSpecs.get_status_of_thread_with_uncaught_exception.stop?.should == true
+  end
+
+  compliant_on(:ruby) do
+    it "reports aborting on a killed thread" do
+      ThreadSpecs.get_status_of_aborting_thread.stop?.should == false
+    end
+  end
 end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/value_spec.rb;C544557
File: value_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/value_spec.rb;C544557  (server)    1/7/2009 12:49 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/value_spec.rb;hangs
@@ -5,4 +5,14 @@
   it "returns the result of the block" do
     Thread.new { 3 }.value.should == 3
   end
+
+  it "re-raises error for an uncaught exception" do
+    t = Thread.new { raise "Hello" }
+    lambda { t.value }.should raise_error(RuntimeError, "Hello")
+  end
+
+  it "is false for a killed thread" do
+    t = Thread.new { Thread.current.exit }
+    t.value.should == false
+  end
 end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/wakeup_spec.rb;C682742
File: wakeup_spec.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/wakeup_spec.rb;C682742  (server)    1/6/2009 10:15 AM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/wakeup_spec.rb;hangs
@@ -1,38 +1,7 @@
 require File.dirname(__FILE__) + '/../../spec_helper'
 require File.dirname(__FILE__) + '/fixtures/classes'
+require File.dirname(__FILE__) + '/shared/wakeup'
 
 describe "Thread#wakeup" do
-  it "does not result in a deadlock" do
-    c = Channel.new
-    t1 = Thread.new do
-      loop do
-        c << t1
-        c << t1
-        Thread.stop
-      end
-    end
-    t2 = Thread.new do
-      loop do
-        c << t2
-        Thread.stop
-      end
-    end
-
-    count1 = 0
-    count2 = 0
-    while(count1 < 10) do
-      if c.size > 0
-        case c.receive
-        when t1; count1+=1
-        when t2; count2+=1
-        end
-      end
-      t1.wakeup
-      t2.wakeup
-    end
-    count1.should > count2
-
-    t1.kill
-    t2.kill
-  end
+  it_behaves_like :thread_wakeup, :wakeup
 end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/fixtures/classes.rb;C695420
File: classes.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/fixtures/classes.rb;C695420  (server)    1/5/2009 2:10 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/fixtures/classes.rb;hangs
@@ -6,6 +6,88 @@
 end
 
 module ThreadSpecs
+  class Status
+    attr_reader :thread, :inspect, :status
+    def initialize(thread)
+      @thread = thread
+      @alive = thread.alive?
+      @inspect = thread.inspect
+      @status = thread.status
+      @stop = thread.stop?
+    end
+    
+    def alive?
+      @alive
+    end
+    
+    def stop?
+      @stop
+    end
+  end
+  
+  def self.get_status_of_current_thread
+    Thread.new { Status.new(Thread.current) }.value
+  end
+  
+  def self.get_status_of_running_thread
+    @@exit_loop = false
+    t = Thread.new do
+      loop do
+        if @@exit_loop then
+          break
+        end
+      end
+    end
+    status = Status.new t
+    @@exit_loop = true
+    Thread.pass
+    t.join
+    status
+  end
+  
+  def self.get_status_of_completed_thread
+    t = Thread.new { }
+    t.join
+    Status.new t
+  end
+  
+  def self.get_status_of_sleeping_thread
+    t = Thread.new { sleep }   
+    Thread.pass until t.status == 'sleep'
+    status = Status.new t
+    t.run
+    t.join
+    status
+  end
+  
+  def self.get_status_of_aborting_thread
+    t = Thread.new { sleep }
+    begin
+      Thread.critical = true
+      t.kill
+      Status.new t
+    ensure
+      Thread.critical = false      
+    end
+  end
+  
+  def self.get_status_of_killed_thread
+    t = Thread.new { sleep }
+    Thread.pass until t.status == 'sleep'
+    t.kill
+    t.join
+    Status.new t
+  end
+  
+  def self.get_status_of_thread_with_uncaught_exception
+    t = Thread.new { raise "error" }
+    begin
+      t.join
+    rescue RuntimeError
+    end
+    Status.new t
+  end
+  
   def self.critical_should_be_false()
     # Create another thread to verify that it can call Thread.critical=
     t = Thread.new do
@@ -46,14 +128,18 @@
     end
   end
   
-  def self.MainThread1(critical_thread, isThreadStop)
-    # Thread.stop reset Thread.critical. Also, with native threads, the Thread.Stop may not have executed yet
+  def self.MainThread1(critical_thread, isThreadSleep, isThreadStop)
+    # Thread.stop resets Thread.critical. Also, with native threads, the Thread.Stop may not have executed yet
     # since the main thread will race with the critical thread
     if not isThreadStop
       Thread.critical.should == true
     end
     critical_thread[:thread_specs] = 101
-    critical_thread.wakeup
+    if isThreadSleep or isThreadStop
+      # Thread#wakeup calls are not queued up. So we need to ensure that the thread is sleeping before calling wakeup
+      Thread.pass while critical_thread.status != "sleep"
+      critical_thread.wakeup
+    end
   end
   
   def self.MainThread2(critical_thread)
@@ -62,7 +148,7 @@
     Thread.critical.should == false
   end
 
-  def self.critical_thread_yields_to_main_thread(isThreadStop=false)        
+  def self.critical_thread_yields_to_main_thread(isThreadSleep=false, isThreadStop=false)        
     @@after_first_sleep = false
     
     critical_thread = Thread.new do
@@ -70,7 +156,7 @@
       CriticalThread1()
       Thread.main.wakeup
       yield
-      Thread.pass while @@after_first_sleep != true # Implementations using native thread need to ensure that the next statement does not see the first sleep
+      Thread.pass while @@after_first_sleep != true # Need to ensure that the next statement does not see the first sleep itself
       Thread.pass while Thread.main.status != "sleep"
       CriticalThread2(isThreadStop)
       Thread.main.wakeup
@@ -78,7 +164,7 @@
     
     sleep
     @@after_first_sleep = true
-    MainThread1(critical_thread, isThreadStop)
+    MainThread1(critical_thread, isThreadSleep, isThreadStop)
     sleep
     MainThread2(critical_thread)
   end
===================================================================
edit: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/shared/exit.rb;C695420
File: exit.rb
===================================================================
--- $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/shared/exit.rb;C695420  (server)    1/5/2009 2:45 PM
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/shared/exit.rb;hangs
@@ -6,22 +6,37 @@
       ScratchPad.record :after_sleep
     end
     Thread.pass while sleeping_thread.status != "sleep"
-    sleeping_thread.kill
+    sleeping_thread.send(@method)
     sleeping_thread.join
+    sleeping_thread.value.should == false
     ScratchPad.recorded.should == nil
   end
   
   it "kills current thread" do
     ScratchPad.clear()
     thread = Thread.new do
-      Thread.current.kill
+      Thread.current.send(@method)
       ScratchPad.record :after_sleep
     end
-    Thread.pass while thread.status != false
     thread.join
+    thread.status.should == false
+    thread.value.should == false
     ScratchPad.recorded.should == nil
   end
   
+  it "runs ensure clause" do
+    ScratchPad.clear
+    thread = Thread.new do
+      begin
+        Thread.current.send(@method)
+      ensure
+        ScratchPad.record :in_ensure_clause
+      end
+    end
+    thread.join
+    ScratchPad.recorded.should == :in_ensure_clause
+  end
+  
   # This case occurred in JRuby where native threads are used to provide
   # the same behavior as MRI green threads. Key to this issue was the fact
   # that the thread which called #exit in its block was also being explicitly
===================================================================
add: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/shared/wakeup.rb
File: wakeup.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Merlin_External/Languages/IronRuby/mspec/rubyspec/1.8/core/thread/shared/wakeup.rb;hangs
@@ -1,0 +1,50 @@
+describe :thread_wakeup, :shared => true do
+  it "is not queued" do
+    exit_loop = false
+    after_sleep1 = false
+    after_sleep2 = false
+    t = Thread.new do
+      loop do
+        if exit_loop == true
+          break
+        end
+      end
+      
+      sleep
+      after_sleep1 = true
+      
+      sleep
+      after_sleep2 = true
+    end
+
+    10.times { t.send(@method); Thread.pass } # These will all get ignored because the thread is not sleeping yet
+
+    exit_loop = true
+    
+    Thread.pass while t.status != "sleep"
+    after_sleep1.should == false # t should be blocked on the first sleep
+    t.send(@method)
+
+    Thread.pass while after_sleep1 != true
+    Thread.pass while t.status != "sleep"
+    after_sleep2.should == false # t should be blocked on the second sleep
+    t.send(@method)
+    Thread.pass while after_sleep2 != true
+    
+    t.join
+  end
+
+  it "does not result in a deadlock" do
+    c = Channel.new
+    t = Thread.new do
+      1000.times {Thread.stop }
+    end
+
+    while(t.status != false) do
+      t.send(@method)
+      Thread.pass
+    end
+    
+    1.should == 1 # test succeeds if we reach here
+  end
+end
===================================================================
