Permalink
Browse files

Allow sim objects to unregister. this allowed us to fix a very major

memory leak in the spinneret simulation having to do with timers.  Timers
now unregister after they file or are canceled (in the case of repeating
timers).
  • Loading branch information...
Cyrus Hall
Cyrus Hall committed Apr 26, 2007
1 parent 34ca9f8 commit ea09ea30a6ce71361e1a6d6adc45794b0a161ed1
Showing with 39 additions and 17 deletions.
  1. +6 −1 lib/gosim/data.rb
  2. +5 −4 lib/gosim/rpc.rb
  3. +28 −12 lib/gosim/simulation.rb
View
@@ -149,6 +149,7 @@ def close
class DataSet
@@sets = {}
+ @@off = false
# @@handlers = {}
class << self
@@ -170,6 +171,10 @@ def [](set)
end
@@sets[set]
end
+
+ def silent(state = true)
+ @@off = state
+ end
end
def initialize(name)
@@ -181,7 +186,7 @@ def initialize(name)
# DataSet::flush_all
def log(*args)
# Always log for now.
- DataSetWriter::instance.log(@name, args)
+ DataSetWriter::instance.log(@name, args) if !@@off
EventCast.instance.publish(@name, *args)
# if @@handlers[@name]
View
@@ -36,6 +36,7 @@ class RPCErrorResponse < RPCResponse; end
class RPCDeferred < Net::Deferred
def initialize(uid = nil)
@uid = uid
+ @default_eb = @default_cb = nil
super()
end
@@ -128,14 +129,14 @@ def handle_rpc_request(request)
method = request[0]
request = request[1]
+ request = @receive_aspects.inject(request) do | x, aspect |
+ x = aspect.call(method, x)
+ end
+
#puts "top of request"
if alive?
#puts "1 request...#{request.inspect}"
#
- request = @receive_aspects.inject(request) do | x, aspect |
- x = aspect.call(method, x)
- end
-
# If there is no response delete the deferred.
# TODO: Maybe we want to signal something to the deferred here also?
result = send(request.method, *request.args)
View
@@ -34,8 +34,8 @@ def reset
# Set a block of code to run after wait_time units of time. If the
# is_periodic flag is set it will continue to run every wait_time units.
- def set_timeout(wait_time, is_periodic = false, &block)
- SimTimeout.new(wait_time, is_periodic, block)
+ def set_timeout(wait_time, is_periodic = false, data = nil, method = nil, &block)
+ SimTimeout.new(wait_time, is_periodic, data, method || block)
end
# Override the default inspect so entities with lots of state don't fill
@@ -57,37 +57,48 @@ class SimTimeout < Entity
attr_reader :time, :is_periodic, :active
- def initialize(time, is_periodic, block)
+ def initialize(time, is_periodic, data, block)
super()
@time = time
@is_periodic = is_periodic
@block = block
@active = true
+ @data = data
setup_timer
end
def setup_timer
- @active = true
@sim.schedule_event(:handle_timeout, @sid, @time, self)
end
- alias start reset
+
+ private :setup_timer
def cancel
@active = false
+ @sim.unregister_entity(@sid, self)
end
alias stop cancel
- def start
- @active = true
- setup_timer
- end
-
def handle_timeout(timeout)
# Test twice in case the timeout was canceled in the block.
- @block.call(self) if @active
- setup_timer if @active and @is_periodic
+ #puts @is_periodic
+ if @active
+ if @data
+ @block.call(self, @data)
+ else
+ @block.call(self)
+ end
+ end
+
+ if @active && @is_periodic
+ setup_timer
+ end
+
+ if !@is_periodic
+ @sim.unregister_entity(@sid, self)
+ end
end
def inspect
@@ -171,6 +182,11 @@ def register_entity(sid, entity)
@handlers[sid] = {}
end
+ def unregister_entity(sid, entity)
+ @entities.delete(sid)
+ @handlers.delete(sid)
+ end
+
def add_handler(sid, event_id, &block)
@handlers[sid][event_id] = block
end

0 comments on commit ea09ea3

Please sign in to comment.