Skip to content

Commit

Permalink
Merge branch 'jruby-9.1'
Browse files Browse the repository at this point in the history
headius committed Nov 28, 2017

Verified

This commit was signed with the committer’s verified signature.
headius Charles Oliver Nutter
2 parents 54f890d + e43ee25 commit 412f7d4
Showing 9 changed files with 82 additions and 33 deletions.
21 changes: 1 addition & 20 deletions core/src/main/java/org/jruby/RubyFileTest.java
Original file line number Diff line number Diff line change
@@ -281,26 +281,7 @@ public static IRubyObject sticky_p(IRubyObject recv, IRubyObject filename) {

@JRubyMethod(name = "symlink?", required = 1, module = true)
public static RubyBoolean symlink_p(IRubyObject recv, IRubyObject filename) {
Ruby runtime = recv.getRuntime();

Path p = new File(filename.toString()).toPath();

try {
// Note: We can't use file.exists() to check whether the symlink
// exists or not, because that method returns false for existing
// but broken symlink. So, we try without the existence check,
// but in the try-catch block.
// MRI behavior: symlink? on broken symlink should return true.
BasicFileAttributes attrs = Files.readAttributes(p, BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);

return runtime.newBoolean(attrs != null && attrs.isSymbolicLink());
} catch (SecurityException se) {
return runtime.getFalse();
} catch (IOException ie) {
return runtime.getFalse();
} catch (UnsupportedOperationException uoe) {
return runtime.getFalse();
}
return recv.getRuntime().newBoolean(fileResource(filename).isSymLink());
}

// We do both writable and writable_real through the same method because
14 changes: 11 additions & 3 deletions core/src/main/java/org/jruby/RubyTime.java
Original file line number Diff line number Diff line change
@@ -1544,9 +1544,17 @@ private static RubyTime createTime(ThreadContext context, RubyClass klass, IRuby
boolean fractionalUSecGiven = args[6] instanceof RubyFloat || args[6] instanceof RubyRational;

if (fractionalUSecGiven) {
double micros = RubyNumeric.num2dbl(args[6]);
time.dt = dt.withMillis(dt.getMillis() + (long) (micros / 1000));
nanos = (long) Math.rint((micros * 1000) % 1000000);
if (args[6] instanceof RubyRational) {
RubyRational usecRat = (RubyRational) args[6];
RubyRational nsecRat = (RubyRational) usecRat.op_mul(context, runtime.newFixnum(1000));
double tmpNanos = nsecRat.getDoubleValue(context);
time.dt = dt.withMillis((long) (dt.getMillis() + (tmpNanos / 1000000)));
nanos = (long) tmpNanos % 1000000;
} else {
double micros = RubyNumeric.num2dbl(args[6]);
time.dt = dt.withMillis(dt.getMillis() + (long) (micros / 1000));
nanos = (long) Math.rint((micros * 1000) % 1000000);
}
} else {
int usec = i_args4 % 1000;
int msec = i_args4 / 1000;
13 changes: 9 additions & 4 deletions core/src/main/java/org/jruby/ext/fiber/ThreadFiber.java
Original file line number Diff line number Diff line change
@@ -275,10 +275,19 @@ public void run() {
result = block.yieldArray(context, init, null);
}

// Clear ThreadFiber's thread since we're on the way out and need to appear non-alive?
// Waiting thread can proceed immediately after push below but before we are truly dead.
// See https://github.com/jruby/jruby/issues/4838
ThreadFiber tf = data.fiber.get();
if (tf != null) tf.thread = null;

data.prev.data.queue.push(context, new IRubyObject[]{result});
} finally {
// Ensure we do everything for shutdown now
data.queue.shutdown();
runtime.getThreadService().disposeCurrentThread();
ThreadFiber tf = data.fiber.get();
if (tf != null) tf.thread = null;
}
} catch (JumpException.FlowControlException fce) {
if (data.prev != null) {
@@ -304,10 +313,6 @@ public void run() {
if (data.prev != null) {
data.prev.thread.raise(JavaUtil.convertJavaToUsableRubyObject(runtime, t));
}
} finally {
// clear reference to the fiber's thread
ThreadFiber tf = data.fiber.get();
if (tf != null) tf.thread = null;
}
}
});
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ext/ripper/StringTerm.java
Original file line number Diff line number Diff line change
@@ -404,4 +404,4 @@ private void parseEscapeIntoBuffer(RipperLexer lexer, LexerSource src, ByteList
buffer.append(c);
}
}
}
}
5 changes: 5 additions & 0 deletions core/src/main/java/org/jruby/ext/socket/RubyUDPSocket.java
Original file line number Diff line number Diff line change
@@ -129,6 +129,11 @@ public IRubyObject initialize(ThreadContext context, ProtocolFamily family) {
throw runtime.newErrnoECONNREFUSEDError();
} catch (UnknownHostException e) {
throw SocketUtils.sockerr(runtime, "initialize: name or service not known");
} catch (UnsupportedOperationException uoe) {
if (uoe.getMessage().contains("IPv6 not available")) {
throw runtime.newErrnoEAFNOSUPPORTError("socket(2) - udp");
}
throw sockerr(runtime, "UnsupportedOperationException: " + uoe.getLocalizedMessage(), uoe);
} catch (IOException e) {
throw sockerr(runtime, "initialize: name or service not known", e);
}
12 changes: 11 additions & 1 deletion core/src/main/java/org/jruby/ext/thread/Mutex.java
Original file line number Diff line number Diff line change
@@ -130,15 +130,25 @@ public IRubyObject sleep(ThreadContext context) {
public IRubyObject sleep(ThreadContext context, IRubyObject timeout) {
long beg = System.currentTimeMillis();
double t = timeout.convertToFloat().getDoubleValue();

if (t < 0) throw context.runtime.newArgumentError("negative sleep timeout");

unlock(context);

try {
context.getThread().sleep((long) (t * 1000));
long millis = (long) (t * 1000);

if (Double.compare(t, 0.0d) == 0 || millis == 0) {
// wait time is zero or smaller than 1ms, so we just proceed
} else {
context.getThread().sleep(millis);
}
} catch (InterruptedException ex) {
// ignore interrupted
} finally {
lock(context);
}

return context.runtime.newFixnum((System.currentTimeMillis() - beg) / 1000);
}

22 changes: 18 additions & 4 deletions core/src/main/java/org/jruby/util/RegularFileResource.java
Original file line number Diff line number Diff line change
@@ -15,6 +15,9 @@
import java.io.RandomAccessFile;
import java.nio.channels.Channel;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.attribute.BasicFileAttributes;

import org.jruby.ext.fcntl.FcntlLibrary;
import org.jruby.RubyFile;
@@ -93,10 +96,21 @@ public boolean isDirectory() {

@Override
public boolean isSymLink() {
FileStat stat = posix.allocateStat();

return posix.lstat(file.getAbsolutePath(), stat) < 0 ?
false : stat.isSymlink();
try {
// Note: We can't use file.exists() to check whether the symlink exists or not, because that method
// returns false for existing but broken symlink. So, we try without the existence check, but in the
// try-catch block.
// MRI behavior: symlink? on broken symlink should return true.
BasicFileAttributes attrs = Files.readAttributes(file.toPath(), BasicFileAttributes.class, LinkOption.NOFOLLOW_LINKS);

return attrs != null && attrs.isSymbolicLink();
} catch (SecurityException se) {
return false;
} catch (IOException ie) {
return false;
} catch (UnsupportedOperationException uoe) {
return false;
}
}

@Override
19 changes: 19 additions & 0 deletions spec/ruby/core/mutex/sleep_spec.rb
Original file line number Diff line number Diff line change
@@ -71,4 +71,23 @@
m.lock
m.sleep(0.01).should be_kind_of(Integer)
end

it "wakes up when requesting sleep times near or equal to zero" do
times = []
val = 1

# power of two divisor so we eventually get near zero
loop do
val = val / 16.0
times << val
break if val == 0.0
end

m = Mutex.new
m.lock
times.each do |time|
# just testing that sleep completes
m.sleep(time).should_not == nil
end
end
end
7 changes: 7 additions & 0 deletions spec/ruby/core/time/shared/gm.rb
Original file line number Diff line number Diff line change
@@ -19,4 +19,11 @@
it "interprets post-Gregorian reform dates using Gregorian calendar" do
Time.send(@method, 1582, 10, 15, 12).to_i.should == -12219249600 # 2299161j
end

it "handles fractional usec close to rounding limit" do
time = Time.send(@method, 2000, 1, 1, 12, 30, 0, 9999r/10000)

time.usec.should == 0
time.nsec.should == 999
end
end

0 comments on commit 412f7d4

Please sign in to comment.