예제 #1
0
// Worker thread
static void* networkThread(void *data)
{    
    CCHttpRequest *request = 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;
        }
        
        if (need_quit)
        {
            break;
        }
        
        // step 1: send http request if the requestQueue isn't empty
        request = NULL;
        
        pthread_mutex_lock(&s_requestQueueMutex); //Get request task from queue
        if (0 != s_requestQueue->count())
        {
            request = dynamic_cast<CCHttpRequest*>(s_requestQueue->objectAtIndex(0));
            s_requestQueue->removeObjectAtIndex(0);  
            // request's refcount = 1 here
        }
        pthread_mutex_unlock(&s_requestQueueMutex);
        
        if (NULL == request)
        {
            continue;
        }
        
        // step 2: libcurl sync access
        
        // Create a HttpResponse object, the default setting is http access failed
        CCHttpResponse *response = new CCHttpResponse(request);
        
        // request's refcount = 2 here, it's retained by HttpRespose constructor
        request->release();
        // ok, refcount = 1 now, only HttpResponse hold it.
        
        int responseCode = -1;
        int retValue = 0;

        // Process the request -> get response packet
        switch (request->getRequestType())
        {
            case CCHttpRequest::kHttpGet: // HTTP GET
                retValue = processGetTask(request, 
                                          writeData, 
                                          response->getResponseData(), 
                                          &responseCode);
                break;
            
            case CCHttpRequest::kHttpPost: // HTTP POST
                retValue = processPostTask(request, 
                                           writeData, 
                                           response->getResponseData(), 
                                           &responseCode);
                break;
            
            default:
                CCAssert(true, "CCHttpClient: unkown request type, only GET and POSt are supported");
                break;
        }
                
        // write data to HttpResponse
        response->setResponseCode(responseCode);
        
        if (retValue != 0) 
        {
            response->setSucceed(false);
            response->setErrorBuffer(s_errorBuffer);
        }
        else
        {
            response->setSucceed(true);
        }

        
        // add response packet into queue
        pthread_mutex_lock(&s_responseQueueMutex);
        s_responseQueue->addObject(response);
        pthread_mutex_unlock(&s_responseQueueMutex);
        
        // resume dispatcher selector
        CCDirector::sharedDirector()->getScheduler()->resumeTarget(CCHttpClient::getInstance());
    }
    
    // cleanup: if worker thread received quit signal, clean up un-completed request queue
    pthread_mutex_lock(&s_requestQueueMutex);
    s_requestQueue->removeAllObjects();
    pthread_mutex_unlock(&s_requestQueueMutex);
    s_asyncRequestCount -= s_requestQueue->count();
    
    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);
        
        s_requestQueue->release();
        s_responseQueue->release();
    }

    pthread_exit(NULL);
    
    return 0;
}
예제 #2
0
// Worker thread
static void* networkThread(void *data)
{    
    CCHttpRequest *request = NULL;
    
    while (true) 
    {
        if (need_quit)
        {
            break;
        }
        
        // step 1: send http request if the requestQueue isn't empty
        request = NULL;
        
        pthread_mutex_lock(&s_requestQueueMutex); //Get request task from queue
        if (0 != s_requestQueue->count())
        {
            request = dynamic_cast<CCHttpRequest*>(s_requestQueue->objectAtIndex(0));
            s_requestQueue->removeObjectAtIndex(0);  
            // request's refcount = 1 here
        }
        pthread_mutex_unlock(&s_requestQueueMutex);
        
        if (NULL == request)
        {
        	// Wait for http request tasks from main thread
        	pthread_cond_wait(&s_SleepCondition, &s_SleepMutex);
            continue;
        }
        
        // step 2: libcurl sync access
        
        // Create a HttpResponse object, the default setting is http access failed
        CCHttpResponse *response = new CCHttpResponse(request);
        
        // request's refcount = 2 here, it's retained by HttpRespose constructor
        request->release();
        // ok, refcount = 1 now, only HttpResponse hold it.
        
        int32_t responseCode = -1;
        int retValue = 0;

        // Process the request -> get response packet
        switch (request->getRequestType())
        {
            case CCHttpRequest::kHttpGet: // HTTP GET
                retValue = processGetTask(request,
                                          writeData, 
                                          response->getResponseData(), 
                                          &responseCode,
                                          writeHeaderData,
                                          response->getResponseHeader());
                break;
            
            case CCHttpRequest::kHttpPost: // HTTP POST
                retValue = processPostTask(request,
                                           writeData, 
                                           response->getResponseData(), 
                                           &responseCode,
                                           writeHeaderData,
                                           response->getResponseHeader());
                break;

            case CCHttpRequest::kHttpPut:
                retValue = processPutTask(request,
                                          writeData,
                                          response->getResponseData(),
                                          &responseCode,
                                          writeHeaderData,
                                          response->getResponseHeader());
                break;

            case CCHttpRequest::kHttpDelete:
                retValue = processDeleteTask(request,
                                             writeData,
                                             response->getResponseData(),
                                             &responseCode,
                                             writeHeaderData,
                                             response->getResponseHeader());
                break;
            
            default:
                CCAssert(true, "CCHttpClient: unkown request type, only GET and POSt are supported");
                break;
        }
                
        // write data to HttpResponse
        response->setResponseCode(responseCode);
        
        if (retValue != 0) 
        {
            response->setSucceed(false);
            response->setErrorBuffer(s_errorBuffer);
        }
        else
        {
            response->setSucceed(true);
        }

        
        // add response packet into queue
        pthread_mutex_lock(&s_responseQueueMutex);
        s_responseQueue->addObject(response);
        pthread_mutex_unlock(&s_responseQueueMutex);
        
        // resume dispatcher selector
        CAScheduler::getScheduler()->resumeTarget(CCHttpClient::getInstance());
    }
    
    // cleanup: if worker thread received quit signal, clean up un-completed request queue
    pthread_mutex_lock(&s_requestQueueMutex);
    s_requestQueue->removeAllObjects();
    pthread_mutex_unlock(&s_requestQueueMutex);
    s_asyncRequestCount -= s_requestQueue->count();
    
    if (s_requestQueue != NULL) {
        
        pthread_mutex_destroy(&s_requestQueueMutex);
        pthread_mutex_destroy(&s_responseQueueMutex);
        
        pthread_mutex_destroy(&s_SleepMutex);
        pthread_cond_destroy(&s_SleepCondition);

        s_requestQueue->release();
        s_requestQueue = NULL;
        s_responseQueue->release();
        s_responseQueue = NULL;
    }

    pthread_exit(NULL);
    
    return 0;
}
예제 #3
0
// Worker thread
static KDvoid*  networkThread ( KDvoid* pData )
{    
    CCHttpRequest*  pRequest = KD_NULL;
    
    while ( 1 ) 
    {        
        if ( l_bNeedQuit )
        {
            break;
        }
        
        // step 1: send http request if the requestQueue isn't empty
        pRequest = KD_NULL;
        
		kdThreadMutexLock ( l_pRequestQueueMutex );	// Get request task from queue

        if ( 0 != l_pRequestQueue->count ( ) )
        {
            pRequest = dynamic_cast<CCHttpRequest*> ( l_pRequestQueue->objectAtIndex ( 0 ) );
            l_pRequestQueue->removeObjectAtIndex ( 0 );  
            // request's refcount = 1 here
        }
		kdThreadMutexUnlock ( l_pRequestQueueMutex );
        
        if ( KD_NULL == pRequest )
        {
			// Wait for http request tasks from main thread
        	kdThreadCondWait ( l_pSleepCondition, l_pSleepMutex );
            continue;
        }
   
        // step 2: libcurl sync access
        
        // Create a HttpResponse object, the default setting is http access failed
        CCHttpResponse*  pResponse = new CCHttpResponse ( pRequest );
        
        // request's refcount = 2 here, it's retained by HttpRespose constructor
        pRequest->release ( );
        // ok, refcount = 1 now, only HttpResponse hold it.
        
        KDint  nResponseCode = -1;
        KDint  nRetValue = 0;

        // Process the request -> get response packet
        switch ( pRequest->getRequestType ( ) )
        {
            case CCHttpRequest::kCCHttpGet :	// HTTP GET
                nRetValue = processGetTask  ( pRequest, writeData, pResponse->getResponseData ( ), &nResponseCode );
                break;
            
            case CCHttpRequest::kCCHttpPost :		// HTTP POST
                nRetValue = processPostTask ( pRequest, writeData, pResponse->getResponseData ( ), &nResponseCode );
                break;
            
            default :
                CCAssert ( KD_TRUE, "CCHttpClient: unkown request type, only GET and POSt are supported" );
                break;
        }
                  
        // write data to HttpResponse
        pResponse->setResponseCode ( nResponseCode );
        
        if ( nRetValue != 0 ) 
        {
            pResponse->setSucceed ( KD_FALSE );
            pResponse->setErrorBuffer ( l_szErrorBuffer );
        }
        else
        {
            pResponse->setSucceed ( KD_TRUE );
        }
        
        // add response packet into queue
        kdThreadMutexLock ( l_pResponseQueueMutex );
        l_pResponseQueue->addObject ( pResponse );
        kdThreadMutexUnlock ( l_pResponseQueueMutex );
        
        // resume dispatcher selector
        CCDirector::sharedDirector ( )->getScheduler ( )->resumeTarget ( CCHttpClient::getInstance ( ) );		
    }
    
    // cleanup: if worker thread received quit signal, clean up un-completed request queue
    kdThreadMutexLock ( l_pRequestQueueMutex );
    l_pRequestQueue->removeAllObjects ( );
    kdThreadMutexUnlock ( l_pRequestQueueMutex );
    l_uAsyncRequestCount -= l_pRequestQueue->count ( );
    
    if ( l_pRequestQueue != KD_NULL ) 
	{        
		kdThreadMutexFree ( l_pRequestQueueMutex );
		kdThreadMutexFree ( l_pResponseQueueMutex );
        
		kdThreadMutexFree ( l_pSleepMutex );
        kdThreadCondFree  ( l_pSleepCondition );

        l_pRequestQueue->release ( );
		l_pRequestQueue = KD_NULL;
        l_pResponseQueue->release ( );	
		l_pResponseQueue = KD_NULL;
    }

	kdThreadExit ( KD_NULL );
    
    return 0;
}