lib/systemu.rb in systemu-1.1.0 vs lib/systemu.rb in systemu-1.2.0

- old
+ new

@@ -1,5 +1,6 @@ +# vim: ts=2:sw=2:sts=2:et:fdm=marker require 'tmpdir' require 'socket' require 'fileutils' require 'rbconfig' require 'thread' @@ -8,16 +9,15 @@ class Object def systemu(*a, &b) SystemUniversal.new(*a, &b).systemu end end class SystemUniversal -#--{{{ # # constants # - SystemUniversal::VERSION = '1.1.0' unless defined? SystemUniversal::VERSION - def version() VERSION end + SystemUniversal::VERSION = '1.2.0' unless defined? SystemUniversal::VERSION + def version() SystemUniversal::VERSION end # # class methods # @host = Socket.gethostname @@ -40,11 +40,10 @@ # # instance methods # def initialize argv, opts = {}, &block -#--{{{ getopt = getopts opts @argv = argv @block = block @@ -56,25 +55,20 @@ @host = getopt[ 'host', self.class.host ] @ppid = getopt[ 'ppid', self.class.ppid ] @pid = getopt[ 'pid', self.class.pid ] @ruby = getopt[ 'ruby', self.class.ruby ] -#--}}} end def systemu -#--{{{ tmpdir do |tmp| c = child_setup tmp status = nil - if @block - q = Queue.new - t = Thread.new{ Thread.current_abort_on_exception = true; @block[ q.pop ] } - end - begin + thread = nil + quietly{ IO.popen "#{ @ruby } #{ c['program'] }", 'r+' do |pipe| line = pipe.gets case line when %r/^pid: \d+$/ @@ -88,33 +82,50 @@ raise e rescue raise "wtf?\n#{ buf }\n" end end - cid = Integer pipe.gets - q.push cid if @block + thread = new_thread cid, @block if @block pipe.read rescue nil end } status = $? ensure - t.kill rescue nil if t + if thread + begin + class << status + attr 'thread' + end + status.instance_eval{ @thread = thread } + rescue + 42 + end + end end if @stdout or @stderr open(c['stdout']){|f| relay f => @stdout} if @stdout open(c['stderr']){|f| relay f => @stderr} if @stderr status else [status, IO.read(c['stdout']), IO.read(c['stderr'])] end end -#--}}} end + def new_thread cid, block + q = Queue.new + Thread.new(cid) do |cid| + current = Thread.current + current.abort_on_exception = true + q.push current + block.call cid + end + q.pop + end + def child_setup tmp -#--{{{ stdin = File.expand_path(File.join(tmp, 'stdin')) stdout = File.expand_path(File.join(tmp, 'stdout')) stderr = File.expand_path(File.join(tmp, 'stderr')) program = File.expand_path(File.join(tmp, 'program')) config = File.expand_path(File.join(tmp, 'config')) @@ -138,25 +149,21 @@ open(config, 'w'){|f| YAML.dump c, f} open(program, 'w'){|f| f.write child_program(config)} c -#--}}} end def quietly -#--{{{ v = $VERBOSE $VERBOSE = nil yield ensure $VERBOSE = v -#--}}} end def child_program config -#--{{{ <<-program PIPE = STDOUT.dup begin require 'yaml' @@ -174,36 +181,32 @@ STDIN.reopen stdin STDOUT.reopen stdout STDERR.reopen stderr - PIPE.puts "pid: #{ Process.pid }" + PIPE.puts "pid: \#{ Process.pid }" PIPE.flush ### the process is ready yo! PIPE.close exec *argv rescue Exception => e PIPE.write Marshal.dump(e) rescue nil exit 42 end program -#--}}} end def relay srcdst -#--{{{ src, dst, ignored = srcdst.to_a.first if src.respond_to? 'read' while((buf = src.read(8192))); dst << buf; end else src.each{|buf| dst << buf} end -#--}}} end def tmpdir d = Dir.tmpdir, max = 42, &b -#--{{{ i = -1 and loop{ i += 1 tmp = File.join d, "systemu_#{ @host }_#{ @ppid }_#{ @pid }_#{ rand }_#{ i += 1 }" @@ -224,15 +227,13 @@ else tmp end ) } -#--}}} end def getopts opts = {} -#--{{{ lambda do |*args| keys, default, ignored = args catch('opt') do [keys].flatten.each do |key| [key, key.to_s, key.to_s.intern].each do |key| @@ -240,15 +241,24 @@ end end default end end -#--}}} end -#--}}} end SystemU = SystemUniversal unless defined? SystemU + + + + + + + + + + + if $0 == __FILE__ # # date