Пример #1
0
/********************************************************************************
 * upnp_igd_stop
 *
 * Description:
 *       Stop uPnP IGD context.
 *
 * Parameters:
 *   igd_ctxt -- The upnp igd context
 *
 ********************************************************************************/
int upnp_igd_stop(upnp_igd_context *igd_ctxt) {
	ithread_mutex_lock(&igd_ctxt->mutex);
	
	if(igd_ctxt->upnp_handle == -1) {
		upnp_igd_print(igd_ctxt, UPNP_IGD_WARNING, "uPnP IGD client already stopped...");
		ithread_mutex_unlock(&igd_ctxt->mutex);
		return -1;
	}

	ithread_mutex_lock(&igd_ctxt->timer_mutex);
	ithread_cond_signal(&igd_ctxt->timer_cond);
	ithread_mutex_unlock(&igd_ctxt->timer_mutex);
	ithread_join(igd_ctxt->timer_thread, NULL);

	upnp_igd_remove_all(igd_ctxt);

	UpnpUnRegisterClient(igd_ctxt->upnp_handle);
	
	// Wait that all clients are finish the callback
	// Doing UpnpUnRegisterClient no more callbacks are bone
	// But current running clients are still here
	ithread_mutex_lock(&igd_ctxt->client_mutex);
	while(igd_ctxt->client_count > 0) {	
		ithread_cond_wait(&igd_ctxt->client_cond, &igd_ctxt->client_mutex);	
	}
	ithread_mutex_unlock(&igd_ctxt->client_mutex);
		
	igd_ctxt->upnp_handle = -1;
	
	ithread_mutex_unlock(&igd_ctxt->mutex);

	// Handle remaining callbacks	
	upnp_context_handle_callbacks(igd_ctxt);
	return 0;
}
Пример #2
0
static const char *web_CameraConnectedMobile(void *data, const char *query)
{
	ithread_mutex_lock(&state_mutex);
	camera_responded = 1;
	ithread_cond_signal(&state_cond);
	ithread_mutex_unlock(&state_mutex);
	return xml_CameraConnectedMobile;
}
Пример #3
0
void upnp_context_remove_client(upnp_igd_context *igd_ctxt) {
	ithread_mutex_lock(&igd_ctxt->client_mutex);
	igd_ctxt->client_count--;
	if(igd_ctxt->client_count == 0) {
		ithread_cond_signal(&igd_ctxt->client_cond);
	}
	ithread_mutex_unlock(&igd_ctxt->client_mutex);
}
Пример #4
0
/****************************************************************************
 * Function: ThreadPoolAddPersistent
 *
 *  Description:
 *      Adds a long term job to the thread pool.
 *      Job will be run as soon as possible.
 *      Call will block until job is scheduled.
 *  Parameters:
 *      tp - valid thread pool pointer
 *      job-> valid ThreadPoolJob pointer with following fields
 *          func - ThreadFunction to run
 *          arg - argument to function.
 *          priority - priority of job.
 *          free_function - function to use when freeing argument
 *  Returns:
 *      0 on success, nonzero on failure
 *      EOUTOFMEM not enough memory to add job.
 *      EMAXTHREADS not enough threads to add persistent job.
 *****************************************************************************/
