/*! * \brief Call this function to initialize the UPnP library and start the TV * Control Point. This function creates a timer thread and provides a * callback handler to process any UPnP events that are received. * * \return TV_SUCCESS if everything went well, else TV_ERROR. */ int TvCtrlPointStart(print_string printFunctionPtr, state_update updateFunctionPtr, int combo) { ithread_t timer_thread; int rc; unsigned short port = 0; char *ip_address = NULL; SampleUtil_Initialize(printFunctionPtr); SampleUtil_RegisterUpdateFunction(updateFunctionPtr); ithread_mutex_init(&DeviceListMutex, 0); SampleUtil_Print("Initializing UPnP Sdk with\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); rc = UpnpInit(ip_address, port); if (rc != UPNP_E_SUCCESS) { SampleUtil_Print("WinCEStart: UpnpInit() Error: %d\n", rc); if (!combo) { UpnpFinish(); return TV_ERROR; } } if (!ip_address) { ip_address = UpnpGetServerIpAddress(); } if (!port) { port = UpnpGetServerPort(); } SampleUtil_Print("UPnP Initialized\n" "\tipaddress = %s port = %u\n", ip_address ? ip_address : "{NULL}", port); SampleUtil_Print("Registering Control Point\n"); rc = UpnpRegisterClient(TvCtrlPointCallbackEventHandler, &ctrlpt_handle, &ctrlpt_handle); if (rc != UPNP_E_SUCCESS) { SampleUtil_Print("Error registering CP: %d\n", rc); UpnpFinish(); return TV_ERROR; } SampleUtil_Print("Control Point Registered\n"); TvCtrlPointRefresh(); /* start a timer thread */ ithread_create(&timer_thread, NULL, TvCtrlPointTimerLoop, NULL); ithread_detach(timer_thread); return TV_SUCCESS; }
/**************************************************************************** * Function: CreateWorker * * Description: * Creates a worker thread, if the thread pool * does not already have max threads. * Internal to thread pool. * Parameters: * ThreadPool *tp * * Returns: * 0 on success, <0 on failure * EMAXTHREADS if already max threads reached * EAGAIN if system can not create thread * *****************************************************************************/ static int CreateWorker( ThreadPool *tp ) { //printf("%s, %d\n", __FUNCTION__, __LINE__); ithread_t temp; int rc = 1; int currentThreads = tp->totalThreads + 1; //printf("%s, %d\n", __FUNCTION__, __LINE__); assert( tp != NULL ); if ( tp->attr.maxThreads != INFINITE_THREADS && currentThreads > tp->attr.maxThreads ) { return EMAXTHREADS; } //printf("%s, %d\n", __FUNCTION__, __LINE__); //rc = ithread_create( &temp, NULL, WorkerThread, tp ); rc = pthread_create( &temp, NULL, WorkerThread, tp ); //printf("%s, %d, %d\n", __FUNCTION__, __LINE__, rc); //pthread_join(temp, NULL); //printf("%s, %d\n", __FUNCTION__, __LINE__); if( rc == 0 ) { rc = ithread_detach( temp ); //printf("%s, %d, totalThreads: %d, currentThreads: %d\n", __FUNCTION__, __LINE__, tp->totalThreads, currentThreads); while( tp->totalThreads < currentThreads ) { //printf("%s, %d\n", __FUNCTION__, __LINE__, tp->totalThreads, currentThreads); ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex ); } } //printf("%s, %d\n", __FUNCTION__, __LINE__); if( tp->stats.maxThreads < tp->totalThreads ) { tp->stats.maxThreads = tp->totalThreads; } //printf("%s, %d\n", __FUNCTION__, __LINE__); return rc; }
/*! * \brief Creates a worker thread, if the thread pool does not already have * max threads. * * \remark The ThreadPool object mutex must be locked prior to calling this * function. * * \internal * * \return * \li \c 0 on success, < 0 on failure. * \li \c EMAXTHREADS if already max threads reached. * \li \c EAGAIN if system can not create thread. */ static int CreateWorker( /*! A pointer to the ThreadPool object. */ ThreadPool *tp) { ithread_t temp; int rc = 0; ithread_attr_t attr; /* if a new worker is the process of starting, wait until it fully starts */ while (tp->pendingWorkerThreadStart) { ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex); } if (tp->attr.maxThreads != INFINITE_THREADS && tp->totalThreads + 1 > tp->attr.maxThreads) { return EMAXTHREADS; } ithread_attr_init(&attr); ithread_attr_setstacksize(&attr, tp->attr.stackSize); ithread_attr_setdetachstate(&attr, ITHREAD_CREATE_DETACHED); rc = ithread_create(&temp, &attr, WorkerThread, tp); ithread_attr_destroy(&attr); if (rc == 0) { rc = ithread_detach(temp); /* ithread_detach will return EINVAL if thread has been successfully detached by ithread_create */ if (rc == EINVAL) rc = 0; tp->pendingWorkerThreadStart = 1; /* wait until the new worker thread starts */ while (tp->pendingWorkerThreadStart) { ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex); } } if (tp->stats.maxThreads < tp->totalThreads) { tp->stats.maxThreads = tp->totalThreads; } return rc; }