104 lines
2.0 KiB
Ruby
104 lines
2.0 KiB
Ruby
|
require 'msf/core/plugin'
|
||
|
|
||
|
module Msf
|
||
|
|
||
|
###
|
||
|
#
|
||
|
# This class manages the threads spawned by the framework object, this provides some additional
|
||
|
# features over standard ruby threads.
|
||
|
#
|
||
|
###
|
||
|
class ThreadManager < Array
|
||
|
|
||
|
include Framework::Offspring
|
||
|
|
||
|
attr_accessor :monitor
|
||
|
|
||
|
#
|
||
|
# Initializes the thread manager.
|
||
|
#
|
||
|
def initialize(framework)
|
||
|
self.framework = framework
|
||
|
self.monitor = spawn_monitor
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Spawns a monitor thread for removing dead threads
|
||
|
#
|
||
|
def spawn_monitor
|
||
|
::Thread.new do
|
||
|
begin
|
||
|
|
||
|
::Thread.current[:tm_name] = "Thread Monitor"
|
||
|
::Thread.current[:tm_crit] = true
|
||
|
|
||
|
while true
|
||
|
::IO.select(nil, nil, nil, 1.0)
|
||
|
self.each_index do |i|
|
||
|
state = self[i].alive? rescue false
|
||
|
self[i] = nil if not state
|
||
|
end
|
||
|
self.delete(nil)
|
||
|
end
|
||
|
|
||
|
rescue ::Exception => e
|
||
|
elog("thread monitor: #{e} #{e.backtrace} source:#{self[:tm_call].inspect}")
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Spawns a new thread
|
||
|
#
|
||
|
def spawn(name, crit, *args, &block)
|
||
|
t = nil
|
||
|
|
||
|
if block
|
||
|
t = ::Thread.new(name, crit, caller, block, *args) do |*argv|
|
||
|
::Thread.current[:tm_name] = argv.shift.to_s
|
||
|
::Thread.current[:tm_crit] = argv.shift
|
||
|
::Thread.current[:tm_call] = argv.shift
|
||
|
::Thread.current[:tm_time] = Time.now
|
||
|
|
||
|
begin
|
||
|
argv.shift.call(*argv)
|
||
|
rescue ::Exception => e
|
||
|
elog("thread exception: #{::Thread.current[:tm_name]} critical=#{::Thread.current[:tm_crit]} error:#{e.class} #{e} #{e.backtrace} source:#{::Thread.current[:tm_call].inspect}")
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
t = ::Thread.new(name, crit, caller, *args) do |*argv|
|
||
|
::Thread.current[:tm_name] = argv.shift
|
||
|
::Thread.current[:tm_crit] = argv.shift
|
||
|
::Thread.current[:tm_call] = argv.shift
|
||
|
::Thread.current[:tm_time] = Time.now
|
||
|
end
|
||
|
end
|
||
|
|
||
|
self << t
|
||
|
t
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Registers an existing thread
|
||
|
#
|
||
|
def register(t, name, crit)
|
||
|
t[:tm_name] = name
|
||
|
t[:tm_crit] = crit
|
||
|
t[:tm_call] = caller
|
||
|
t[:tm_time] = Time.now
|
||
|
self << t
|
||
|
t
|
||
|
end
|
||
|
|
||
|
#
|
||
|
# Kills a thread by index
|
||
|
#
|
||
|
def kill(idx)
|
||
|
self[idx].kill rescue false
|
||
|
end
|
||
|
|
||
|
end
|
||
|
|
||
|
end
|