From: Tom Felker Date: 2003-06-02T14:34:13+09:00 Subject: Re: thread-unsafe stuff: could you summarize? While you're asking that, I have a similar question: is the following thread-safe? (This is part of PeerTalk, a LAN chat program I'm writing.) ----- =begin defer.rb - the Defer module Defer is used to defer the execution of a block of code, to simplify multi-threaded programming. Defer is useful when a GUI thread must be the only thread that interacts with the toolkit, but other threads may make demands on the GUI at any time. Defer can be mixed in to the GUI class. To defer a block, call defer with the block. This can be done from any thread, and defer will return immediately. When you are ready to run the blocks, call run_deferred, which will execute the blocks in the context of the calling thread (not the thread which defered them). If a deferred block defers a block, that block will be executed immediately, and the callback won't be called. To be notified when a block is deferred, call set_defer_callback with an associated block. This block will be called whenever a block is deferred, in the context of the thread defering it. You can use this to notify the GUI thread that calling run_deferred is necessary. =end require "thread" module Defer def initialize super @deferBlocks = Queue.new @deferRunning = false @deferCallback = Proc.new { } @deferMutex = Mutex.new end def defer if @deferRunning yield else @deferBlocks.push Proc.new @deferCallback.call end end def run_deferred return if @deferRunning @deferMutex.synchronize do @deferRunning = true begin until @deferBlocks.empty? @deferBlocks.pop.call end ensure @deferRunning = false end end end def set_defer_callback @deferCallback = Proc.new end end class Deferrer include Defer def initialize(*args) super(*args) end end -- Tom Felker If we developed a replicator, it would be banned for its threat to the profits of existing business.