summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-08-24 01:07:45 +0000
committerPaul Phillips <paulp@improving.org>2009-08-24 01:07:45 +0000
commitdb8c41b53586961f10c2ba3a48ad14fa622d507f (patch)
treed3bb02c75e0e4eb3b63e6a1c97450c8e23d818c1 /src
parent0f7296a008e0e4090e69b489c23a492df26fd4f6 (diff)
downloadscala-db8c41b53586961f10c2ba3a48ad14fa622d507f.tar.gz
scala-db8c41b53586961f10c2ba3a48ad14fa622d507f.tar.bz2
scala-db8c41b53586961f10c2ba3a48ad14fa622d507f.zip
Taking a little more advantage of some recent a...
Taking a little more advantage of some recent abstractions.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala50
-rw-r--r--src/compiler/scala/tools/nsc/CompileSocket.scala48
-rw-r--r--src/compiler/scala/tools/util/SocketServer.scala77
-rw-r--r--src/library/scala/io/File.scala7
4 files changed, 96 insertions, 86 deletions
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index 010d183bc8..7cd4be214a 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -6,10 +6,9 @@
package scala.tools.nsc
-import java.io.{BufferedOutputStream, File, FileOutputStream, PrintStream}
-import java.lang.{Runtime, System, Thread}
+import java.io.{ BufferedOutputStream, FileOutputStream, PrintStream, File => JFile }
+import scala.io.File
-import scala.concurrent.ops.spawn
import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
import scala.tools.nsc.util.FakePos //Position
import scala.tools.util.SocketServer
@@ -22,7 +21,8 @@ import scala.tools.util.SocketServer
* @author Martin Odersky
* @version 1.0
*/
-class StandardCompileServer extends SocketServer {
+class StandardCompileServer extends SocketServer
+{
def compileSocket: CompileSocket = CompileSocket // todo: make this a lazy val
val versionMsg = "Fast Scala compiler " +
@@ -44,6 +44,7 @@ class StandardCompileServer extends SocketServer {
}
private val runtime = Runtime.getRuntime()
+ import runtime.{ totalMemory, freeMemory, maxMemory }
var reporter: ConsoleReporter = _
@@ -54,24 +55,31 @@ class StandardCompileServer extends SocketServer {
}
override def timeout() {
- if (!compileSocket.portFile(port).exists())
+ if (!compileSocket.portFile(port).file.exists())
fatal("port file no longer exists; skipping cleanup")
}
+ def printMemoryStats() {
+ System.out.println("New session, total memory = %s, max memory = %s, free memory = %s".format(
+ totalMemory, maxMemory, freeMemory))
+ System.out.flush()
+ }
+
+ def isMemoryFullEnough() = {
+ runtime.gc()
+ (totalMemory - freeMemory).toDouble / maxMemory.toDouble > MaxCharge
+ }
+
protected def newOfflineCompilerCommand(
arguments: List[String],
settings: Settings,
error: String => Unit,
- interactive: Boolean)
- = new OfflineCompilerCommand(arguments, settings, error, interactive)
+ interactive: Boolean
+ ) = new OfflineCompilerCommand(arguments, settings, error, interactive)
def session() {
- System.out.println("New session" +
- ", total memory = "+ runtime.totalMemory() +
- ", max memory = " + runtime.maxMemory() +
- ", free memory = " + runtime.freeMemory)
- System.out.flush()
- val password = compileSocket.getPassword(port)
+ printMemoryStats()
+ val password = compileSocket getPassword port
val guessedPassword = in.readLine()
val input = in.readLine()
if ((input ne null) && password == guessedPassword) {
@@ -127,24 +135,18 @@ class StandardCompileServer extends SocketServer {
shutDown = true
}
reporter.printSummary()
- runtime.gc()
- if ((runtime.totalMemory() - runtime.freeMemory()).toDouble /
- runtime.maxMemory().toDouble > MaxCharge) compiler = null
+ if (isMemoryFullEnough)
+ compiler = null
}
}
}
/** A directory holding redirected output */
- private val redirectDir = new File(compileSocket.tmpDir, "output-redirects")
+ private val redirectDir = File(compileSocket.tmpDir) / "output-redirects"
redirectDir.mkdirs
- private def redirect(setter: PrintStream => Unit, filename: String) {
- setter(
- new PrintStream(
- new BufferedOutputStream(
- new FileOutputStream(
- new File(redirectDir, filename)))))
- }
+ private def redirect(setter: PrintStream => Unit, filename: String): Unit =
+ setter(new PrintStream(redirectDir / filename bufferedOutput()))
def main(args: Array[String]) {
redirect(System.setOut, "scala-compile-server-out.log")
diff --git a/src/compiler/scala/tools/nsc/CompileSocket.scala b/src/compiler/scala/tools/nsc/CompileSocket.scala
index 42b91a59ad..fb4d4c50dc 100644
--- a/src/compiler/scala/tools/nsc/CompileSocket.scala
+++ b/src/compiler/scala/tools/nsc/CompileSocket.scala
@@ -6,10 +6,16 @@
package scala.tools.nsc
-import java.io.{ File, IOException, FileNotFoundException, PrintWriter, FileOutputStream }
+import java.io.{ IOException, FileNotFoundException, PrintWriter, FileOutputStream }
import java.io.{ BufferedReader, FileReader }
import java.util.regex.Pattern
import java.net._
+import java.security.SecureRandom
+
+import scala.io.File
+import scala.util.control.Exception.catching
+
+// class CompileChannel { }
/** This class manages sockets for the fsc offline compiler. */
class CompileSocket {
@@ -26,7 +32,7 @@ class CompileSocket {
protected val vmCommand = Properties.scalaHome match {
case null => cmdName
case dirname =>
- val trial = scala.io.File(dirname) / "bin" / cmdName
+ val trial = File(dirname) / "bin" / cmdName
if (trial.canRead) trial.path
else cmdName
}
@@ -53,7 +59,7 @@ class CompileSocket {
/** A temporary directory to use */
val tmpDir = {
val udir = Option(Properties.userName) getOrElse "shared"
- val f = (scala.io.File(Properties.tmpDir) / "scala-devel" / udir).file
+ val f = (File(Properties.tmpDir) / "scala-devel" / udir).file
f.mkdirs()
if (f.isDirectory && f.canWrite) {
@@ -64,7 +70,7 @@ class CompileSocket {
}
/* A directory holding port identification files */
- val portsDir = new File(tmpDir, dirName)
+ val portsDir = File(tmpDir) / dirName
portsDir.mkdirs
/** Maximum number of polls for an available port */
@@ -97,24 +103,16 @@ class CompileSocket {
}
/** The port identification file */
- def portFile(port: Int) = new File(portsDir, port.toString())
+ def portFile(port: Int) = portsDir / port.toString
/** Poll for a server port number; return -1 if none exists yet */
- private def pollPort(): Int = {
- val hits = portsDir.listFiles()
- if (hits.length == 0) -1
- else
- try {
- for (i <- 1 until hits.length) hits(i).delete()
- hits(0).getName.toInt
- } catch {
- case ex: NumberFormatException =>
- fatal(ex.toString() +
- "\nbad file in temp directory: " +
- hits(0).getAbsolutePath() +
- "\nplease remove the file and try again")
- }
- }
+ private def pollPort(): Int =
+ portsDir.iterator.toList match {
+ case Nil => -1
+ case p :: xs =>
+ xs forall (_.delete())
+ p.name.toInt
+ }
/** Get the port number to which a scala compile server is connected;
* If no server is running yet, then create one.
@@ -138,8 +136,8 @@ class CompileSocket {
/** Set the port number to which a scala compile server is connected */
def setPort(port: Int) {
- val file = scala.io.File(portFile(port))
- val secret = new java.security.SecureRandom().nextInt.toString
+ val file = portFile(port)
+ val secret = new SecureRandom().nextInt.toString
try file writeAll List(secret) catch {
case e @ (_: FileNotFoundException | _: SecurityException) =>
@@ -148,7 +146,7 @@ class CompileSocket {
}
/** Delete the port number to which a scala compile server was connected */
- def deletePort(port: Int) { portFile(port).delete() }
+ def deletePort(port: Int) = portFile(port).delete()
/** Get a socket connected to a daemon. If create is true, then
* create a new daemon if necessary. Returns null if the connection
@@ -210,8 +208,8 @@ class CompileSocket {
}
def getPassword(port: Int): String = {
- val ff = scala.io.File(portFile(port))
- val f = ff.bufferedReader()
+ val ff = portFile(port)
+ val f = ff.bufferedReader()
// allow some time for the server to start up
def check = {
diff --git a/src/compiler/scala/tools/util/SocketServer.scala b/src/compiler/scala/tools/util/SocketServer.scala
index 1a1815f02a..00180f7659 100644
--- a/src/compiler/scala/tools/util/SocketServer.scala
+++ b/src/compiler/scala/tools/util/SocketServer.scala
@@ -10,12 +10,22 @@
package scala.tools.util
-import java.lang.System
-import java.io.PrintWriter
-import java.io.BufferedOutputStream
-import java.io.{BufferedReader, InputStreamReader}
-import java.io.IOException
-import java.net.{ServerSocket, SocketException, SocketTimeoutException}
+import java.io.{ PrintWriter, BufferedOutputStream, BufferedReader, InputStreamReader, IOException }
+import java.net.{ Socket, ServerSocket, SocketException, SocketTimeoutException }
+
+object SocketServer
+{
+ // After 30 idle minutes, politely exit.
+ // Should the port file disappear, and the clients
+ // therefore unable to contact this server instance,
+ // the process will just eventually terminate by itself.
+ val IdleTimeout = 1800000
+ val BufferSize = 10240
+
+ def bufferedReader(s: Socket) = new BufferedReader(new InputStreamReader(s.getInputStream()))
+ def bufferedOutput(s: Socket) = new BufferedOutputStream(s.getOutputStream, BufferSize)
+}
+import SocketServer._
/** The abstract class <code>SocketServer</code> implements the server
* communication for the fast Scala compiler.
@@ -23,8 +33,8 @@ import java.net.{ServerSocket, SocketException, SocketTimeoutException}
* @author Martin Odersky
* @version 1.0
*/
-abstract class SocketServer {
-
+abstract class SocketServer
+{
def shutDown: Boolean
def session()
@@ -51,41 +61,38 @@ abstract class SocketServer {
val port: Int = serverSocket.getLocalPort()
+ // @todo: this is going to be a prime candidate for ARM
+ def doSession(clientSocket: Socket) = {
+ out = new PrintWriter(clientSocket.getOutputStream(), true)
+ in = bufferedReader(clientSocket)
+ val bufout = bufferedOutput(clientSocket)
+
+ scala.Console.withOut(bufout) { session() }
+
+ bufout.close()
+ out.close()
+ in.close()
+ }
+
def run() {
- try {
- // After 30 idle minutes, politely exit.
- // Should the port file disappear, and the clients
- // therefore unable to contact this server instance,
- // the process will just eventually terminate by itself.
- serverSocket.setSoTimeout(1800000)
- } catch {
- case e: SocketException =>
- fatal("Could not set timeout on port: " + port + "; exiting.")
+ def fail(s: String) = fatal(s format port)
+
+ try serverSocket setSoTimeout IdleTimeout catch {
+ case e: SocketException => fail("Could not set timeout on port: %d; exiting.")
}
+
try {
while (!shutDown) {
- val clientSocket = try {
- serverSocket.accept()
- } catch {
- case e: IOException =>
- fatal("Accept on port " + port + " failed; exiting.")
+ val clientSocket = try serverSocket.accept() catch {
+ case e: IOException => fail("Accept on port %d failed; exiting.")
}
-
- out = new PrintWriter(clientSocket.getOutputStream(), true)
- in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()))
- val bufout = new BufferedOutputStream(clientSocket.getOutputStream, 10240)
-
- scala.Console.withOut(bufout) {
- session()
- }
- bufout.close()
- out.close()
- in.close()
+ doSession(clientSocket)
clientSocket.close()
}
- } catch {
+ }
+ catch {
case e: SocketTimeoutException =>
- warn("Timeout elapsed with no requests from clients on port " + port + "; exiting")
+ warn("Timeout elapsed with no requests from clients on port %d; exiting" format port)
timeout()
}
serverSocket.close()
diff --git a/src/library/scala/io/File.scala b/src/library/scala/io/File.scala
index 98b76b24bf..f1cdb452dc 100644
--- a/src/library/scala/io/File.scala
+++ b/src/library/scala/io/File.scala
@@ -12,7 +12,7 @@ package scala.io
import java.io.{
FileInputStream, FileOutputStream, BufferedReader, BufferedWriter, InputStreamReader, OutputStreamWriter,
- BufferedInputStream, File => JFile }
+ BufferedInputStream, BufferedOutputStream, File => JFile }
import collection.Traversable
object File
@@ -56,6 +56,7 @@ import File._
*/
class File(val file: JFile)(implicit val codec: Codec = Codec.default) extends collection.Iterable[File]
{
+ def name = file.getName()
def path = file.getPath()
def absolutePath = file.getAbsolutePath()
def delete() = file.delete()
@@ -82,7 +83,7 @@ class File(val file: JFile)(implicit val codec: Codec = Codec.default) extends c
* you can map (_.toByte) if you would really prefer Bytes.
*/
def bytes(): Iterator[Int] = {
- val in = new BufferedInputStream(inputStream())
+ val in = bufferedInput()
Iterator continually in.read() takeWhile (_ != -1)
}
@@ -104,9 +105,11 @@ class File(val file: JFile)(implicit val codec: Codec = Codec.default) extends c
/** Obtains an InputStream. */
def inputStream() = new FileInputStream(file)
+ def bufferedInput() = new BufferedInputStream(inputStream())
/** Obtains a OutputStream. */
def outputStream(append: Boolean = false) = new FileOutputStream(file, append)
+ def bufferedOutput(append: Boolean = false) = new BufferedOutputStream(outputStream(append))
/** Obtains an InputStreamReader wrapped around a FileInputStream.
*/