From ef6d251c30a58c407e21a4a44da09a42e0a86caa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 27 Mar 2015 15:52:22 +0100 Subject: [PATCH 1/2] Oops, that went directly into the stable branch earlier. --- src/main/scala/li/cil/oc/server/component/InternetCard.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/li/cil/oc/server/component/InternetCard.scala b/src/main/scala/li/cil/oc/server/component/InternetCard.scala index 7ae2037ce..2d7adda33 100644 --- a/src/main/scala/li/cil/oc/server/component/InternetCard.scala +++ b/src/main/scala/li/cil/oc/server/component/InternetCard.scala @@ -47,7 +47,7 @@ class InternetCard extends prefab.ManagedEnvironment { @Callback(direct = true, doc = """function():boolean -- Returns whether HTTP requests can be made (config setting).""") def isHttpEnabled(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.httpEnabled) - @Callback(doc = """function(url:string[, postData:string]):boolean -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.""") + @Callback(doc = """function(url:string[, postData:string]):userdata -- Starts an HTTP request. If this returns true, further results will be pushed using `http_response` signals.""") def request(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { checkOwner(context) val address = args.checkString(0) @@ -66,7 +66,7 @@ class InternetCard extends prefab.ManagedEnvironment { @Callback(direct = true, doc = """function():boolean -- Returns whether TCP connections can be made (config setting).""") def isTcpEnabled(context: Context, args: Arguments): Array[AnyRef] = result(Settings.get.tcpEnabled) - @Callback(doc = """function(address:string[, port:number]):number -- Opens a new TCP connection. Returns the handle of the connection.""") + @Callback(doc = """function(address:string[, port:number]):userdata -- Opens a new TCP connection. Returns the handle of the connection.""") def connect(context: Context, args: Arguments): Array[AnyRef] = this.synchronized { checkOwner(context) val address = args.checkString(0) From fa5a6f14b0f72e26704a5882a98285bedeed4da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20N=C3=BCcke?= Date: Fri, 27 Mar 2015 19:25:39 +0100 Subject: [PATCH 2/2] Might make #973 go away. --- .../assets/opencomputers/lua/machine.lua | 20 +++--- .../oc/server/component/InternetCard.scala | 63 ++++++++----------- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/main/resources/assets/opencomputers/lua/machine.lua b/src/main/resources/assets/opencomputers/lua/machine.lua index 603d5e7b5..3402c90ec 100644 --- a/src/main/resources/assets/opencomputers/lua/machine.lua +++ b/src/main/resources/assets/opencomputers/lua/machine.lua @@ -908,7 +908,7 @@ wrappedUserdataMeta = { local wrappedUserdata = setmetatable({}, wrappedUserdataMeta) local function processResult(result) - wrapUserdata(result) -- needed for metamethods. + result = wrapUserdata(result) -- needed for metamethods. if not result[1] then -- error that should be re-thrown. error(result[2], 0) else -- success or already processed error. @@ -920,8 +920,9 @@ local function invoke(target, direct, ...) local result if direct then local args = table.pack(...) -- for unwrapping - unwrapUserdata(args) + args = unwrapUserdata(args) result = table.pack(target.invoke(table.unpack(args, 1, args.n))) + args = nil -- clear upvalue, avoids trying to persist it if result.n == 0 then -- limit for direct calls reached result = nil end @@ -930,9 +931,10 @@ local function invoke(target, direct, ...) if not result then local args = table.pack(...) -- for access in closure result = select(1, coroutine.yield(function() - unwrapUserdata(args) + args = unwrapUserdata(args) local result = table.pack(target.invoke(table.unpack(args, 1, args.n))) - wrapUserdata(result) + args = nil -- clear upvalue, avoids trying to persist it + result = wrapUserdata(result) return result end)) end @@ -941,8 +943,9 @@ end local function udinvoke(f, data, ...) local args = table.pack(...) - unwrapUserdata(args) + args = unwrapUserdata(args) local result = table.pack(f(data, table.unpack(args))) + args = nil -- clear upvalue, avoids trying to persist it return processResult(result) end @@ -1035,7 +1038,7 @@ function wrapUserdata(values) end return value end - wrapRecursively(values) + return wrapRecursively(values) end function unwrapUserdata(values) @@ -1054,7 +1057,7 @@ function unwrapUserdata(values) end return value end - unwrapRecursively(values) + return unwrapRecursively(values) end ------------------------------------------------------------------------------- @@ -1343,13 +1346,14 @@ local function main() debug.sethook(co, checkDeadline, "", hookInterval) local result = table.pack(coroutine.resume(co, table.unpack(args, 1, args.n))) + args = nil -- clear upvalue, avoids trying to persist it if not result[1] then error(tostring(result[2]), 0) elseif coroutine.status(co) == "dead" then error("computer halted", 0) else args = table.pack(coroutine.yield(result[2])) -- system yielded value - wrapUserdata(args) + args = wrapUserdata(args) end end end diff --git a/src/main/scala/li/cil/oc/server/component/InternetCard.scala b/src/main/scala/li/cil/oc/server/component/InternetCard.scala index 2d7adda33..74d5d1d0e 100644 --- a/src/main/scala/li/cil/oc/server/component/InternetCard.scala +++ b/src/main/scala/li/cil/oc/server/component/InternetCard.scala @@ -1,27 +1,15 @@ package li.cil.oc.server.component -import java.io.BufferedWriter -import java.io.FileNotFoundException -import java.io.IOException -import java.io.InputStream -import java.io.OutputStreamWriter +import java.io.{BufferedWriter, FileNotFoundException, IOException, InputStream, OutputStreamWriter} import java.net._ import java.nio.ByteBuffer import java.nio.channels.SocketChannel -import java.util.concurrent.Callable -import java.util.concurrent.ConcurrentLinkedQueue -import java.util.concurrent.ExecutionException -import java.util.concurrent.Future +import java.util.concurrent.{Callable, ConcurrentLinkedQueue, ExecutionException, Future} -import li.cil.oc.OpenComputers -import li.cil.oc.Settings -import li.cil.oc.api -import li.cil.oc.api.Network -import li.cil.oc.api.machine.Arguments -import li.cil.oc.api.machine.Callback -import li.cil.oc.api.machine.Context +import li.cil.oc.{OpenComputers, Settings, api} +import li.cil.oc.api.machine.{Arguments, Callback, Context} import li.cil.oc.api.network._ -import li.cil.oc.api.prefab +import li.cil.oc.api.{Network, prefab} import li.cil.oc.api.prefab.AbstractValue import li.cil.oc.util.ExtendedNBT._ import li.cil.oc.util.ThreadPoolFactory @@ -239,28 +227,30 @@ object InternetCard { }) } - private def checkConnected() = try { + private def checkConnected() = { if (owner.isEmpty) throw new IOException("connection lost") - if (isAddressResolved) channel.finishConnect() - else if (address.isCancelled) { - // I don't think this can ever happen, Justin Case. - channel.close() - throw new IOException("bad connection descriptor") - } - else if (address.isDone) { - // Check for errors. - try address.get catch { - case e: ExecutionException => throw e.getCause + try { + if (isAddressResolved) channel.finishConnect() + else if (address.isCancelled) { + // I don't think this can ever happen, Justin Case. + channel.close() + throw new IOException("bad connection descriptor") } - isAddressResolved = true - false + else if (address.isDone) { + // Check for errors. + try address.get catch { + case e: ExecutionException => throw e.getCause + } + isAddressResolved = true + false + } + else false + } + catch { + case t: Throwable => + close() + false } - else false - } - catch { - case t: Throwable => - close() - false } // This has to be an explicit internal class instead of an anonymous one @@ -430,6 +420,7 @@ object InternetCard { throw new IOException(Option(e.getMessage).getOrElse(e.toString)) } } + } }