mirror of https://github.com/axmolengine/axmol.git
Merge pull request #7192 from kezhuw/bugfix_http_client
bugfix: condition variable sleep on unrelated mutex
This commit is contained in:
commit
7b1be80eb8
|
@ -47,16 +47,13 @@ namespace network {
|
||||||
static std::mutex s_requestQueueMutex;
|
static std::mutex s_requestQueueMutex;
|
||||||
static std::mutex s_responseQueueMutex;
|
static std::mutex s_responseQueueMutex;
|
||||||
|
|
||||||
static std::mutex s_SleepMutex;
|
static std::condition_variable_any s_SleepCondition;
|
||||||
static std::condition_variable s_SleepCondition;
|
|
||||||
|
|
||||||
|
|
||||||
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
|
||||||
typedef int int32_t;
|
typedef int int32_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool s_need_quit = false;
|
|
||||||
|
|
||||||
static Vector<HttpRequest*>* s_requestQueue = nullptr;
|
static Vector<HttpRequest*>* s_requestQueue = nullptr;
|
||||||
static Vector<HttpResponse*>* s_responseQueue = nullptr;
|
static Vector<HttpResponse*>* s_responseQueue = nullptr;
|
||||||
|
|
||||||
|
@ -102,41 +99,29 @@ static int processDeleteTask(HttpRequest *request, write_callback callback, void
|
||||||
// int processDownloadTask(HttpRequest *task, write_callback callback, void *stream, int32_t *errorCode);
|
// int processDownloadTask(HttpRequest *task, write_callback callback, void *stream, int32_t *errorCode);
|
||||||
static void processResponse(HttpResponse* response, char* errorBuffer);
|
static void processResponse(HttpResponse* response, char* errorBuffer);
|
||||||
|
|
||||||
|
static HttpRequest *s_requestSentinel = new HttpRequest;
|
||||||
|
|
||||||
// Worker thread
|
// Worker thread
|
||||||
void HttpClient::networkThread()
|
void HttpClient::networkThread()
|
||||||
{
|
{
|
||||||
HttpRequest *request = nullptr;
|
|
||||||
|
|
||||||
auto scheduler = Director::getInstance()->getScheduler();
|
auto scheduler = Director::getInstance()->getScheduler();
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (s_need_quit)
|
HttpRequest *request;
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// step 1: send http request if the requestQueue isn't empty
|
// step 1: send http request if the requestQueue isn't empty
|
||||||
request = nullptr;
|
|
||||||
|
|
||||||
s_requestQueueMutex.lock();
|
|
||||||
|
|
||||||
//Get request task from queue
|
|
||||||
|
|
||||||
if (!s_requestQueue->empty())
|
|
||||||
{
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||||
|
while (s_requestQueue->empty()) {
|
||||||
|
s_SleepCondition.wait(s_requestQueueMutex);
|
||||||
|
}
|
||||||
request = s_requestQueue->at(0);
|
request = s_requestQueue->at(0);
|
||||||
s_requestQueue->erase(0);
|
s_requestQueue->erase(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
s_requestQueueMutex.unlock();
|
if (request == s_requestSentinel) {
|
||||||
|
break;
|
||||||
if (nullptr == request)
|
|
||||||
{
|
|
||||||
// Wait for http request tasks from main thread
|
|
||||||
std::unique_lock<std::mutex> lk(s_SleepMutex);
|
|
||||||
s_SleepCondition.wait(lk);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// step 2: libcurl sync access
|
// step 2: libcurl sync access
|
||||||
|
@ -462,9 +447,11 @@ HttpClient::HttpClient()
|
||||||
|
|
||||||
HttpClient::~HttpClient()
|
HttpClient::~HttpClient()
|
||||||
{
|
{
|
||||||
s_need_quit = true;
|
|
||||||
|
|
||||||
if (s_requestQueue != nullptr) {
|
if (s_requestQueue != nullptr) {
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(s_requestQueueMutex);
|
||||||
|
s_requestQueue->pushBack(s_requestSentinel);
|
||||||
|
}
|
||||||
s_SleepCondition.notify_one();
|
s_SleepCondition.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,8 +468,6 @@ bool HttpClient::lazyInitThreadSemphore()
|
||||||
s_requestQueue = new (std::nothrow) Vector<HttpRequest*>();
|
s_requestQueue = new (std::nothrow) Vector<HttpRequest*>();
|
||||||
s_responseQueue = new (std::nothrow) Vector<HttpResponse*>();
|
s_responseQueue = new (std::nothrow) Vector<HttpResponse*>();
|
||||||
|
|
||||||
s_need_quit = false;
|
|
||||||
|
|
||||||
auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this));
|
auto t = std::thread(CC_CALLBACK_0(HttpClient::networkThread, this));
|
||||||
t.detach();
|
t.detach();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue