summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-07-29 22:23:43 +0300
committerAndrei Karas <akaras@inbox.ru>2014-07-29 22:23:43 +0300
commitd425193e392ee14695faa75d7f6d7a7fd3ea4dd2 (patch)
tree1ea51b26a10554cdfa488960798e82caeec696bb
parent3941d588a3233176416edf90d1f248ac4cb0fe5e (diff)
downloadmv-d425193e392ee14695faa75d7f6d7a7fd3ea4dd2.tar.gz
mv-d425193e392ee14695faa75d7f6d7a7fd3ea4dd2.tar.bz2
mv-d425193e392ee14695faa75d7f6d7a7fd3ea4dd2.tar.xz
mv-d425193e392ee14695faa75d7f6d7a7fd3ea4dd2.zip
Use thread safe way for ipc interaction.
-rw-r--r--src/gui/gui.cpp4
-rw-r--r--src/net/ipc.cpp33
-rw-r--r--src/net/ipc.h8
3 files changed, 42 insertions, 3 deletions
diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp
index 779bec99c..7ac1273bd 100644
--- a/src/gui/gui.cpp
+++ b/src/gui/gui.cpp
@@ -100,6 +100,8 @@
#include "utils/langs.h"
#include "utils/timer.h"
+#include "net/ipc.h"
+
#include "debug.h"
// Guichan stuff
@@ -347,6 +349,8 @@ void Gui::slowLogic()
if (mTime != time)
{
logger->flush();
+ if (ipc)
+ ipc->flush();
mTime = time;
}
diff --git a/src/net/ipc.cpp b/src/net/ipc.cpp
index 629a069f5..22fbb4ce4 100644
--- a/src/net/ipc.cpp
+++ b/src/net/ipc.cpp
@@ -37,8 +37,11 @@ IPC *ipc = nullptr;
IPC::IPC() :
mNumReqs(0),
mSocket(nullptr),
+ mDelayedCommands(),
mThread(nullptr),
+ mMutex(SDL_CreateMutex()),
mPort(44007U),
+ mThreadLocked(false),
mListen(false)
{
}
@@ -51,6 +54,8 @@ IPC::~IPC()
TcpNet::closeSocket(mSocket);
mSocket = nullptr;
}
+ SDL_DestroyMutex(mMutex);
+ mMutex = nullptr;
int status;
if (mThread && SDL_GetThreadID(mThread))
SDL_WaitThread(mThread, &status);
@@ -115,10 +120,14 @@ int IPC::acceptLoop(void *ptr)
}
std::string req(data);
- req = trim(req);
+ trim(req);
+
+ ipc1->mThreadLocked = true;
+ SDL_mutexP(ipc1->mMutex);
+ ipc1->mDelayedCommands.push_back(req);
+ SDL_mutexV(ipc1->mMutex);
+ ipc1->mThreadLocked = false;
- if (chatWindow)
- chatWindow->chatInput(req);
ipc1->mNumReqs ++;
const std::string resp = strprintf("[%d] %s\n",
ipc1->mNumReqs, req.c_str());
@@ -176,3 +185,21 @@ void IPC::start()
}
delete2(ipc);
}
+
+void IPC::flush()
+{
+ if (!mThreadLocked)
+ {
+ SDL_mutexP(mMutex);
+ if (chatWindow)
+ {
+ FOR_EACH (std::vector<std::string>::const_iterator, it,
+ mDelayedCommands)
+ {
+ chatWindow->chatInput(*it);
+ }
+ }
+ mDelayedCommands.clear();
+ SDL_mutexV(mMutex);
+ }
+}
diff --git a/src/net/ipc.h b/src/net/ipc.h
index eb2e92c9b..739eb746e 100644
--- a/src/net/ipc.h
+++ b/src/net/ipc.h
@@ -23,6 +23,9 @@
#include "net/sdltcpnet.h"
+#include <string>
+#include <vector>
+
#include <SDL_thread.h>
class IPC final
@@ -45,6 +48,8 @@ class IPC final
unsigned short getPort() const A_WARN_UNUSED
{ return mPort; }
+ void flush();
+
static int acceptLoop(void *ptr);
static void start();
@@ -57,8 +62,11 @@ class IPC final
unsigned int mNumReqs;
TcpNet::Socket mSocket;
+ std::vector<std::string> mDelayedCommands;
SDL_Thread *mThread;
+ SDL_mutex *mMutex;
unsigned short mPort;
+ volatile bool mThreadLocked;
bool mListen;
};