Skip to content

Commit

Permalink
Make 'stdin', 'stdout' and 'stderr' thread local.
Browse files Browse the repository at this point in the history
NOTE: Because the java type of those items changed from
PrintWriter/BufferedReader to ThreadLocal<PrintWriter>/ThreadLocal<BufferedReader>
this change is binary backwards compatible. In particular,
code compiled with an earlier version will try to access
'stdout' as 'PrintWriter'.
  • Loading branch information
Ingo60 committed Mar 7, 2014
1 parent 495119a commit 90df590
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 32 deletions.
4 changes: 2 additions & 2 deletions frege/compiler/GenJava7.fr
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ mainCode g sym
" " ++ "frege.runtime.Delayed.<frege.runtime.Lambda>forced(",
" " ++ show (mainClass g U.`memberOf` "_main") ++ ")));",
" final long t2 = java.lang.System.nanoTime();",
" frege.runtime.Runtime.stderr.println(",
" frege.runtime.Runtime.stderr.get().println(",
" \"runtime \" + ((((t2 - t1) + 500000) / 1000000) / 1e3) + \" wallclock seconds.\");",
" if (xit != null) java.lang.System.exit(xit);",
"}"
Expand All @@ -440,7 +440,7 @@ mainCode g sym
++ pPreludeBase.unpack g
++ "._toList(argv)).<frege.runtime.Lambda>forced()));",
" final long t2 = java.lang.System.nanoTime();",
" frege.runtime.Runtime.stderr.println(",
" frege.runtime.Runtime.stderr.get().println(",
" \"runtime \" + ((((t2 - t1) + 500000) / 1000000) / 1e3) + \" wallclock seconds.\");",
" if (xit != null) java.lang.System.exit(xit);",
"}"
Expand Down
11 changes: 8 additions & 3 deletions frege/java/IO.fr
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,14 @@ data PrintWriter = mutable native java.io.PrintWriter where
| Writer -> IO PrintWriter
| Writer -> Bool -> IO PrintWriter

native stdout frege.runtime.Runtime.stdout :: PrintWriter
native stderr frege.runtime.Runtime.stderr :: PrintWriter
native stdin frege.runtime.Runtime.stdin :: BufferedReader
--- The standard output 'PrintWriter'
native stdout "frege.runtime.Runtime.stdout.get()" :: PrintWriter

--- The standard error 'PrintWriter'
native stderr "frege.runtime.Runtime.stderr.get()" :: PrintWriter

--- The standard input 'BufferedReader'
native stdin "frege.runtime.Runtime.stdin.get()" :: BufferedReader

{--
Frege type for a @java.io.StringWriter@
Expand Down
35 changes: 25 additions & 10 deletions frege/runtime/Runtime.java
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,38 @@ final public static Class<?> getClass(Object o) {

/**
* Provide UTF-8 encoded standard printer for stdout with automatic line flushing
* <p>Must be thread local so that it works in the online REPL, for instance. </p>
*/
public static PrintWriter stdout = new PrintWriter(
new OutputStreamWriter(System.out, StandardCharsets.UTF_8),
true);
public static ThreadLocal<PrintWriter> stdout = new ThreadLocal<PrintWriter>() {
@Override protected PrintWriter initialValue() {
return new PrintWriter(
new OutputStreamWriter(System.out, StandardCharsets.UTF_8),
true);
}
};

/**
* Provide UTF-8 encoded standard printer for stderr with autoflush
* <p>Must be thread local so that it works in the online REPL, for instance. </p>
*/
public static PrintWriter stderr = new PrintWriter(
new OutputStreamWriter(System.err, StandardCharsets.UTF_8),
true);
public static ThreadLocal<PrintWriter> stderr = new ThreadLocal<PrintWriter>() {
@Override protected PrintWriter initialValue() {
return new PrintWriter(
new OutputStreamWriter(System.err, StandardCharsets.UTF_8),
true);
}
};


/**
* Provide UTF-8 decoded standard inupt Reader
*/
public static BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in, StandardCharsets.UTF_8));
public static ThreadLocal<BufferedReader> stdin = new ThreadLocal<BufferedReader>() {
@Override protected BufferedReader initialValue() {
return new BufferedReader(
new InputStreamReader(System.in, StandardCharsets.UTF_8));
}
};

