Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creation of singleton dependencies is not thread-safe #18

Open
KevinBrowne opened this issue Feb 21, 2024 · 0 comments
Open

Creation of singleton dependencies is not thread-safe #18

KevinBrowne opened this issue Feb 21, 2024 · 0 comments
Labels

Comments

@KevinBrowne
Copy link
Member

KevinBrowne commented Feb 21, 2024

Sinject::Container#get has no critical sections, meaning that requesting a singleton dependency is not guaranteed to return the same object each time. Though unlikely in practice, timing issues may result in the generation of multiple instances of a supposed singleton.

Steps to reproduce:

(A contrived example, admittedly.)

require 'sinject'
container = Sinject::Container.new(false)
# obvious contrivance!
container.register(key: :foo, class: Array, singleton: true) { sleep(1); [] }

objects = Set.new.compare_by_identity
mutex = Mutex.new
3500.times.map do
  Thread.new do
    o = container.get(:foo)
    mutex.synchronize { objects.add(o) }
  end
end.each(&:join)
objects.size

Expected:

objects.size is 1.

Actual:

objects.size is greater than 1, the exact number being subject to the timing of the threads' execution.

Where objects.size is less than the number of threads spawned, this shows that eventually #get does return the same instance each time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

1 participant