Beispiel #1
0
// Get item or wait max time.
qitem* queue_timepop(queue *queue, uint32_t miliseconds)
{
	qitem *r = qpop(&queue->q);
	if (r)
		return r;
	else
	{
		if (SEM_TIMEDWAIT(queue->sem, miliseconds) != 0)
			return NULL;
		else
			return qpop(&queue->q);
	}
}
Beispiel #2
0
static void *realplay_thread(void *arg)
{
	realplay_handle_t *p = (realplay_handle_t *)arg;
	int first = 0;
	struct timespec ts;
	int ret;

	while (1) {
		pthread_mutex_lock(&p->login_id_mtx);
		p->play_ret = p->fp_realplay_start(p);
		pthread_mutex_unlock(&p->login_id_mtx);

		if (first == 0) {
			first = 1;
			sem_post(&p->play_sem);
			if (p->play_ret == -1)
				break;
		}

		if (p->play_ret == -1) {
			clock_gettime(CLOCK_REALTIME, &ts);
			ts.tv_sec += RECONN_DELAY;
			SEM_TIMEDWAIT(&p->stop_sem, &ts, &ret);

			if (p->stop_sess == 1)
				break;
			continue;
		}

		p->state_cb(1, p->param);
		recv_data(p);
		p->state_cb(0, p->param);

		pthread_mutex_lock(&p->login_id_mtx);
		p->fp_realplay_stop(p);
		pthread_mutex_unlock(&p->login_id_mtx);

		if (p->stop_sess == 1)
			break;
	}

	return NULL;
}
Beispiel #3
0
/* packetization: 0-not need packetization to rtp packages, 1-need */
unsigned long specialipc_start_realplay(realplay_info_t *info)
{
	realplay_handle_t *p;
	struct timespec ts;
	int ret;

	p = calloc(1, sizeof(realplay_handle_t));
	if (p == NULL)
		goto err;
	memcpy(p, info, sizeof(realplay_handle_t));

	pthread_mutex_init(&p->login_id_mtx, NULL);

	if (sem_init(&p->play_sem, 0, 0) || sem_init(&p->stop_sem, 0, 0))
		goto err;
	p->play_ret = -1;
	p->stop_sess = 0;

	ret = pthread_create(&p->play_tid, NULL, realplay_thread, p);
	if (ret != 0)
		goto err;

	clock_gettime(CLOCK_REALTIME, &ts);
	ts.tv_sec += 5;
	SEM_TIMEDWAIT(&p->play_sem, &ts, &ret);
	if (p->play_ret == -1) {
		pthread_join(p->play_tid, NULL);
		goto err;
	}

	syslog(LOG_DEBUG, "specialipc play session: %lu", (unsigned long)p);
	return (unsigned long)p;

err:
	session_free(p);
	syslog(LOG_DEBUG, "specialipc play session error");
	return -1;
}
void openavbAcmpSMControllerStateMachine()
{
	AVB_TRACE_ENTRY(AVB_TRACE_ACMP);

	openavb_acmp_InflightCommand_t *pInflightActive = NULL;		// The inflight command for the current state
	openavb_acmp_sm_controller_state_t state = OPENAVB_ACMP_SM_CONTROLLER_STATE_WAITING;

	// Lock such that the mutex is held unless waiting for a semaphore. Synchronous processing of command responses.
	ACMP_SM_LOCK();
	while (bRunning) {
		switch (state) {
			case OPENAVB_ACMP_SM_CONTROLLER_STATE_WAITING:
				AVB_TRACE_LINE(AVB_TRACE_ACMP);
				AVB_LOG_DEBUG("State:  OPENAVB_ACMP_SM_CONTROLLER_STATE_WAITING");

				openavbAcmpSMControllerVars.rcvdResponse = FALSE;

				// Calculate timeout for inflight commands
				// Start is a arbitrary large time out.
				struct timespec timeout;
				CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &timeout);
				timeout.tv_sec += 60;	// At most will timeout after 60 seconds

				// Look for soonest inflight command timeout
				openavb_list_node_t node = openavbListIterFirst(openavbAcmpSMControllerVars.inflight);
				while (node) {
					openavb_acmp_InflightCommand_t *pInflight = openavbListData(node);
					if ((openavbTimeTimespecCmp(&pInflight->timer, &timeout) < 0)) {
						timeout.tv_sec = pInflight->timer.tv_sec;
						timeout.tv_nsec = pInflight->timer.tv_nsec;
					}
					node = openavbListIterNext(openavbAcmpSMControllerVars.inflight);
				}

				ACMP_SM_UNLOCK();
				U32 timeoutMSec = 0;
				struct timespec now;
				CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &now);
				timeoutMSec = openavbTimeUntilMSec(&now, &timeout);
				SEM_ERR_T(err);
				SEM_TIMEDWAIT(openavbAcmpSMControllerSemaphore, timeoutMSec, err);
				ACMP_SM_LOCK();

				if (!SEM_IS_ERR_NONE(err)) {
					if (SEM_IS_ERR_TIMEOUT(err)) {
						struct timespec now;
						CLOCK_GETTIME(OPENAVB_CLOCK_REALTIME, &now);

						// Look for a timed out inflight command
						openavb_list_node_t node = openavbListIterFirst(openavbAcmpSMControllerVars.inflight);
						while (node) {
							openavb_acmp_InflightCommand_t *pInflight = openavbListData(node);
							if ((openavbTimeTimespecCmp(&now, &pInflight->timer) >= 0)) {
								// Found a timed out command
								state = OPENAVB_ACMP_SM_CONTROLLER_STATE_TIMEOUT;
								pInflightActive = pInflight;
								break;
							}
							node = openavbListIterNext(openavbAcmpSMControllerVars.inflight);
						}
					}
				}
				else {
					if (openavbAcmpSMControllerVars.doTerminate) {
						bRunning = FALSE;
					}
					else if (openavbAcmpSMControllerVars.rcvdResponse &&
							memcmp(pRcvdCmdResp->controller_entity_id, openavbAcmpSMGlobalVars.my_id, sizeof(openavbAcmpSMGlobalVars.my_id)) == 0) {
						// Look for a corresponding inflight command
						openavb_list_node_t node = openavbListIterFirst(openavbAcmpSMControllerVars.inflight);
						while (node) {
							openavb_acmp_InflightCommand_t *pInflight = openavbListData(node);
							if (pRcvdCmdResp->sequence_id == pInflight->command.sequence_id &&
									pRcvdCmdResp->message_type == pInflight->command.message_type + 1) {
								// Found a corresponding command
								state = OPENAVB_ACMP_SM_CONTROLLER_STATE_RESPONSE;
								pInflightActive = pInflight;
								break;
							}
							node = openavbListIterNext(openavbAcmpSMControllerVars.inflight);
						}
					}
				break;

			case OPENAVB_ACMP_SM_CONTROLLER_STATE_TIMEOUT:
				{
					AVB_TRACE_LINE(AVB_TRACE_ACMP);
					AVB_LOG_DEBUG("State:  OPENAVB_ACMP_SM_CONTROLLER_STATE_TIMEOUT");

					if (pInflightActive) {
						if (pInflightActive->retried) {
							openavbAcmpSMController_removeInflight(&pInflightActive->command);
						}
						else {
							openavbAcmpSMController_txCommand(pInflightActive->command.message_type, &pInflightActive->command, TRUE);
						}
					}
					pInflightActive = NULL;
					state = OPENAVB_ACMP_SM_CONTROLLER_STATE_WAITING;
				}
				break;

			case OPENAVB_ACMP_SM_CONTROLLER_STATE_RESPONSE:
				{
					AVB_TRACE_LINE(AVB_TRACE_ACMP);
					AVB_LOG_DEBUG("State:  OPENAVB_ACMP_SM_CONTROLLER_STATE_RESPONSE");

					if (pInflightActive) {
						openavbAcmpSMController_cancelTimeout(pRcvdCmdResp);
						openavbAcmpSMController_processResponse(pRcvdCmdResp);
						openavbAcmpSMController_removeInflight(pRcvdCmdResp);
					}
					pInflightActive = NULL;
					state = OPENAVB_ACMP_SM_CONTROLLER_STATE_WAITING;
				}
				break;
			}
		}
	}
	ACMP_SM_UNLOCK();

	AVB_TRACE_EXIT(AVB_TRACE_ACMP);
}