// 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); } }
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; }
/* 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); }