Skip to content

Instantly share code, notes, and snippets.

@evanphx
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evanphx/6eef92f2c40662a4171b to your computer and use it in GitHub Desktop.
Save evanphx/6eef92f2c40662a4171b to your computer and use it in GitHub Desktop.
CREF for sclass shared between threads
num_threads = (ARGV[0] || 2).to_i
num_iterations = (ARGV[1] || num_threads).to_i
def url_helpers
Module.new do
class << self
# This line changes everything. It causes the GIL to switch to another
# thread. That other thread mutates the CREF that is accidentally shared
# between these independent sclass scopes, causing the def below to add
# the method on an entirely different sclass.
puts "inside"
attr_reader :before
def url_options; {}; end
attr_reader :after
end
unless respond_to? :url_options
raise "method definiton has failed - #{self.methods(false)}"
end
end
end
threads = []
num_threads.times do |thread_num|
threads << Thread.new(thread_num) do |num|
puts "S - #{num}"
num_iterations.times do |i|
url_helpers
end
puts "E - #{num}"
end
end
threads.each do |thr|
thr.join
end
@ryanclark2
Copy link

Hey Evan, which line? #6, class << self? Would this be the case in any codebase where this is used in a threaded app?

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