From: knu@... Date: 2014-10-31T13:22:03+00:00 Subject: [ruby-core:66035] [ruby-trunk - Bug #9494] [Closed] Race condition in autoload of Digest::SHA256, etc. Issue #9494 has been updated by Akinori MUSHA. Status changed from Assigned to Closed % Done changed from 0 to 100 Applied in changeset r48213. ---------- Make Digest() thread-safe. * ext/digest/lib/digest.rb (Digest()): This function should now be thread-safe. If you have a problem with regard to on-demand loading under a multi-threaded environment, preload "digest/*" modules on boot or use this method instead of directly referencing Digest::*. [Bug #9494] cf. https://github.com/aws/aws-sdk-ruby/issues/525 ---------------------------------------- Bug #9494: Race condition in autoload of Digest::SHA256, etc. https://bugs.ruby-lang.org/issues/9494#change-49754 * Author: Conrad Irwin * Status: Closed * Priority: Normal * Assignee: Akinori MUSHA * Category: ext * Target version: * ruby -v: 2.0.0p247 * Backport: 1.9.3: UNKNOWN, 2.0.0: UNKNOWN, 2.1: UNKNOWN ---------------------------------------- At the moment the digest extension uses const_missing to implement autoload. Unfortunately there's a race condition: another thread can run after the constant is defined, but before it is initialized. (http://git.io/YW3bbA) There's a minimal test case here: http://git.io/5umBqQ ��� this was happening to us regularly in production because each sidekiq worker would race to create a hash. The work around we have deployed is to require digest/sha2.so pre-emptively. And the attached patch does that. An alternative solution would be to use `autoload`, but that is deprecated; or to change the way meta-data is stored for Digest classes so that it can be accessed immediately. There's no way to use a mutex inside const_missing to fix this, because the bug is that the constant becomes not-missing before it is fully defined. ---Files-------------------------------- require-digest-upfront.patch (1006 Bytes) -- https://bugs.ruby-lang.org/