document.write('<link rel="stylesheet" href="http://flowcoder.com/stylesheets/pygment_trac.css" />');
document.write('<link rel="stylesheet" href="http://flowcoder.com/stylesheets/embed.css" />');
document.write('<div class="flowcoder_post flowcoder_clearfix">');
document.write('<div class="flowcoder_posttitle"><a href=\"http://flowcoder.com/139\">Poor Man\'s Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)<\/a></div>');
document.write('<div class="flowcoder_postbody flowcoder_syntax"><div class=\"highlight\"><pre><span class=\"c1\"># Origin: http://gist.github.com/4631<\/span>\n<span class=\"c1\"># Poor Man&#39;s Fiber (API compatible Thread based Fiber implementation for Ruby 1.8)<\/span>\n<span class=\"c1\"># (c) 2008 Aman Gupta (tmm1)<\/span>\n\n<span class=\"k\">unless<\/span> <span class=\"n\">defined?<\/span> <span class=\"no\">Fiber<\/span>\n  <span class=\"nb\">require<\/span> <span class=\"s1\">&#39;thread&#39;<\/span>\n\n  <span class=\"k\">class<\/span> <span class=\"nc\">FiberError<\/span> <span class=\"o\">&lt;<\/span> <span class=\"no\">StandardError<\/span><span class=\"p\">;<\/span> <span class=\"k\">end<\/span>\n\n  <span class=\"k\">class<\/span> <span class=\"nc\">Fiber<\/span>\n    <span class=\"k\">def<\/span> <span class=\"nf\">initialize<\/span>\n      <span class=\"k\">raise<\/span> <span class=\"no\">ArgumentError<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;new Fiber requires a block&#39;<\/span> <span class=\"k\">unless<\/span> <span class=\"nb\">block_given?<\/span>\n\n      <span class=\"vi\">@yield<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Queue<\/span><span class=\"o\">.<\/span><span class=\"n\">new<\/span>\n      <span class=\"vi\">@resume<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Queue<\/span><span class=\"o\">.<\/span><span class=\"n\">new<\/span>\n\n      <span class=\"vi\">@thread<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Thread<\/span><span class=\"o\">.<\/span><span class=\"n\">new<\/span><span class=\"p\">{<\/span> <span class=\"vi\">@yield<\/span><span class=\"o\">.<\/span><span class=\"n\">push<\/span> <span class=\"o\">[<\/span> <span class=\"o\">*<\/span><span class=\"k\">yield<\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"vi\">@resume<\/span><span class=\"o\">.<\/span><span class=\"n\">pop<\/span><span class=\"p\">)<\/span> <span class=\"o\">]<\/span> <span class=\"p\">}<\/span>\n      <span class=\"vi\">@thread<\/span><span class=\"o\">.<\/span><span class=\"n\">abort_on_exception<\/span> <span class=\"o\">=<\/span> <span class=\"kp\">true<\/span>\n      <span class=\"vi\">@thread<\/span><span class=\"o\">[<\/span><span class=\"ss\">:fiber<\/span><span class=\"o\">]<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">self<\/span>\n    <span class=\"k\">end<\/span>\n    <span class=\"kp\">attr_reader<\/span> <span class=\"ss\">:thread<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">resume<\/span> <span class=\"o\">*<\/span><span class=\"n\">args<\/span>\n      <span class=\"k\">raise<\/span> <span class=\"no\">FiberError<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;dead fiber called&#39;<\/span> <span class=\"k\">unless<\/span> <span class=\"vi\">@thread<\/span><span class=\"o\">.<\/span><span class=\"n\">alive?<\/span>\n      <span class=\"vi\">@resume<\/span><span class=\"o\">.<\/span><span class=\"n\">push<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span>\n      <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"vi\">@yield<\/span><span class=\"o\">.<\/span><span class=\"n\">pop<\/span>\n      <span class=\"n\">result<\/span><span class=\"o\">.<\/span><span class=\"n\">size<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">1<\/span> <span class=\"o\">?<\/span> <span class=\"n\">result<\/span> <span class=\"p\">:<\/span> <span class=\"n\">result<\/span><span class=\"o\">.<\/span><span class=\"n\">first<\/span>\n    <span class=\"k\">end<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">yield<\/span> <span class=\"o\">*<\/span><span class=\"n\">args<\/span>\n      <span class=\"vi\">@yield<\/span><span class=\"o\">.<\/span><span class=\"n\">push<\/span><span class=\"p\">(<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span>\n      <span class=\"n\">result<\/span> <span class=\"o\">=<\/span> <span class=\"vi\">@resume<\/span><span class=\"o\">.<\/span><span class=\"n\">pop<\/span>\n      <span class=\"n\">result<\/span><span class=\"o\">.<\/span><span class=\"n\">size<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">1<\/span> <span class=\"o\">?<\/span> <span class=\"n\">result<\/span> <span class=\"p\">:<\/span> <span class=\"n\">result<\/span><span class=\"o\">.<\/span><span class=\"n\">first<\/span>\n    <span class=\"k\">end<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nc\">self<\/span><span class=\"o\">.<\/span><span class=\"nf\">yield<\/span> <span class=\"o\">*<\/span><span class=\"n\">args<\/span>\n      <span class=\"k\">raise<\/span> <span class=\"no\">FiberError<\/span><span class=\"p\">,<\/span> <span class=\"s2\">&quot;can&#39;t yield from root fiber&quot;<\/span> <span class=\"k\">unless<\/span> <span class=\"n\">fiber<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Thread<\/span><span class=\"o\">.<\/span><span class=\"n\">current<\/span><span class=\"o\">[<\/span><span class=\"ss\">:fiber<\/span><span class=\"o\">]<\/span>\n      <span class=\"n\">fiber<\/span><span class=\"o\">.<\/span><span class=\"n\">yield<\/span><span class=\"p\">(<\/span><span class=\"o\">*<\/span><span class=\"n\">args<\/span><span class=\"p\">)<\/span>\n    <span class=\"k\">end<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nc\">self<\/span><span class=\"o\">.<\/span><span class=\"nf\">current<\/span>\n      <span class=\"no\">Thread<\/span><span class=\"o\">.<\/span><span class=\"n\">current<\/span><span class=\"o\">[<\/span><span class=\"ss\">:fiber<\/span><span class=\"o\">]<\/span> <span class=\"ow\">or<\/span> <span class=\"k\">raise<\/span> <span class=\"no\">FiberError<\/span><span class=\"p\">,<\/span> <span class=\"s1\">&#39;not inside a fiber&#39;<\/span>\n    <span class=\"k\">end<\/span>\n\n    <span class=\"k\">def<\/span> <span class=\"nf\">inspect<\/span>\n      <span class=\"s2\">&quot;#&lt;<\/span><span class=\"si\">#{<\/span><span class=\"nb\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">class<\/span><span class=\"si\">}<\/span><span class=\"s2\">:0x<\/span><span class=\"si\">#{<\/span><span class=\"nb\">self<\/span><span class=\"o\">.<\/span><span class=\"n\">object_id<\/span><span class=\"o\">.<\/span><span class=\"n\">to_s<\/span><span class=\"p\">(<\/span><span class=\"mi\">16<\/span><span class=\"p\">)<\/span><span class=\"si\">}<\/span><span class=\"s2\">&gt;&quot;<\/span>\n    <span class=\"k\">end<\/span>\n  <span class=\"k\">end<\/span>\n<span class=\"k\">end<\/span>\n\n<span class=\"k\">if<\/span> <span class=\"bp\">__FILE__<\/span> <span class=\"o\">==<\/span> <span class=\"vg\">$0<\/span>\n  <span class=\"n\">f<\/span> <span class=\"o\">=<\/span> <span class=\"no\">Fiber<\/span><span class=\"o\">.<\/span><span class=\"n\">new<\/span><span class=\"p\">{<\/span> <span class=\"nb\">puts<\/span> <span class=\"s1\">&#39;hi&#39;<\/span><span class=\"p\">;<\/span> <span class=\"nb\">p<\/span> <span class=\"no\">Fiber<\/span><span class=\"o\">.<\/span><span class=\"n\">yield<\/span><span class=\"p\">(<\/span><span class=\"mi\">1<\/span><span class=\"p\">);<\/span> <span class=\"nb\">puts<\/span> <span class=\"s1\">&#39;bye&#39;<\/span><span class=\"p\">;<\/span> <span class=\"ss\">:done<\/span> <span class=\"p\">}<\/span>\n  <span class=\"nb\">p<\/span> <span class=\"n\">f<\/span><span class=\"o\">.<\/span><span class=\"n\">resume<\/span>\n  <span class=\"nb\">p<\/span> <span class=\"n\">f<\/span><span class=\"o\">.<\/span><span class=\"n\">resume<\/span><span class=\"p\">(<\/span><span class=\"mi\">2<\/span><span class=\"p\">)<\/span>\n<span class=\"k\">end<\/span>\n\n<span class=\"cp\">__END__<\/span>\n\n<span class=\"cp\">$ ruby fbr.rb <\/span>\n<span class=\"cp\">hi<\/span>\n<span class=\"cp\">1<\/span>\n<span class=\"cp\">2<\/span>\n<span class=\"cp\">bye<\/span>\n<span class=\"cp\">:done<\/span>\n\n<span class=\"cp\">$ ruby1.9 fbr.rb <\/span>\n<span class=\"cp\">hi<\/span>\n<span class=\"cp\">1<\/span>\n<span class=\"cp\">2<\/span>\n<span class=\"cp\">bye<\/span>\n<span class=\"cp\">:done<\/span>\n<\/pre><\/div>\n</div>');
document.write('<div class="flowcoder_bottombar flowcoder_clearfix">');
document.write('<div class="flowcoder_postedby">Posted by <a href=\"http://flowcoder.com/zh\">zh<\/a> on <a href=\"http://flowcoder.com/\">Flowcoder<\/a></div>');
document.write('<div class="flowcoder_viewraw"><a href=\"http://flowcoder.com/139.txt\">view raw<\/a></div>');
document.write('</div></div>');
