Merge pull request #7192 from kezhuw/bugfix_http_client

bugfix: condition variable sleep on unrelated mutex
This commit is contained in:
minggo 2014-09-04 13:34:33 +08:00
commit 7b1be80eb8
1 changed files with 19 additions and 34 deletions

View File

@ -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();
} }