示例#1
0
//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;
}