Thread.current.parent and Thread.current.ancestors

Discussion in 'Ruby' started by ara.t.howard@noaa.gov, Feb 16, 2007.

  1. Guest

    can anyone see issues with this:

    harp:~ > cat a.rb
    class Thread
    class << self
    alias_method "__new__", "new"

    def new *a, &b
    parent = Thread.current

    __new__(*a) do |*a|
    Thread.current.parent = parent
    b.call *a
    end
    end

    end

    def parent
    self['parent']
    end

    def parent= parent
    self['parent'] = parent
    end

    def ancestors
    list = [t = self]
    while((t = t.parent))
    list << t
    end
    list
    end
    end

    Thread.new{ Thread.new{ Thread.new{ sleep 2; p Thread.current.ancestors } } }

    STDIN.gets


    harp:~ > ruby a.rb
    [#<Thread:0xb75d2264 run>, #<Thread:0xb75d2354 dead>, #<Thread:0xb75d2444 dead>, #<Thread:0xb75df900 sleep>]


    it's hard to wrap my head around, but even GC seems like it'd be fine - the
    child, upon death, will allow the parent to be freed, and so on.

    -a
    --
    we can deny everything, except that we have the possibility of being better.
    simply reflect on that.
    - the dalai lama
     
    , Feb 16, 2007
    #1
    1. Advertising

  2. It doesn't work with Thread#start (==fork)...

    Thread#start doesn't reuse Thread.new. Neither does
    rb_thread_create(), which is used in e.g. TK.

    All three methods (new, start/fork and rb_thread_create()) come
    together in rb_thread_alloc(). That's the place where the
    parent should be set. The problem is that you can't redefine
    rb_thread_alloc() in Ruby... ;[

    I really like this Thread.current.parent or Thread.parent.
    There's at least one place where I really, really need it
    myself... Something for Ruby 1.8.6?... ;]

    gegroet,
    Erik V. - http://www.erikveen.dds.nl/
     
    Erik Veenstra, Feb 16, 2007
    #2
    1. Advertising

  3. Using new_with_parent (see below) has two advantages:

    * By calling new_with_parent, you're saying: Yes, I know that
    parent doesn't work for all threads.

    * Thread#parent doesn't return nil for "unpatched" threads,
    since it doesn't exist in the first place.

    You can achieve the same by subclassing Thread.

    Disadvantage:

    * You can only ask for parents of your own threads. You can't
    ask for a parent of e.g. a DRb thread, since those aren't
    patched.

    gegroet,
    Erik V. - http://www.erikveen.dds.nl/

    ----------------------------------------------------------------

    class Thread
    def self.new_with_parent(*args, &block)
    parent = Thread.current

    self.new do
    define_method :parent do
    parent
    end

    block.call(*args)
    end
    end
    end

    ----------------------------------------------------------------
     
    Erik Veenstra, Feb 16, 2007
    #3
  4. Guest

    On Fri, 16 Feb 2007, Erik Veenstra wrote:

    > It doesn't work with Thread#start (==fork)...
    >
    > Thread#start doesn't reuse Thread.new. Neither does
    > rb_thread_create(), which is used in e.g. TK.
    >
    > All three methods (new, start/fork and rb_thread_create()) come
    > together in rb_thread_alloc(). That's the place where the
    > parent should be set. The problem is that you can't redefine
    > rb_thread_alloc() in Ruby... ;[


    hrrrm. good point, this is the best i've come up with:


    harp:~ > cat a.rb
    class Thread
    class << self
    alias_method "__new__", "new"
    def new *a, &b
    child '__new__', *a, &b
    end
    alias_method "__start__", "start"
    def start *a, &b
    child '__start__', *a, &b
    end
    private
    def child as, *a, &b
    parent = Thread.current
    send(as, *a) do |*a|
    Thread.current.parent = parent
    b.call *a
    end
    end
    end
    def parent
    self['parent']
    end
    def parent= parent
    self['parent'] = parent
    end
    def ancestors
    return self['ancestors'] if self['ancestors']
    list = [t = self]
    while((t = t.parent))
    list << t
    end
    self['ancestors'] = list
    end
    end


    Thread.new{ Thread.new{ Thread.new{ sleep 0.42 and p [Thread.current, Thread.current.ancestors] } } }
    Thread.start{ Thread.start{ Thread.start{ sleep 0.42 and p [Thread.current, Thread.current.ancestors] } } }

    STDIN.gets


    harp:~ > ruby a.rb
    [#<Thread:0xb75cc0f8 run>, [#<Thread:0xb75cc0f8 run>, #<Thread:0xb75cc24c dead>, #<Thread:0xb75cc3a0 dead>, #<Thread:0xb75da748 sleep>]]
    [#<Thread:0xb75cc508 run>, [#<Thread:0xb75cc508 run>, #<Thread:0xb75cc65c dead>, #<Thread:0xb75cc7b0 dead>, #<Thread:0xb75da748 sleep>]]


    > I really like this Thread.current.parent or Thread.parent.
    > There's at least one place where I really, really need it
    > myself... Something for Ruby 1.8.6?... ;]


    RCR?

    -a
    --
    we can deny everything, except that we have the possibility of being better.
    simply reflect on that.
    - the dalai lama
     
    , Feb 16, 2007
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. yurick

    XML: Collecting ancestors

    yurick, Jan 14, 2004, in forum: XML
    Replies:
    2
    Views:
    544
    yurick
    Jan 15, 2004
  2. Martin Pettersson

    Multiply ancestors in xsl

    Martin Pettersson, Oct 5, 2004, in forum: XML
    Replies:
    2
    Views:
    2,129
    Martin Pettersson
    Oct 18, 2004
  3. Replies:
    6
    Views:
    544
  4. andrew cooke
    Replies:
    2
    Views:
    286
    Vinay Sajip
    Apr 26, 2008
  5. Yanick

    JQuery and ancestors

    Yanick, Dec 30, 2006, in forum: Javascript
    Replies:
    4
    Views:
    125
    Yanick
    Dec 31, 2006
Loading...

Share This Page