Skip to content

Commit

Permalink
[Truffle] Read files interruptedly and deal with ClosedByInterruptExc…
Browse files Browse the repository at this point in the history
…eption.
  • Loading branch information
eregon committed Jan 28, 2015
1 parent 580bd4e commit 33c7f7e
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 22 deletions.
Expand Up @@ -27,6 +27,7 @@
import org.jruby.truffle.runtime.core.RubyArray;
import org.jruby.truffle.runtime.core.RubyClass;
import org.jruby.truffle.runtime.rubinius.RubiniusByteArray;
import org.jruby.truffle.runtime.util.FileUtils;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.cli.Options;
Expand Down Expand Up @@ -166,13 +167,7 @@ public Object execute(final TranslatorDriver.ParserContext parserContext, final
// Assume UTF-8 for the moment
source = Source.fromBytes(runtime.getInstanceConfig().inlineScript(), "-e", new BytesDecoder.UTF8BytesDecoder());
} else {
final byte[] bytes;

try {
bytes = Files.readAllBytes(Paths.get(inputFile));
} catch (IOException e) {
throw new RuntimeException(e);
}
final byte[] bytes = FileUtils.readAllBytesInterruptedly(truffleContext, inputFile);

// Assume UTF-8 for the moment
source = Source.fromBytes(bytes, inputFile, new BytesDecoder.UTF8BytesDecoder());
Expand Down
18 changes: 10 additions & 8 deletions truffle/src/main/java/org/jruby/truffle/nodes/core/FileNodes.java
Expand Up @@ -13,14 +13,20 @@
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.source.SourceSection;

import jnr.posix.FileStat;

import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.UndefinedPlaceholder;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingActionWithoutGlobalLock;
import org.jruby.truffle.runtime.util.FileUtils;
import org.jruby.util.ByteList;

import java.io.*;
import java.nio.channels.ClosedByInterruptException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

@CoreClass(name = "File")
Expand Down Expand Up @@ -352,7 +358,7 @@ public RubyNilClass puts(RubyFile file, RubyString string) {

}

@CoreMethod(names = "read", isModuleFunction = true, needsSelf = false, required = 1)
@CoreMethod(names = "read", onSingleton = true, needsSelf = false, required = 1)
public abstract static class ReadFunctionNode extends CoreMethodNode {

public ReadFunctionNode(RubyContext context, SourceSection sourceSection) {
Expand All @@ -364,15 +370,11 @@ public ReadFunctionNode(ReadFunctionNode prev) {
}

@Specialization
public RubyString read(RubyString path) {
public RubyString read(RubyString file) {
notDesignedForCompilation();

try {
return new RubyString(getContext().getCoreLibrary().getStringClass(),
new ByteList(Files.readAllBytes(Paths.get(path.toString()))));
} catch (IOException e) {
throw new RuntimeException(e);
}
return new RubyString(getContext().getCoreLibrary().getStringClass(),
new ByteList(FileUtils.readAllBytesInterruptedly(getContext(), file.toString())));
}

}
Expand Down
Expand Up @@ -28,6 +28,7 @@
import org.jruby.truffle.runtime.control.RaiseException;
import org.jruby.truffle.runtime.core.*;
import org.jruby.truffle.runtime.subsystems.*;
import org.jruby.truffle.runtime.util.FileUtils;
import org.jruby.truffle.translator.NodeWrapper;
import org.jruby.truffle.translator.TranslatorDriver;
import org.jruby.util.ByteList;
Expand Down Expand Up @@ -156,13 +157,7 @@ public void loadFile(String fileName, RubyNode currentNode) {
}

private void loadFileAbsolute(String fileName, RubyNode currentNode) {
final byte[] bytes;

try {
bytes = Files.readAllBytes(Paths.get(fileName));
} catch (IOException e) {
throw new RuntimeException(e);
}
final byte[] bytes = FileUtils.readAllBytesInterruptedly(this, fileName);

// Assume UTF-8 for the moment
final Source source = Source.fromBytes(bytes, fileName, new BytesDecoder.UTF8BytesDecoder());
Expand Down
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
* code is released under a tri EPL/GPL/LGPL license. You can use it,
* redistribute it and/or modify it under the terms of the:
*
* Eclipse Public License version 1.0
* GNU General Public License version 2
* GNU Lesser General Public License version 2.1
*/
package org.jruby.truffle.runtime.util;

import java.io.IOException;
import java.nio.channels.ClosedByInterruptException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import org.jruby.truffle.nodes.RubyNode;
import org.jruby.truffle.runtime.RubyContext;
import org.jruby.truffle.runtime.subsystems.ThreadManager.BlockingActionWithoutGlobalLock;

public class FileUtils {

public static byte[] readAllBytesInterruptedly(RubyContext context, String file) {
RubyNode.notDesignedForCompilation();

final Path path = Paths.get(file.toString());

return context.getThreadManager().runUntilResult(new BlockingActionWithoutGlobalLock<byte[]>() {
@Override
public byte[] block() throws InterruptedException {
try {
// TODO: only read small chunks to avoid too much repeated execution.
return Files.readAllBytes(path);
} catch (ClosedByInterruptException e) {
throw new InterruptedException();
} catch (IOException e) {
// TODO: handle this more nicely
throw new RuntimeException(e);
}
}
});
}

}

0 comments on commit 33c7f7e

Please sign in to comment.