summaryrefslogtreecommitdiff
path: root/library/RemoteServer.cpp
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-03-18 11:04:15 +0400
committerAlexander Gavrilov2012-03-18 11:04:15 +0400
commitb9ecd03fe2c4013a57f30ada6534a248b27b7515 (patch)
treefe42dc901accb7cdea3319d9f3b1de5da46943c4 /library/RemoteServer.cpp
parent293eb53677ebcb5fb5db83b6a3df99ba635fe6af (diff)
downloaddfhack-b9ecd03fe2c4013a57f30ada6534a248b27b7515.tar.gz
dfhack-b9ecd03fe2c4013a57f30ada6534a248b27b7515.tar.bz2
dfhack-b9ecd03fe2c4013a57f30ada6534a248b27b7515.tar.xz
Make the server suspend the core around calls unless disabled.
I expect the majority of methods will have to suspend the core first thing anyway, so this will reduce typing and bugs. Also get rid of the "me->" ugliness by splitting threadFn.
Diffstat (limited to 'library/RemoteServer.cpp')
-rw-r--r--library/RemoteServer.cpp50
1 files changed, 31 insertions, 19 deletions
diff --git a/library/RemoteServer.cpp b/library/RemoteServer.cpp
index e12b8b04..ed47890f 100644
--- a/library/RemoteServer.cpp
+++ b/library/RemoteServer.cpp
@@ -198,6 +198,14 @@ void ServerConnection::connection_ostream::flush_proxy()
void ServerConnection::threadFn(void *arg)
{
ServerConnection *me = (ServerConnection*)arg;
+
+ me->threadFn();
+
+ delete me;
+}
+
+void ServerConnection::threadFn()
+{
color_ostream_proxy out(Core::getInstance().getConsole());
/* Handshake */
@@ -205,10 +213,9 @@ void ServerConnection::threadFn(void *arg)
{
RPCHandshakeHeader header;
- if (!readFullBuffer(me->socket, &header, sizeof(header)))
+ if (!readFullBuffer(socket, &header, sizeof(header)))
{
out << "In RPC server: could not read handshake header." << endl;
- delete me;
return;
}
@@ -216,17 +223,15 @@ void ServerConnection::threadFn(void *arg)
header.version != 1)
{
out << "In RPC server: invalid handshake header." << endl;
- delete me;
return;
}
memcpy(header.magic, RPCHandshakeHeader::RESPONSE_MAGIC, sizeof(header.magic));
header.version = 1;
- if (me->socket->Send((uint8*)&header, sizeof(header)) != sizeof(header))
+ if (socket->Send((uint8*)&header, sizeof(header)) != sizeof(header))
{
out << "In RPC server: could not send handshake response." << endl;
- delete me;
return;
}
}
@@ -235,11 +240,11 @@ void ServerConnection::threadFn(void *arg)
std::cerr << "Client connection established." << endl;
- while (!me->in_error) {
+ while (!in_error) {
// Read the message
RPCMessageHeader header;
- if (!readFullBuffer(me->socket, &header, sizeof(header)))
+ if (!readFullBuffer(socket, &header, sizeof(header)))
{
out.printerr("In RPC server: I/O error in receive header.\n");
break;
@@ -256,7 +261,7 @@ void ServerConnection::threadFn(void *arg)
std::auto_ptr<uint8_t> buf(new uint8_t[header.size]);
- if (!readFullBuffer(me->socket, buf.get(), header.size))
+ if (!readFullBuffer(socket, buf.get(), header.size))
{
out.printerr("In RPC server: I/O error in receive %d bytes of data.\n", header.size);
break;
@@ -267,31 +272,40 @@ void ServerConnection::threadFn(void *arg)
// Find and call the function
int in_size = header.size;
- ServerFunctionBase *fn = vector_get(me->functions, header.id);
+ ServerFunctionBase *fn = vector_get(functions, header.id);
MessageLite *reply = NULL;
command_result res = CR_FAILURE;
if (!fn)
{
- me->stream.printerr("RPC call of invalid id %d\n", header.id);
+ stream.printerr("RPC call of invalid id %d\n", header.id);
}
else
{
if (!fn->in()->ParseFromArray(buf.get(), header.size))
{
- me->stream.printerr("In call to %s: could not decode input args.\n", fn->name);
+ stream.printerr("In call to %s: could not decode input args.\n", fn->name);
}
else
{
buf.reset();
reply = fn->out();
- res = fn->execute(me->stream);
+
+ if (fn->flags & SF_DONT_SUSPEND)
+ {
+ res = fn->execute(stream);
+ }
+ else
+ {
+ CoreSuspender suspend;
+ res = fn->execute(stream);
+ }
}
}
// Flush all text output
- if (me->in_error)
+ if (in_error)
break;
//out.print("Answer %d:%d\n", res, reply);
@@ -301,16 +315,16 @@ void ServerConnection::threadFn(void *arg)
if (out_size > RPCMessageHeader::MAX_MESSAGE_SIZE)
{
- me->stream.printerr("In call to %s: reply too large: %d.\n",
+ stream.printerr("In call to %s: reply too large: %d.\n",
(fn ? fn->name : "UNKNOWN"), out_size);
res = CR_LINK_FAILURE;
}
- me->stream.flush();
+ stream.flush();
if (res == CR_OK && reply)
{
- if (!sendRemoteMessage(me->socket, RPC_REPLY_RESULT, reply, true))
+ if (!sendRemoteMessage(socket, RPC_REPLY_RESULT, reply, true))
{
out.printerr("In RPC server: I/O error in send result.\n");
break;
@@ -321,7 +335,7 @@ void ServerConnection::threadFn(void *arg)
header.id = RPC_REPLY_FAIL;
header.size = res;
- if (me->socket->Send((uint8_t*)&header, sizeof(header)) != sizeof(header))
+ if (socket->Send((uint8_t*)&header, sizeof(header)) != sizeof(header))
{
out.printerr("In RPC server: I/O error in send failure code.\n");
break;
@@ -337,8 +351,6 @@ void ServerConnection::threadFn(void *arg)
}
std::cerr << "Shutting down client connection." << endl;
-
- delete me;
}
ServerMain::ServerMain()