/**
* <p> Utility method used by <code>String.show</code> to quote a string. </p>
Expand Down Expand Up @@ -220,8 +235,8 @@ else if (mainres instanceof java.lang.Boolean) {
// throw new Error(ex); // ex.printStackTrace();
// }
finally {
stderr.flush();
stdout.flush();
stderr.get().flush();
stdout.get().flush();
}
return xit;
}
Expand Down
57 changes: 40 additions & 17 deletions frege/runtime/Runtime.java6
Original file line number Diff line number Diff line change
Expand Up @@ -76,27 +76,41 @@ public class Runtime {
return o.getClass();
}


public static Charset utf8 = Charset.forName("UTF-8");
private static Charset utf8 = Charset.forName("UTF-8");
/**
* Provide UTF-8 encoded standard printer for stdout with automatic line flushing
* <p>Must be thread local so that it works in the online REPL, for instance. </p>
*/
public static PrintWriter stdout = new PrintWriter(
new OutputStreamWriter(System.out, utf8),
true);
public static ThreadLocal<PrintWriter> stdout = new ThreadLocal<PrintWriter>() {
@Override protected PrintWriter initialValue() {
return new PrintWriter(
new OutputStreamWriter(System.out, utf8),
true);
}
};

/**
* Provide UTF-8 encoded standard printer for stderr with autoflush
* <p>Must be thread local so that it works in the online REPL, for instance. </p>
*/
public static PrintWriter stderr = new PrintWriter(
new OutputStreamWriter(System.err, utf8),
true);
public static ThreadLocal<PrintWriter> stderr = new ThreadLocal<PrintWriter>() {
@Override protected PrintWriter initialValue() {
return new PrintWriter(
new OutputStreamWriter(System.err, utf8),
true);
}
};


/**
* Provide UTF-8 decoded standard inupt Reader
*/
public static BufferedReader stdin = new BufferedReader(
new InputStreamReader(System.in, utf8));
public static ThreadLocal<BufferedReader> stdin = new ThreadLocal<BufferedReader>() {
@Override protected BufferedReader initialValue() {
return new BufferedReader(
new InputStreamReader(System.in, utf8));
}
};

/**
* <p> Utility method used by <code>String.show</code> to quote a string. </p>
Expand Down Expand Up @@ -199,24 +213,33 @@ public class Runtime {
* *
* <p> Called from the java <tt>main</tt> method of a frege program.
* This converts the argument String array to a list and passes this to
* the compiled frege main function. The result is an IO action of type
* <tt>IO ()</tt> to which then <tt>IO.performUnsafe</tt> is applied.
* the compiled frege main function, if it is a function.
* The result is an IO action of type
* <tt>IO a</tt> to which then <tt>IO.performUnsafe</tt> is applied.
* The resulting {@link Lambda} then actually executes the frege code
* when evaluated.</p>
*
*/
public static void runMain(final Object arg) {
public static java.lang.Integer runMain(final Object arg) {
java.lang.Integer xit = 0;
try {
Delayed.delayed(arg).call();
Object mainres = Delayed.delayed(arg).call();
mainres = Delayed.<Object>forced(mainres);
if (mainres instanceof java.lang.Integer) {
xit = (java.lang.Integer)mainres;
}
else if (mainres instanceof java.lang.Boolean) {
xit = (boolean)(java.lang.Boolean)mainres ? 0 : 1;
}
}
// catch (Exception ex) {
// throw new Error(ex); // ex.printStackTrace();
// }
finally {
stderr.flush();
stdout.flush();
stderr.get().flush();
stdout.get().flush();
}
return;
return xit;
}

final public static void exit() {
Expand Down

0 comments on commit 90df590

Please sign in to comment.