//Worker thread static void *requestThread(void *data) { data; CCThread thread; thread.createAutoreleasePool(); HttpRequestPacket *req = NULL; while (true) { //Wait for http request tasks from main thread int semWaitRet = sem_wait(s_pSem); if (semWaitRet < 0) { CCLog("HttpRequest async thread semaphore error: %s\n", strerror(errno)); break; } std::queue<HttpRequestPacket *> *pQueue = s_requestQueue; pthread_mutex_lock(&s_requestQueueMutex); //Get request task from queue if (pQueue->empty()) { pthread_mutex_unlock(&s_requestQueueMutex); if (need_quit) { break; } else { continue; } } else { if (need_quit) { pthread_mutex_unlock(&s_requestQueueMutex); break; } req = pQueue->front(); pQueue->pop(); pthread_mutex_unlock(&s_requestQueueMutex); } //Create a response packet and assume it will successed HttpResponsePacket *responsePacket = new HttpResponsePacket(); responsePacket->request = req; responsePacket->succeed = true; //Process the request if (req->reqType == kHttpRequestGet) { //Get Request int32_t ret = processGetTask(req, writeData, &responsePacket->responseData, &responsePacket->responseCode); if (ret != 0) { responsePacket->succeed = false; responsePacket->responseData = errorBuffer; } } else if (req->reqType == kHttpRequestPost) { //Post Request int32_t ret = processPostTask(req, writeData, &responsePacket->responseData, &responsePacket->responseCode); if (ret != 0) { responsePacket->succeed = false; responsePacket->responseData = errorBuffer; } } else if (req->reqType == kHttpRequestDownloadFile) { //Download File Request bool fullyDownloaded = true; std::vector<std::string>::iterator iter; std::string saveFileName; std::string needDownload; for (iter = req->files.begin(); iter != req->files.end(); ++iter) { needDownload = *iter; std::string::size_type pos = needDownload.rfind("/"); if (pos != std::string::npos) { saveFileName = needDownload.substr(pos + 1); } else { saveFileName = needDownload; } //If the download url is http://www.xxx.com/yyy.html //The saved file name must be yyy.html saveFileName = CCFileUtils::sharedFileUtils()->getWriteablePath() + saveFileName; CCLog(CCFileUtils::sharedFileUtils()->getWriteablePath().c_str()); FILE *handle = fopen(saveFileName.c_str(), "w+b"); CCLog("open file for download"); CCLog(saveFileName.c_str()); if (!handle) { fullyDownloaded = false; break; } CCLog("success"); req->url = needDownload; int32_t ret = processDownloadTask(req, writeFile, handle, &responsePacket->responseCode); if (handle) { fclose(handle); } if (ret != 0) { fullyDownloaded = false; break; } } //Only consider download task successfully when all the files downloaded if (!fullyDownloaded) { responsePacket->succeed = false; responsePacket->responseData = errorBuffer; } } pthread_mutex_lock(&s_responseQueueMutex); s_responseQueue->push(responsePacket); pthread_mutex_unlock(&s_responseQueueMutex); } //If worker thread received quit signal, clean up un-completed request queue releaseRequestQueue(); if (s_pSem != NULL) { #if CC_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE sem_unlink(CC_ASYNC_HTTPREQUEST_SEMAPHORE); sem_close(s_pSem); #else sem_destroy(s_pSem); #endif s_pSem = NULL; pthread_mutex_destroy(&s_requestQueueMutex); pthread_mutex_destroy(&s_responseQueueMutex); delete s_requestQueue; delete s_responseQueue; } pthread_exit(NULL); return 0; }
//Worker thread static void *requestThread(void *data) { CCThread thread; thread.createAutoreleasePool(); HttpRequestPacket *req = NULL; while (true) { int semWaitRet = sem_wait(s_pSem); if (semWaitRet < 0) { CCLog("HttpRequest async thread semaphore error: %s\n", strerror(errno)); break; } std::queue<HttpRequestPacket *> *pQueue = s_requestQueue; pthread_mutex_lock(&s_requestQueueMutex); if (pQueue->empty()) { pthread_mutex_unlock(&s_requestQueueMutex); if (need_quit) { break; } else { continue; } } else { if (need_quit) { pthread_mutex_unlock(&s_requestQueueMutex); break; } req = pQueue->front(); pQueue->pop(); pthread_mutex_unlock(&s_requestQueueMutex); } HttpResponsePacket *responsePacket = new HttpResponsePacket(); responsePacket->request = req; responsePacket->succeed = true; //Process the request if (req->reqType == kHttpRequestGet) { int32_t ret = processGetTask(req, writeData, &responsePacket->responseData, &responsePacket->responseCode); if (ret != 0) { responsePacket->succeed = false; responsePacket->responseData = errorBuffer; } } else if (req->reqType == kHttpRequestPost) { int32_t ret = processPostTask(req, writeData, &responsePacket->responseData, &responsePacket->responseCode); if (ret != 0) { responsePacket->succeed = false; responsePacket->responseData = errorBuffer; } } else if (req->reqType == kHttpRequestDownloadFile) { bool fullyDownloaded = true; std::vector<std::string>::iterator iter; std::string saveFileName; std::string needDownload; for (iter = req->files.begin(); iter != req->files.end(); ++iter) { needDownload = *iter; std::string::size_type pos = needDownload.rfind("/"); if (pos != std::string::npos) { saveFileName = needDownload.substr(pos + 1); } else { saveFileName = needDownload; } saveFileName = CCFileUtils::sharedFileUtils()->getWriteablePath() + saveFileName; FILE *handle = fopen(saveFileName.c_str(), "w+"); if (!handle) { fullyDownloaded = false; break; } req->url = needDownload; int32_t ret = processDownloadTask(req, writeFile, handle, &responsePacket->responseCode); if (handle) { fclose(handle); } if (ret != 0) { fullyDownloaded = false; break; } } if (!fullyDownloaded) { responsePacket->succeed = false; responsePacket->responseData = errorBuffer; } } pthread_mutex_lock(&s_responseQueueMutex); s_responseQueue->push(responsePacket); pthread_mutex_unlock(&s_responseQueueMutex); } releaseRequestQueue(); if (s_pSem != NULL) { #if CC_ASYNC_HTTPREQUEST_USE_NAMED_SEMAPHORE sem_unlink(CC_ASYNC_HTTPREQUEST_SEMAPHORE); sem_close(s_pSem); #else sem_destroy(s_pSem); #endif s_pSem = NULL; pthread_mutex_destroy(&s_requestQueueMutex); pthread_mutex_destroy(&s_responseQueueMutex); delete s_requestQueue; delete s_responseQueue; } pthread_exit(NULL); return 0; }