Skip to content

Commit

Permalink
make sure only one finalizer is defined per thread
Browse files Browse the repository at this point in the history
  • Loading branch information
schoefmann committed Mar 10, 2009
1 parent 9884294 commit f4fd003
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 6 deletions.
8 changes: 4 additions & 4 deletions lib/tlattr_accessors.rb
Expand Up @@ -33,11 +33,11 @@ def #{name}
def #{name}=(val)
#{ivar} = Hash.new #{'{|h, k| h[k] = val}' if first_is_default} unless #{ivar}
unless #{ivar}.has_key?(Thread.current)
finalize = Thread.current.object_id # required for JRuby compatibility
ObjectSpace.define_finalizer(Thread.current, lambda { #{ivar}.delete(finalize) })
thread_id = Thread.current.object_id
unless #{ivar}.has_key?(thread_id)
ObjectSpace.define_finalizer(Thread.current, lambda { #{ivar}.delete(thread_id) })
end
#{ivar}[Thread.current.object_id] = val
#{ivar}[thread_id] = val
end
}, __FILE__, __LINE__
end
Expand Down
11 changes: 10 additions & 1 deletion spec/thread_local_accessors_spec.rb
Expand Up @@ -60,7 +60,6 @@ def initialize(value)
x.bar.should == 2
end

# This will epically FAIL under JRuby, as JRuby doesn't support finalizers
it 'should not leak memory' do
x = Foo.new
n = 6000
Expand All @@ -74,5 +73,15 @@ def initialize(value)
hash.size.should < (n / 2) # it should be a lot lower than n!
end

it 'should define only one finalizer per thread' do
ObjectSpace.should_receive(:define_finalizer).exactly(:twice)
x = Foo.new
2.times do
Thread.new do
10.times { x.foo = "bar" }
end.join
end
end

end

2 changes: 1 addition & 1 deletion tlattr_accessors.gemspec
Expand Up @@ -2,7 +2,7 @@

Gem::Specification.new do |s|
s.name = %q{tlattr_accessors}
s.version = "0.0.2"
s.version = "0.0.3"
s.authors = ["Maximilian Sch\303\266fmann"]
s.date = %q{2009-03-10}
s.description = "thread-local accessors for your classes"
Expand Down

0 comments on commit f4fd003

Please sign in to comment.