mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
859a7a9277
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1341 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
209 lines
3.9 KiB
Ruby
209 lines
3.9 KiB
Ruby
#
|
||
# irb/multi-irb.rb - multiple irb module(JP: $BJ#?t(Birb$BBP1~%b%8%e!<%k(B)
|
||
# $Release Version: 0.7.3$
|
||
# $Revision$
|
||
# $Date$
|
||
# by Keiju ISHITSUKA(keiju@ishitsuka.com)
|
||
#
|
||
# --
|
||
#
|
||
#
|
||
#
|
||
IRB.fail CanNotGoMultiIrbMode unless defined?(Thread)
|
||
require "thread"
|
||
|
||
module IRB
|
||
# job management class
|
||
# (JP: job$B4IM}%/%i%9(B)
|
||
class JobManager
|
||
@RCS_ID='-$Id$-'
|
||
|
||
def initialize
|
||
# @jobs = [[thread, irb],...]
|
||
@jobs = []
|
||
@current_job = nil
|
||
end
|
||
|
||
attr_accessor :current_job
|
||
|
||
def n_jobs
|
||
@jobs.size
|
||
end
|
||
|
||
def thread(key)
|
||
th, irb = search(key)
|
||
irb
|
||
end
|
||
|
||
def irb(key)
|
||
th, irb = search(key)
|
||
irb
|
||
end
|
||
|
||
def main_thread
|
||
@jobs[0][0]
|
||
end
|
||
|
||
def main_irb
|
||
@jobs[0][1]
|
||
end
|
||
|
||
def insert(irb)
|
||
@jobs.push [Thread.current, irb]
|
||
end
|
||
|
||
def switch(key)
|
||
th, irb = search(key)
|
||
IRB.fail IrbAlreadyDead unless th.alive?
|
||
IRB.fail IrbSwitchToCurrentThread if th == Thread.current
|
||
@current_job = irb
|
||
th.run
|
||
Thread.stop
|
||
@current_job = irb(Thread.current)
|
||
end
|
||
|
||
def kill(*keys)
|
||
for key in keys
|
||
th, irb = search(key)
|
||
IRB.fail IrbAlreadyDead unless th.alive?
|
||
th.exit
|
||
end
|
||
end
|
||
|
||
def search(key)
|
||
case key
|
||
when Integer
|
||
@jobs[key]
|
||
when Irb
|
||
@jobs.find{|k, v| v.equal?(irb)}
|
||
when Thread
|
||
@jobs.assoc(key)
|
||
else
|
||
assoc = @jobs.find{|k, v| v.context.main.equal?(key)}
|
||
IRB.fail NoSuchJob, key if assoc.nil?
|
||
assoc
|
||
end
|
||
end
|
||
|
||
def delete(key)
|
||
case key
|
||
when Integer
|
||
IRB.fail NoSuchJob, key unless @jobs[key]
|
||
@jobs[key] = nil
|
||
else
|
||
catch (:EXISTS) do
|
||
@jobs.each_index do
|
||
|i|
|
||
if @jobs[i] and (@jobs[i][0] == key ||
|
||
@jobs[i][1] == key ||
|
||
@jobs[i][1].context.main.equal?(key))
|
||
@jobs[i] = nil
|
||
throw :EXISTS
|
||
end
|
||
end
|
||
IRB.fail NoSuchJob, key
|
||
end
|
||
end
|
||
until assoc = @jobs.pop; end unless @jobs.empty?
|
||
@jobs.push assoc
|
||
end
|
||
|
||
def inspect
|
||
ary = []
|
||
@jobs.each_index do
|
||
|i|
|
||
th, irb = @jobs[i]
|
||
next if th.nil?
|
||
|
||
if th.alive?
|
||
if th.stop?
|
||
t_status = "stop"
|
||
else
|
||
t_status = "running"
|
||
end
|
||
else
|
||
t_status = "exited"
|
||
end
|
||
ary.push format("#%d->%s on %s (%s: %s)",
|
||
i,
|
||
irb.context.irb_name,
|
||
irb.context.main,
|
||
th,
|
||
t_status)
|
||
end
|
||
ary.join("\n")
|
||
end
|
||
end
|
||
|
||
@JobManager = JobManager.new
|
||
|
||
def IRB.JobManager
|
||
@JobManager
|
||
end
|
||
|
||
# invoke multi-irb
|
||
# (JP: irb$B5/F0(B)
|
||
def IRB.irb(file = nil, *main)
|
||
workspace = WorkSpace.new(*main)
|
||
parent_thread = Thread.current
|
||
Thread.start do
|
||
begin
|
||
irb = Irb.new(workspace, file)
|
||
rescue
|
||
print "Subirb can't start with context(self): ", workspace.main.inspect, "\n"
|
||
print "return to main irb\n"
|
||
Thread.pass
|
||
Thread.main.wakeup
|
||
Thread.exit
|
||
end
|
||
@CONF[:IRB_RC].call(irb.context) if @CONF[:IRB_RC]
|
||
@JobManager.insert(irb)
|
||
begin
|
||
system_exit = false
|
||
catch(:IRB_EXIT) do
|
||
irb.eval_input
|
||
end
|
||
rescue SystemExit
|
||
system_exit = true
|
||
raise
|
||
#fail
|
||
ensure
|
||
unless system_exit
|
||
@JobManager.delete(irb)
|
||
if parent_thread.alive?
|
||
@JobManager.current_job = @JobManager.irb(parent_thread)
|
||
parent_thread.run
|
||
else
|
||
@JobManager.current_job = @JobManager.main_irb
|
||
@JobManager.main_thread.run
|
||
end
|
||
end
|
||
end
|
||
end
|
||
Thread.stop
|
||
@JobManager.current_job = @JobManager.irb(Thread.current)
|
||
end
|
||
|
||
class Context
|
||
def _=(value)
|
||
@_ = value
|
||
@workspace.evaluate "_ = IRB.JobManager.irb(Thread.current).context._"
|
||
end
|
||
end
|
||
|
||
module ExtendCommand
|
||
def irb_context
|
||
IRB.JobManager.irb(Thread.current).context
|
||
end
|
||
# alias conf irb_context
|
||
end
|
||
|
||
@CONF[:SINGLE_IRB_MODE] = false
|
||
@JobManager.insert(@CONF[:MAIN_CONTEXT].irb)
|
||
@JobManager.current_job = @CONF[:MAIN_CONTEXT].irb
|
||
|
||
trap("SIGINT") do
|
||
@JobManager.current_job.signal_handle
|
||
end
|
||
|
||
end
|