Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 11aad5b0d5c1
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 670e43692d9b
Choose a head ref
  • 2 commits
  • 2 files changed
  • 1 contributor

Commits on Aug 11, 2016

  1. Copy the full SHA
    56807f0 View commit details
  2. Synchronize around getgrgid call. Fixes #4057.

    getgrgid is thread-safe on OS X, but other platforms are not
    required to be thread-safe by the POSIX specification. It appears
    that at least some flavors of Linux do not have thread-safe
    getgrgid. To aid users who might be calling it across threads, we
    lock around the native getgrgid call.
    
    I chose to lock around the RubyEtc.class to ensure the native call
    is single-threaded for all JRuby instances in a given classloader.
    There's no clean way to make that guarantee across classloaders.
    headius committed Aug 11, 2016
    Copy the full SHA
    670e436 View commit details
Showing with 32 additions and 8 deletions.
  1. +8 −1 core/src/main/java/org/jruby/ext/etc/RubyEtc.java
  2. +24 −7 lib/ruby/1.9/digest.rb
9 changes: 8 additions & 1 deletion core/src/main/java/org/jruby/ext/etc/RubyEtc.java
Original file line number Diff line number Diff line change
@@ -387,7 +387,14 @@ public static IRubyObject group(IRubyObject recv, Block block) {
public static IRubyObject getgrent(IRubyObject recv) {
Ruby runtime = recv.getRuntime();
try {
Group gr = runtime.getPosix().getgrent();
Group gr;

// We synchronize on this class so at least all JRuby instances in this classloader are safe.
// See jruby/jruby#4057
synchronized (RubyEtc.class) {
gr = runtime.getPosix().getgrent();
}

if (gr != null) {
return setupGroup(recv.getRuntime(), gr);
} else {
31 changes: 24 additions & 7 deletions lib/ruby/1.9/digest.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# frozen_string_literal: false
require 'digest.so'

module Digest
@@ -26,12 +27,14 @@ def self.const_missing(name) # :nodoc:
end

class ::Digest::Class
# creates a digest object and reads a given file, _name_.
# Creates a digest object and reads a given file, _name_.
# Optional arguments are passed to the constructor of the digest
# class.
#
# p Digest::SHA256.file("X11R6.8.2-src.tar.bz2").hexdigest
# # => "f02e3c85572dc9ad7cb77c2a638e3be24cc1b5bea9fdbb0b0299c9668475c534"
def self.file(name)
new.file(name)
def self.file(name, *args)
new(*args).file(name)
end

# Returns the base64 encoded hash value of a given _string_. The
@@ -43,7 +46,7 @@ def self.base64digest(str, *args)
end

module Instance
# updates the digest with the contents of a given file _name_ and
# Updates the digest with the contents of a given file _name_ and
# returns self.
def file(name)
File.open(name, "rb") {|f|
@@ -79,15 +82,29 @@ def base64digest!
# call-seq:
# Digest(name) -> digest_subclass
#
# Returns a Digest subclass by +name+.
# Returns a Digest subclass by +name+ in a thread-safe manner even
# when on-demand loading is involved.
#
# require 'digest'
#
# Digest("MD5")
# # => Digest::MD5
#
# Digest("Foo")
# Digest(:SHA256)
# # => Digest::SHA256
#
# Digest(:Foo)
# # => LoadError: library not found for class Digest::Foo -- digest/foo
def Digest(name)
Digest.const_get(name)
const = name.to_sym

# Ignore autoload's because it is void when we have #const_missing
Digest.const_missing(const)
rescue LoadError
# Constants do not necessarily rely on digest/*.
if Digest.const_defined?(const)
Digest.const_get(const)
else
raise
end
end