static int semaphore_test(pj_pool_t *pool) { pj_sem_t *sem; pj_status_t status; PJ_LOG(3,("", "...testing semaphore")); status = pj_sem_create(pool, NULL, 0, 1, &sem); if (status != PJ_SUCCESS) { app_perror("...error: pj_sem_create()", status); return -151; } status = pj_sem_post(sem); if (status != PJ_SUCCESS) { app_perror("...error: pj_sem_post()", status); pj_sem_destroy(sem); return -153; } status = pj_sem_trywait(sem); if (status != PJ_SUCCESS) { app_perror("...error: pj_sem_trywait()", status); pj_sem_destroy(sem); return -156; } status = pj_sem_post(sem); if (status != PJ_SUCCESS) { app_perror("...error: pj_sem_post()", status); pj_sem_destroy(sem); return -159; } status = pj_sem_wait(sem); if (status != PJ_SUCCESS) { app_perror("...error: pj_sem_wait()", status); pj_sem_destroy(sem); return -161; } status = pj_sem_destroy(sem); if (status != PJ_SUCCESS) { app_perror("...error: pj_sem_destroy()", status); return -163; } return 0; }
/* API: start stream. */ static pj_status_t strm_start(pjmedia_aud_stream *s) { struct android_aud_stream *stream = (struct android_aud_stream*)s; if (!stream->running) { stream->running = PJ_TRUE; if (stream->record) pj_sem_post(stream->rec_sem); if (stream->track) pj_sem_post(stream->play_sem); } PJ_LOG(4, (THIS_FILE, "Android JNI stream started")); return PJ_SUCCESS; }
static pj_status_t job_queue_destroy(job_queue *jq) { unsigned i; jq->is_quitting = PJ_TRUE; if (jq->thread) { pj_sem_post(jq->sem); pj_thread_join(jq->thread); pj_thread_destroy(jq->thread); } if (jq->sem) { pj_sem_destroy(jq->sem); jq->sem = NULL; } for (i = 0; i < jq->size; i++) { if (jq->job_sem[i]) { pj_sem_destroy(jq->job_sem[i]); jq->job_sem[i] = NULL; } } if (jq->mutex) { pj_mutex_destroy(jq->mutex); jq->mutex = NULL; } return PJ_SUCCESS; }
static pj_status_t job_queue_post_job(job_queue *jq, job_func_ptr func, void *data, unsigned flags, pj_status_t *retval) { job jb; int tail; if (jq->is_quitting) return PJ_EBUSY; jb.func = func; jb.data = data; jb.flags = flags; pj_mutex_lock(jq->mutex); jq->jobs[jq->tail] = &jb; tail = jq->tail; jq->tail = (jq->tail + 1) % jq->size; pj_sem_post(jq->sem); /* Wait until our posted job is completed. */ pj_sem_wait(jq->job_sem[tail]); pj_mutex_unlock(jq->mutex); if (retval) *retval = jb.retval; return PJ_SUCCESS; }
PJ_DEF(void) pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr) { if (!mgr) mgr = pjmedia_event_mgr_instance(); PJ_ASSERT_ON_FAIL(mgr != NULL, return); if (mgr->thread) { mgr->is_quitting = PJ_TRUE; pj_sem_post(mgr->sem); pj_thread_join(mgr->thread); } if (mgr->sem) { pj_sem_destroy(mgr->sem); mgr->sem = NULL; } if (mgr->mutex) { pj_mutex_destroy(mgr->mutex); mgr->mutex = NULL; } if (mgr->pool) pj_pool_release(mgr->pool); if (event_manager_instance == mgr) event_manager_instance = NULL; }
PJ_DEF(pj_status_t) pjmedia_event_publish( pjmedia_event_mgr *mgr, void *epub, pjmedia_event *event, pjmedia_event_publish_flag flag) { pj_status_t err = PJ_SUCCESS; PJ_ASSERT_RETURN(epub && event, PJ_EINVAL); if (!mgr) mgr = pjmedia_event_mgr_instance(); PJ_ASSERT_RETURN(mgr, PJ_EINVAL); event->epub = epub; pj_mutex_lock(mgr->mutex); if (flag & PJMEDIA_EVENT_PUBLISH_POST_EVENT) { if (event_queue_add_event(&mgr->ev_queue, event) == PJ_SUCCESS) pj_sem_post(mgr->sem); } else { /* For nested pjmedia_event_publish() calls, i.e. calling publish() * inside the subscriber's callback, the function will only add * the event to the event queue of the first publish() call. It * is the first publish() call that will be responsible to * distribute the events. */ if (mgr->pub_ev_queue) { event_queue_add_event(mgr->pub_ev_queue, event); } else { static event_queue ev_queue; pj_status_t status; ev_queue.head = ev_queue.tail = 0; ev_queue.is_full = PJ_FALSE; mgr->pub_ev_queue = &ev_queue; event_queue_add_event(mgr->pub_ev_queue, event); do { status = event_mgr_distribute_events(mgr, mgr->pub_ev_queue, &mgr->pub_next_sub, PJ_FALSE); if (status != PJ_SUCCESS && err == PJ_SUCCESS) err = status; } while(ev_queue.head != ev_queue.tail || ev_queue.is_full); mgr->pub_ev_queue = NULL; } } pj_mutex_unlock(mgr->mutex); return err; }
static int timer_add_entry(pj_timer_entry* entry, pj_time_val* delay) { pj_status_t rc; if (timer_initialized && timer != NULL) { rc = pj_timer_heap_schedule(timer, entry, delay); pj_sem_post(timer_sem); return rc; } else return PJ_EIGNORED; }
static void client_on_request_complete( pj_stun_session *sess, pj_status_t status, void *token, pj_stun_tx_data *tdata, const pj_stun_msg *response, const pj_sockaddr_t *src_addr, unsigned src_addr_len) { PJ_UNUSED_ARG(sess); PJ_UNUSED_ARG(token); PJ_UNUSED_ARG(tdata); PJ_UNUSED_ARG(src_addr); PJ_UNUSED_ARG(src_addr_len); client->response_status = status; if (response) client->response = pj_stun_msg_clone(client->pool, response); pj_sem_post(client->test_complete); }
/* * Release read lock. * */ PJ_DEF(pj_status_t) pj_rwmutex_unlock_read(pj_rwmutex_t *mutex) { pj_status_t status; PJ_ASSERT_RETURN(mutex, PJ_EINVAL); status = pj_mutex_lock(mutex->read_lock); if (status != PJ_SUCCESS) { pj_assert(!"This pretty much is unexpected"); return status; } pj_assert(mutex->reader_count >= 1); --mutex->reader_count; if (mutex->reader_count == 0) pj_sem_post(mutex->write_lock); status = pj_mutex_unlock(mutex->read_lock); return status; }
static int job_thread(void * data) { job_queue *jq = (job_queue *)data; while (1) { job *jb; /* Wait until there is a job. */ pj_sem_wait(jq->sem); /* Make sure there is no pending jobs before we quit. */ if (jq->is_quitting && jq->head == jq->tail) break; jb = jq->jobs[jq->head]; jb->retval = (*jb->func)(jb->data); pj_sem_post(jq->job_sem[jq->head]); jq->head = (jq->head + 1) % jq->size; } return 0; }
/* API: destroy stream. */ static pj_status_t strm_destroy(pjmedia_aud_stream *s) { struct android_aud_stream *stream = (struct android_aud_stream*)s; JNIEnv *jni_env = 0; jmethodID release_method=0; pj_bool_t attached; PJ_LOG(4,(THIS_FILE, "Destroying Android JNI stream...")); stream->quit_flag = PJ_TRUE; /* Stop the stream */ strm_stop(s); attached = attach_jvm(&jni_env); if (stream->record){ if (stream->rec_thread) { pj_sem_post(stream->rec_sem); pj_thread_join(stream->rec_thread); pj_thread_destroy(stream->rec_thread); stream->rec_thread = NULL; } if (stream->rec_sem) { pj_sem_destroy(stream->rec_sem); stream->rec_sem = NULL; } release_method = (*jni_env)->GetMethodID(jni_env, stream->record_class, "release", "()V"); (*jni_env)->CallVoidMethod(jni_env, stream->record, release_method); (*jni_env)->DeleteGlobalRef(jni_env, stream->record); (*jni_env)->DeleteGlobalRef(jni_env, stream->record_class); stream->record = NULL; stream->record_class = NULL; PJ_LOG(4, (THIS_FILE, "Audio record released")); } if (stream->track) { if (stream->play_thread) { pj_sem_post(stream->play_sem); pj_thread_join(stream->play_thread); pj_thread_destroy(stream->play_thread); stream->play_thread = NULL; } if (stream->play_sem) { pj_sem_destroy(stream->play_sem); stream->play_sem = NULL; } release_method = (*jni_env)->GetMethodID(jni_env, stream->track_class, "release", "()V"); (*jni_env)->CallVoidMethod(jni_env, stream->track, release_method); (*jni_env)->DeleteGlobalRef(jni_env, stream->track); (*jni_env)->DeleteGlobalRef(jni_env, stream->track_class); stream->track = NULL; stream->track_class = NULL; PJ_LOG(3, (THIS_FILE, "Audio track released")); } pj_pool_release(stream->pool); PJ_LOG(4, (THIS_FILE, "Android JNI stream destroyed")); detach_jvm(attached); return PJ_SUCCESS; }
/* * Release write lock. * */ PJ_DEF(pj_status_t) pj_rwmutex_unlock_write(pj_rwmutex_t *mutex) { PJ_ASSERT_RETURN(mutex, PJ_EINVAL); pj_assert(mutex->reader_count <= 1); return pj_sem_post(mutex->write_lock); }
static void timer_stop() { timer_running = 0; pj_sem_post(timer_sem); }
// // Post semaphore. // pj_status_t post() { return pj_sem_post(this->pj_sem_t_()); }