diff options
author | Andrei Karas <akaras@inbox.ru> | 2014-07-29 22:23:43 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2014-07-29 22:23:43 +0300 |
commit | d425193e392ee14695faa75d7f6d7a7fd3ea4dd2 (patch) | |
tree | 1ea51b26a10554cdfa488960798e82caeec696bb | |
parent | 3941d588a3233176416edf90d1f248ac4cb0fe5e (diff) | |
download | mv-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.cpp | 4 | ||||
-rw-r--r-- | src/net/ipc.cpp | 33 | ||||
-rw-r--r-- | src/net/ipc.h | 8 |
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; }; |