int ThreadPoolAddPersistent( ThreadPool *tp, ThreadPoolJob *job, int *jobId )
{
	int tempId = -1;
	ThreadPoolJob *temp = NULL;

	assert( tp != NULL );
	assert( job != NULL );
	if( ( tp == NULL ) || ( job == NULL ) ) {
		return EINVAL;
	}

	if( jobId == NULL ) {
		jobId = &tempId;
	}

	*jobId = INVALID_JOB_ID;

	ithread_mutex_lock( &tp->mutex );

	assert( job->priority == LOW_PRIORITY ||
	        job->priority == MED_PRIORITY ||
	        job->priority == HIGH_PRIORITY );

	// Create A worker if less than max threads running
	if( tp->totalThreads < tp->attr.maxThreads ) {
		CreateWorker( tp );
	} else {
		// if there is more than one worker thread
		// available then schedule job, otherwise fail
		if( tp->totalThreads - tp->persistentThreads - 1 == 0 ) {
			ithread_mutex_unlock( &tp->mutex );
			return EMAXTHREADS;
		}
	}

	temp = CreateThreadPoolJob( job, tp->lastJobId, tp );
	if( temp == NULL ) {
		ithread_mutex_unlock( &tp->mutex );
		return EOUTOFMEM;
	}

	tp->persistentJob = temp;

	// Notify a waiting thread
	ithread_cond_signal( &tp->condition );

	// wait until long job has been picked up
	while( tp->persistentJob != NULL ) {
		ithread_cond_wait( &tp->start_and_shutdown, &tp->mutex );
	}

	*jobId = tp->lastJobId++;
	ithread_mutex_unlock( &tp->mutex );

	return 0;
}
Пример #5
0
static int upnp_client_event_handler(Upnp_EventType type, void *event,
		void *cookie)
{
	struct Upnp_Discovery *devent = event;

	/* ignore devices other than the camera */
	switch (type) {
	case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
	case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
	case UPNP_DISCOVERY_SEARCH_RESULT:
		if (strcmp(devent->ServiceType, CAMERA_SERVICE_NAME) != 0)
			return 0;
		break;
	default:
		;
	}

	switch (type) {
	case UPNP_DISCOVERY_SEARCH_TIMEOUT:
		ithread_mutex_lock(&state_mutex);
		discovery_timeout = 1;
		ithread_cond_signal(&state_cond);
		ithread_mutex_unlock(&state_mutex);
		break;
	case UPNP_DISCOVERY_ADVERTISEMENT_ALIVE:
	case UPNP_DISCOVERY_SEARCH_RESULT:
		printf("discovery event: %d\n", type);
		ithread_mutex_lock(&state_mutex);
		if (strcmp_null(camera_url, devent->Location) != 0) {
			free(camera_url);
			camera_url = strdup(devent->Location);
			ithread_cond_signal(&state_cond);
		}
		ithread_mutex_unlock(&state_mutex);
		break;
	case UPNP_DISCOVERY_ADVERTISEMENT_BYEBYE:
		fprintf(stderr, "FIXME: camera disconnected\n");
		break;
	default:
		fprintf(stderr, "unhandled client event: %d, %p, %p\n", type, event, cookie);
	}
	return 0;
}
Пример #6
0
int ThreadPoolAdd(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
{
	int rc = EOUTOFMEM;
	int tempId = -1;
	long totalJobs;
	ThreadPoolJob *temp = NULL;

	if (!tp || !job)
		return EINVAL;

	ithread_mutex_lock(&tp->mutex);

	totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
	if (totalJobs >= tp->attr.maxJobsTotal) {
		fprintf(stderr, "total jobs = %ld, too many jobs", totalJobs);
		goto exit_function;
	}
	if (!jobId)
		jobId = &tempId;
	*jobId = INVALID_JOB_ID;
	temp = CreateThreadPoolJob(job, tp->lastJobId, tp);
	if (!temp)
		goto exit_function;
	switch (job->priority) {
	case HIGH_PRIORITY:
		if (ListAddTail(&tp->highJobQ, temp))
			rc = 0;
		break;
	case MED_PRIORITY:
		if (ListAddTail(&tp->medJobQ, temp))
			rc = 0;
		break;
	default:
		if (ListAddTail(&tp->lowJobQ, temp))
			rc = 0;
	}
	/* AddWorker if appropriate */
	AddWorker(tp);
	/* Notify a waiting thread */
	if (rc == 0)
		ithread_cond_signal(&tp->condition);
	else
		FreeThreadPoolJob(tp, temp);
	*jobId = tp->lastJobId++;

exit_function:
	ithread_mutex_unlock(&tp->mutex);

	return rc;
}
Пример #7
0
int ThreadPoolAddPersistent(ThreadPool *tp, ThreadPoolJob *job, int *jobId)
{
	int ret = 0;
	int tempId = -1;
	ThreadPoolJob *temp = NULL;

	if (!tp || !job) {
		return EINVAL;
	}
	if (!jobId) {
		jobId = &tempId;
	}
	*jobId = INVALID_JOB_ID;

	ithread_mutex_lock(&tp->mutex);

	/* Create A worker if less than max threads running */
	if (tp->totalThreads < tp->attr.maxThreads) {
		CreateWorker(tp);
	} else {
		/* if there is more than one worker thread
		 * available then schedule job, otherwise fail */
		if (tp->totalThreads - tp->persistentThreads - 1 == 0) {
			ret = EMAXTHREADS;
			goto exit_function;
		}
	}
	temp = CreateThreadPoolJob(job, tp->lastJobId, tp);
	if (!temp) {
		ret = EOUTOFMEM;
		goto exit_function;
	}
	tp->persistentJob = temp;

	/* Notify a waiting thread */
	ithread_cond_signal(&tp->condition);

	/* wait until long job has been picked up */
	while (tp->persistentJob)
		ithread_cond_wait(&tp->start_and_shutdown, &tp->mutex);
	*jobId = tp->lastJobId++;

exit_function:
	ithread_mutex_unlock(&tp->mutex);

	return ret;
}
Пример #8
0
/****************************************************************************
 * Function: ThreadPoolSetAttr
 *
 *  Description:
 *      Sets the attributes for the thread pool.
 *      Only affects future calculations.
 *  Parameters:
 *      tp - valid thread pool pointer
 *      attr - pointer to attributes, null sets attributes to default.
 *  Returns:
 *      0 on success, nonzero on failure
 *      Returns INVALID_POLICY if policy can not be set.
 *****************************************************************************/
int ThreadPoolSetAttr( ThreadPool *tp, ThreadPoolAttr *attr )
{
	int retCode = 0;
	ThreadPoolAttr temp;
	int i = 0;

	assert( tp != NULL );
	if( tp == NULL ) {
		return EINVAL;
	}
	ithread_mutex_lock( &tp->mutex );

	if( attr != NULL ) {
		temp = ( *attr );
	} else {
		TPAttrInit( &temp );
	}

	if( SetPolicyType( temp.schedPolicy ) != 0 ) {
		ithread_mutex_unlock( &tp->mutex );

		return INVALID_POLICY;
	}

	tp->attr = ( temp );

	// add threads
	if( tp->totalThreads < tp->attr.minThreads )
	{
		for( i = tp->totalThreads; i < tp->attr.minThreads; i++ ) {
			if( ( retCode = CreateWorker( tp ) ) != 0 ) {
				break;
			}
		}
	}

	// signal changes 
	ithread_cond_signal( &tp->condition ); 
	ithread_mutex_unlock( &tp->mutex );

	if( retCode != 0 ) {
		// clean up if the min threads could not be created
		ThreadPoolShutdown( tp );
	}

	return retCode;
}
Пример #9
0
int ThreadPoolSetAttr(ThreadPool *tp, ThreadPoolAttr *attr)
{
	int retCode = 0;
	ThreadPoolAttr temp;
	int i = 0;

	if (!tp)
		return EINVAL;

	ithread_mutex_lock(&tp->mutex);

	if (attr)
		temp = *attr;
	else
		TPAttrInit(&temp);
	if (SetPolicyType(temp.schedPolicy) != 0) {
		ithread_mutex_unlock(&tp->mutex);
		return INVALID_POLICY;
	}
	tp->attr = temp;
	/* add threads */
	if (tp->totalThreads < tp->attr.minThreads) {
		for (i = tp->totalThreads; i < tp->attr.minThreads; i++) {
			retCode = CreateWorker(tp);
			if (retCode != 0) {
				break;
			}
		}
	}
	/* signal changes */
	ithread_cond_signal(&tp->condition); 

	ithread_mutex_unlock(&tp->mutex);

	if (retCode != 0)
		/* clean up if the min threads could not be created */
		ThreadPoolShutdown(tp);

	return retCode;
}
Пример #10
0
/****************************************************************************
 * Function: TimerThreadWorker
 *
 *  Description:
 *      Implements timer thread.
 *      Waits for next event to occur and schedules
 *      associated job into threadpool.
 *      Internal Only.
 *  Parameters:
 *      void * arg -> is cast to TimerThread *
 *****************************************************************************/
static void *
TimerThreadWorker( void *arg )
{
    TimerThread *timer = ( TimerThread * ) arg;
    ListNode *head = NULL;

    TimerEvent *nextEvent = NULL;

    time_t currentTime = 0;
    time_t nextEventTime = 0;
    struct timespec timeToWait;

    int tempId;

    assert( timer != NULL );

    ithread_mutex_lock( &timer->mutex );

    while( 1 )
    {

        //mutex should always be locked at top of loop

        //Check for shutdown

        if( timer->shutdown )
        {

            timer->shutdown = 0;
            ithread_cond_signal( &timer->condition );
            ithread_mutex_unlock( &timer->mutex );
            return NULL;

        }

        nextEvent = NULL;

        //Get the next event if possible
        if( timer->eventQ.size > 0 )
        {
            head = ListHead( &timer->eventQ );

            nextEvent = ( TimerEvent * ) head->item;
            nextEventTime = nextEvent->eventTime;
        }

        currentTime = time( NULL );

        //If time has elapsed, schedule job

        if( ( nextEvent != NULL ) && ( currentTime >= nextEventTime ) )
        {

            if( nextEvent->persistent ) {

                ThreadPoolAddPersistent( timer->tp, &nextEvent->job,
                                         &tempId );
            } else {

                ThreadPoolAdd( timer->tp, &nextEvent->job, &tempId );
            }

            ListDelNode( &timer->eventQ, head, 0 );
            FreeTimerEvent( timer, nextEvent );

            continue;

        }

        if( nextEvent != NULL ) {
            timeToWait.tv_nsec = 0;
            timeToWait.tv_sec = nextEvent->eventTime;

            ithread_cond_timedwait( &timer->condition, &timer->mutex,
                                    &timeToWait );

        } else {
            ithread_cond_wait( &timer->condition, &timer->mutex );
        }

    }
}
Пример #11
0
/************************************************************************
 * Function: TimerThreadSchedule
 * 
 *  Description:
 *     Schedules an event to run at a specified time.
 *
 *  Parameters:
 *             timer - valid timer thread pointer.
 *             time_t - time of event.
 *                      either in absolute seconds,
 *                      or relative seconds in the future.
 *             timeoutType - either ABS_SEC, or REL_SEC.
 *                           if REL_SEC, then the event
 *                           will be scheduled at the
 *                           current time + REL_SEC.
 *             
 *             func - function to schedule
 *             arg - argument to function
 *             priority - priority of job.
 *             id - id of timer event. (out)
 *  Return:
 *            0 on success, nonzero on failure
 *			  EOUTOFMEM if not enough memory to schedule job
 ************************************************************************/
int
TimerThreadSchedule( TimerThread * timer,
                     time_t timeout,
                     TimeoutType type,
                     ThreadPoolJob * job,
                     Duration duration,
                     int *id )
{

    int rc = EOUTOFMEM;
    int found = 0;
    int tempId = 0;

    ListNode *tempNode = NULL;
    TimerEvent *temp = NULL;
    TimerEvent *newEvent = NULL;

    assert( timer != NULL );
    assert( job != NULL );

    if( ( timer == NULL ) || ( job == NULL ) ) {
        return EINVAL;
    }

    CalculateEventTime( &timeout, type );
    ithread_mutex_lock( &timer->mutex );

    if( id == NULL )
        id = &tempId;

    ( *id ) = INVALID_EVENT_ID;

    newEvent = CreateTimerEvent( timer, job, duration, timeout,
                                 timer->lastEventId );

    if( newEvent == NULL ) {
        ithread_mutex_unlock( &timer->mutex );
        return rc;
    }

    tempNode = ListHead( &timer->eventQ );
    //add job to Q
    //Q is ordered by eventTime
    //with the head of the Q being the next event

    while( tempNode != NULL ) {
        temp = ( TimerEvent * ) tempNode->item;
        if( temp->eventTime >= timeout )
        {

            if( ListAddBefore( &timer->eventQ, newEvent, tempNode ) !=
                NULL )
                rc = 0;
            found = 1;
            break;

        }
        tempNode = ListNext( &timer->eventQ, tempNode );
    }

    //add to the end of Q
    if( !found ) {

        if( ListAddTail( &timer->eventQ, newEvent ) != NULL )
            rc = 0;

    }
    //signal change in Q
    if( rc == 0 ) {

        ithread_cond_signal( &timer->condition );
    } else {
        FreeTimerEvent( timer, newEvent );
    }
    ( *id ) = timer->lastEventId++;
    ithread_mutex_unlock( &timer->mutex );

    return rc;
}
Пример #12
0
/****************************************************************************
 * Function: ThreadPoolAdd
 *
 *  Description:
 *      Adds a job to the thread pool.
 *      Job will be run as soon as possible.
 *  Parameters:
 *      tp - valid thread pool pointer
 *      func - ThreadFunction to run
 *      arg - argument to function.
 *      priority - priority of job.
 *      jobId - id of job
 *      duration - whether or not this is a persistent thread
 *      free_function - function to use when freeing argument
 *  Returns:
 *      0 on success, nonzero on failure
 *      EOUTOFMEM if not enough memory to add job.
 *****************************************************************************/
int ThreadPoolAdd( ThreadPool *tp, ThreadPoolJob *job, int *jobId )
{
	int rc = EOUTOFMEM;

	int tempId = -1;
	int totalJobs;

	ThreadPoolJob *temp = NULL;

	assert( tp != NULL );
	assert( job != NULL );
	if( ( tp == NULL ) || ( job == NULL ) ) {
		return EINVAL;
	}

	ithread_mutex_lock( &tp->mutex );

	assert( job->priority == LOW_PRIORITY ||
	job->priority == MED_PRIORITY ||
	job->priority == HIGH_PRIORITY );

	totalJobs = tp->highJobQ.size + tp->lowJobQ.size + tp->medJobQ.size;
	if (totalJobs >= tp->attr.maxJobsTotal) {
		fprintf(stderr, "total jobs = %d, too many jobs", totalJobs);
		ithread_mutex_unlock( &tp->mutex );
		return rc;
	}

	if( jobId == NULL ) {
		jobId = &tempId;
	}
	*jobId = INVALID_JOB_ID;

	temp = CreateThreadPoolJob( job, tp->lastJobId, tp );
	if( temp == NULL ) {
		ithread_mutex_unlock( &tp->mutex );
		return rc;
	}

	if( job->priority == HIGH_PRIORITY ) {
		if( ListAddTail( &tp->highJobQ, temp ) ) {
			rc = 0;
		}
	} else if( job->priority == MED_PRIORITY ) {
		if( ListAddTail( &tp->medJobQ, temp ) ) {
			rc = 0;
		}
	} else {
		if( ListAddTail( &tp->lowJobQ, temp ) ) {
			rc = 0;
		}
	}

	// AddWorker if appropriate
	AddWorker( tp );

	// Notify a waiting thread
	if( rc == 0 ) {
		ithread_cond_signal( &tp->condition );
	} else {
		FreeThreadPoolJob( tp, temp );
	}

	*jobId = tp->lastJobId++;

	ithread_mutex_unlock( &tp->mutex );

	return rc;
}