コード例 #1
0
ファイル: alsa_dev.c プロジェクト: elimelec/pjproject
/* API: stop stream */
static pj_status_t alsa_stream_stop (pjmedia_aud_stream *s)
{
    struct alsa_stream *stream = (struct alsa_stream*)s;

    stream->quit = 1;

    if (stream->pb_thread) {
	TRACE_((THIS_FILE,
		   "alsa_stream_stop(%u): Waiting for playback to stop.",
		   (unsigned)syscall(SYS_gettid)));
	pj_thread_join (stream->pb_thread);
	TRACE_((THIS_FILE,
		   "alsa_stream_stop(%u): playback stopped.",
		   (unsigned)syscall(SYS_gettid)));
	pj_thread_destroy(stream->pb_thread);
	stream->pb_thread = NULL;
    }

    if (stream->ca_thread) {
	TRACE_((THIS_FILE,
		   "alsa_stream_stop(%u): Waiting for capture to stop.",
		   (unsigned)syscall(SYS_gettid)));
	pj_thread_join (stream->ca_thread);
	TRACE_((THIS_FILE,
		   "alsa_stream_stop(%u): capture stopped.",
		   (unsigned)syscall(SYS_gettid)));
	pj_thread_destroy(stream->ca_thread);
	stream->ca_thread = NULL;
    }

    return PJ_SUCCESS;
}
コード例 #2
0
/* API: stop stream. */
static pj_status_t strm_stop(pjmedia_aud_stream *s)
{
	struct android_aud_stream *stream = (struct android_aud_stream*)s;
	int i;
	//We assume that all jni calls are safe ... that's acceptable
	if(stream->quit_flag == 0){
		PJ_LOG(3, (THIS_FILE, "Stopping stream"));
	}else{
		PJ_LOG(2, (THIS_FILE, "Already stopped.... nothing to do here"));
		return PJ_SUCCESS;
	}

	JNIEnv *jni_env = 0;
	ATTACH_JVM(jni_env);
	jmethodID method_id;

	stream->quit_flag = 1;

	/*
	if (result != 0) {
		PJ_LOG(1, (THIS_FILE, "Not able to attach the jvm"));
		return PJ_ENOMEM;
	}
	*/

	if(stream->record){
		//stop recording
		method_id = jni_env->GetMethodID(stream->record_class, "stop", "()V");
		jni_env->CallVoidMethod(stream->record, method_id);

		if(stream->rec_thread){
			pj_thread_join(stream->rec_thread);
			pj_thread_destroy(stream->rec_thread);
			stream->rec_thread = NULL;
		}
	}


	if(stream->track){
		method_id = jni_env->GetMethodID(stream->track_class,"flush", "()V");
		jni_env->CallVoidMethod(stream->track, method_id);
		method_id = jni_env->GetMethodID(stream->track_class, "stop", "()V");
		jni_env->CallVoidMethod(stream->track, method_id);

		if(stream->play_thread){
			pj_thread_join(stream->play_thread);
			pj_thread_destroy(stream->play_thread);
			stream->play_thread = NULL;
		}
	}



	PJ_LOG(4,(THIS_FILE, "Stopping Done"));

	DETACH_JVM(jni_env);
	return PJ_SUCCESS;

}
コード例 #3
0
ファイル: clock_thread.c プロジェクト: conght/BLM-Lib
/*
 * Destroy the clock. 
 */
PJ_DEF(pj_status_t) pjmedia_clock_destroy(pjmedia_clock *clock)
{
    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);

    clock->running = PJ_FALSE;
    clock->quitting = PJ_TRUE;

    if (clock->thread) {
	pj_thread_join(clock->thread);
	pj_thread_destroy(clock->thread);
	clock->thread = NULL;
    }

    if (clock->lock) {
	pj_lock_destroy(clock->lock);
	clock->lock = NULL;
    }

    if (clock->pool) {
	pj_pool_t *pool = clock->pool;
	clock->pool = NULL;
	pj_pool_release(pool);
    }
    return PJ_SUCCESS;
}
コード例 #4
0
ファイル: endpoint.c プロジェクト: max3903/SFLphone
/**
 * Deinitialize media endpoint.
 */
PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt)
{
    unsigned i;

    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);

    endpt->quit_flag = 1;

    /* Destroy threads */
    for (i=0; i<endpt->thread_cnt; ++i) {
	if (endpt->thread[i]) {
	    pj_thread_join(endpt->thread[i]);
	    pj_thread_destroy(endpt->thread[i]);
	    endpt->thread[i] = NULL;
	}
    }

    /* Destroy internal ioqueue */
    if (endpt->ioqueue && endpt->own_ioqueue) {
	pj_ioqueue_destroy(endpt->ioqueue);
	endpt->ioqueue = NULL;
    }

    endpt->pf = NULL;

    pjmedia_aud_subsys_shutdown();
    pj_pool_release (endpt->pool);

    return PJ_SUCCESS;
}
コード例 #5
0
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;
}
コード例 #6
0
/*
 * Destroy SIP
 */
static void destroy_app()
{
    unsigned i;

    app.thread_quit = 1;
    for (i=0; i<app.thread_count; ++i) {
	if (app.thread[i]) {
	    pj_thread_join(app.thread[i]);
	    pj_thread_destroy(app.thread[i]);
	    app.thread[i] = NULL;
	}
    }

    if (app.sip_endpt) {
	pjsip_endpt_destroy(app.sip_endpt);
	app.sip_endpt = NULL;
    }

    if (app.pool) {
	pj_pool_release(app.pool);
	app.pool = NULL;
	PJ_LOG(3,(THIS_FILE, "Peak memory size: %uMB",
			     app.cp.peak_used_size / 1000000));
	pj_caching_pool_destroy(&app.cp);
    }

    /* Shutdown PJLIB */
    pj_shutdown();
}
コード例 #7
0
ファイル: icedemo.c プロジェクト: conght/BLM-Lib
/* Utility: display error message and exit application (usually
 * because of fatal error.
 */
static void err_exit(const char *title, pj_status_t status)
{
    if (status != PJ_SUCCESS) {
	icedemo_perror(title, status);
    }
    PJ_LOG(3,(THIS_FILE, "Shutting down.."));

    if (icedemo.icest)
	pj_ice_strans_destroy(icedemo.icest);
    
    pj_thread_sleep(500);

    icedemo.thread_quit_flag = PJ_TRUE;
    if (icedemo.thread) {
	pj_thread_join(icedemo.thread);
	pj_thread_destroy(icedemo.thread);
    }

    if (icedemo.ice_cfg.stun_cfg.ioqueue)
	pj_ioqueue_destroy(icedemo.ice_cfg.stun_cfg.ioqueue);

    if (icedemo.ice_cfg.stun_cfg.timer_heap)
	pj_timer_heap_destroy(icedemo.ice_cfg.stun_cfg.timer_heap);

    pj_caching_pool_destroy(&icedemo.cp);

    pj_shutdown();

    if (icedemo.log_fhnd) {
	fclose(icedemo.log_fhnd);
	icedemo.log_fhnd = NULL;
    }

    exit(status != PJ_SUCCESS);
}
コード例 #8
0
ファイル: wmme_sound.c プロジェクト: deveck/Deveck.TAM
/*
 * Destroy stream.
 */
PJ_DEF(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream)
{
    unsigned i;

    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);

    pjmedia_snd_stream_stop(stream);

    if (stream->thread)
    {
	SetEvent(stream->thread_quit_event);
	pj_thread_join(stream->thread);
	pj_thread_destroy(stream->thread);
	stream->thread = NULL;
    }

    /* Unprepare the headers and close the play device */
    if (stream->play_strm.hWave.Out)
    {
	waveOutReset(stream->play_strm.hWave.Out);
	for (i = 0; i < stream->play_strm.dwMaxBufIdx; ++i)
	    waveOutUnprepareHeader(stream->play_strm.hWave.Out, 
				   &(stream->play_strm.WaveHdr[i]),
				   sizeof(WAVEHDR));
	waveOutClose(stream->play_strm.hWave.Out);
	stream->play_strm.hWave.Out = NULL;
    }

    /* Close the play event */
    if (stream->play_strm.hEvent)
    {
	CloseHandle(stream->play_strm.hEvent);
	stream->play_strm.hEvent = NULL;
    }

    /* Unprepare the headers and close the record device */
    if (stream->rec_strm.hWave.In)
    {
	waveInReset(stream->rec_strm.hWave.In);
	for (i = 0; i < stream->play_strm.dwMaxBufIdx; ++i)
	    waveInUnprepareHeader(stream->rec_strm.hWave.In, 
				  &(stream->rec_strm.WaveHdr[i]),
				  sizeof(WAVEHDR));
	waveInClose(stream->rec_strm.hWave.In);
	stream->rec_strm.hWave.In = NULL;
    }

    /* Close the record event */
    if (stream->rec_strm.hEvent)
    {
	CloseHandle(stream->rec_strm.hEvent);
	stream->rec_strm.hEvent = NULL;
    }

    pj_pool_release(stream->pool);

    return PJ_SUCCESS;
}
コード例 #9
0
PJStunTurn::~PJStunTurn() {
  worker_quit_ = true;
  if (nullptr != thread_) {
    pj_thread_join(thread_);
    pj_thread_destroy(thread_);
  }
  if (ice_cfg_.stun_cfg.ioqueue) pj_ioqueue_destroy(ice_cfg_.stun_cfg.ioqueue);

  if (ice_cfg_.stun_cfg.timer_heap) pj_timer_heap_destroy(ice_cfg_.stun_cfg.timer_heap);
}
コード例 #10
0
ファイル: bb10_dev.c プロジェクト: KevinHM/pjsip
/* API: stop stream */
static pj_status_t bb10_stream_stop (pjmedia_aud_stream *s)
{
    struct bb10_stream *stream = (struct bb10_stream*)s;

    stream->quit = 1;
    TRACE_((THIS_FILE,"bb10_stream_stop()"));

    if (stream->pb_thread) {
        pj_thread_join (stream->pb_thread);
        pj_thread_destroy(stream->pb_thread);
        stream->pb_thread = NULL;
    }

    if (stream->ca_thread) {
        pj_thread_join (stream->ca_thread);
        pj_thread_destroy(stream->ca_thread);
        stream->ca_thread = NULL;
    }

    return PJ_SUCCESS;
}
コード例 #11
0
ファイル: endpoint.c プロジェクト: jhcloos/pjproject
/**
 * Stop and destroy the worker threads of the media endpoint
 */
PJ_DEF(pj_status_t) pjmedia_endpt_stop_threads(pjmedia_endpt *endpt)
{
    unsigned i;

    PJ_ASSERT_RETURN(endpt, PJ_EINVAL);

    endpt->quit_flag = 1;

    /* Destroy threads */
    for (i=0; i<endpt->thread_cnt; ++i) {
        if (endpt->thread[i]) {
            pj_thread_join(endpt->thread[i]);
            pj_thread_destroy(endpt->thread[i]);
            endpt->thread[i] = NULL;
        }
    }

    return PJ_SUCCESS;
}
コード例 #12
0
ファイル: sess_auth.c プロジェクト: Antares84/asuswrt-merlin
/* Destroy server */
static void destroy_server(void)
{
    if (server->thread) {
	server->quit = PJ_TRUE;
	pj_thread_join(server->thread);
	pj_thread_destroy(server->thread);
    }

    if (server->sock) {
	pj_sock_close(server->sock);
    }

    if (server->sess) {
	pj_stun_session_destroy(server->sess);
    }

    pj_pool_release(server->pool);
    server = NULL;
}
コード例 #13
0
ファイル: sess_auth.c プロジェクト: Antares84/asuswrt-merlin
static void destroy_client_server(void)
{
    if (client->thread) {
	client->quit = 1;
	pj_thread_join(client->thread);
	pj_thread_destroy(client->thread);
    }

    if (client->sess)
	pj_stun_session_destroy(client->sess);

    if (client->sock)
	pj_sock_close(client->sock);

    if (client->test_complete)
	pj_sem_destroy(client->test_complete);

    if (server)
	destroy_server();
}
コード例 #14
0
ファイル: endpoint.c プロジェクト: silvansky/pjsip_mod
/**
* Deinitialize media endpoint.
*/
PJ_DEF(pj_status_t) pjmedia_endpt_destroy (pjmedia_endpt *endpt)
{
	exit_cb *ecb;
	unsigned i;

	PJ_ASSERT_RETURN(endpt, PJ_EINVAL);

	endpt->quit_flag = 1;

	/* Destroy threads */
	for (i=0; i<endpt->thread_cnt; ++i) {
		if (endpt->thread[i]) {
			pj_thread_join(endpt->thread[i]);
			pj_thread_destroy(endpt->thread[i]);
			endpt->thread[i] = NULL;
		}
	}

	/* Destroy internal ioqueue */
	if (endpt->ioqueue && endpt->own_ioqueue) {
		pj_ioqueue_destroy(endpt->ioqueue);
		endpt->ioqueue = NULL;
	}

	endpt->pf = NULL;

	pjmedia_codec_mgr_destroy(&endpt->codec_mgr);
	pjmedia_aud_subsys_shutdown();

	/* Call all registered exit callbacks */
	ecb = endpt->exit_cb_list.next;
	while (ecb != &endpt->exit_cb_list) {
		(*ecb->func)(endpt);
		ecb = ecb->next;
	}

	pj_pool_release (endpt->pool);

	return PJ_SUCCESS;
}
コード例 #15
0
/* Handler to destroy the transport; called by transport manager */
static pj_status_t loop_destroy(pjsip_transport *tp)
{
    struct loop_transport *loop = (struct loop_transport*)tp;
    
    PJ_ASSERT_RETURN(tp && (tp->key.type == PJSIP_TRANSPORT_LOOP ||
	             tp->key.type == PJSIP_TRANSPORT_LOOP_DGRAM), PJ_EINVAL);
    
    loop->thread_quit_flag = 1;
    /* Unlock transport mutex before joining thread. */
    pj_lock_release(tp->lock);
    pj_thread_join(loop->thread);
    pj_thread_destroy(loop->thread);

    /* Clear pending send notifications. */
    while (!pj_list_empty(&loop->send_list)) {
	struct send_list *node = loop->send_list.next;
	/* Notify callback. */
	if (node->callback) {
	    (*node->callback)(&loop->base, node->token, -PJSIP_ESHUTDOWN);
	}
	pj_list_erase(node);
	pjsip_tx_data_dec_ref(node->tdata);
    }

    /* Clear "incoming" packets in the queue. */
    while (!pj_list_empty(&loop->recv_list)) {
	struct recv_list *node = loop->recv_list.next;
	pj_list_erase(node);
	pjsip_endpt_release_pool(loop->base.endpt,
				 node->rdata.tp_info.pool);
    }

    /* Self destruct.. heheh.. */
    pj_lock_destroy(loop->base.lock);
    pj_atomic_destroy(loop->base.ref_cnt);
    pjsip_endpt_release_pool(loop->base.endpt, loop->base.pool);

    return PJ_SUCCESS;
}
コード例 #16
0
/*
 * Stop the clock. 
 */
PJ_DEF(pj_status_t) pjmedia_clock_stop(pjmedia_clock *clock)
{
    PJ_ASSERT_RETURN(clock != NULL, PJ_EINVAL);

    clock->running = PJ_FALSE;
    clock->quitting = PJ_TRUE;

    if (clock->thread) {
	//	printf("%s:------------1--------------, 0x%02x, %d\n", THIS_FILE, clock, (int)(clock->quitting));
	if (pj_thread_join(clock->thread) == PJ_SUCCESS) {
	//	printf("%s:------------2--------------\n", THIS_FILE);
	    pj_thread_destroy(clock->thread);
	    clock->thread = NULL;
	    pj_pool_reset(clock->pool);
	} else {
	//	printf("%s:------------3--------------\n", THIS_FILE);
	    clock->quitting = PJ_FALSE;
	}
    }

    return PJ_SUCCESS;
}
コード例 #17
0
static int client_shutdown()
{
    unsigned i;

    if (g.thread) {
	g.quit = 1;
	pj_thread_join(g.thread);
	pj_thread_destroy(g.thread);
	g.thread = NULL;
    }
    if (g.relay) {
	pj_turn_sock_destroy(g.relay);
	g.relay = NULL;
    }
    for (i=0; i<PJ_ARRAY_SIZE(g.peer); ++i) {
	if (g.peer[i].stun_sock) {
	    pj_stun_sock_destroy(g.peer[i].stun_sock);
	    g.peer[i].stun_sock = NULL;
	}
    }
    if (g.stun_config.timer_heap) {
	pj_timer_heap_destroy(g.stun_config.timer_heap);
	g.stun_config.timer_heap = NULL;
    }
    if (g.stun_config.ioqueue) {
	pj_ioqueue_destroy(g.stun_config.ioqueue);
	g.stun_config.ioqueue = NULL;
    }
    if (g.pool) {
	pj_pool_release(g.pool);
	g.pool = NULL;
    }
    pj_pool_factory_dump(&g.cp.factory, PJ_TRUE);
    pj_caching_pool_destroy(&g.cp);

    return PJ_SUCCESS;
}
コード例 #18
0
ファイル: alsa_dev.c プロジェクト: elimelec/pjproject
/* API: start stream */
static pj_status_t alsa_stream_start (pjmedia_aud_stream *s)
{
    struct alsa_stream *stream = (struct alsa_stream*)s;
    pj_status_t status = PJ_SUCCESS;

    stream->quit = 0;
    if (stream->param.dir & PJMEDIA_DIR_PLAYBACK) {
	status = pj_thread_create (stream->pool,
				   "alsasound_playback",
				   pb_thread_func,
				   stream,
				   0, //ZERO,
				   0,
				   &stream->pb_thread);
	if (status != PJ_SUCCESS)
	    return status;
    }

    if (stream->param.dir & PJMEDIA_DIR_CAPTURE) {
	status = pj_thread_create (stream->pool,
				   "alsasound_playback",
				   ca_thread_func,
				   stream,
				   0, //ZERO,
				   0,
				   &stream->ca_thread);
	if (status != PJ_SUCCESS) {
	    stream->quit = PJ_TRUE;
	    pj_thread_join(stream->pb_thread);
	    pj_thread_destroy(stream->pb_thread);
	    stream->pb_thread = NULL;
	}
    }

    return status;
}
コード例 #19
0
ファイル: transport_test.c プロジェクト: Jopie64/pjsip
int transport_rt_test( pjsip_transport_type_e tp_type,
		       pjsip_transport *ref_tp,
		       char *target_url,
		       int *lost)
{
    enum { THREADS = 4, INTERVAL = 10 };
    int i;
    pj_status_t status;
    pj_pool_t *pool;
    pj_bool_t logger_enabled;

    pj_timestamp zero_time, total_time;
    unsigned usec_rt;
    unsigned total_sent;
    unsigned total_recv;

    PJ_UNUSED_ARG(tp_type);
    PJ_UNUSED_ARG(ref_tp);

    PJ_LOG(3,(THIS_FILE, "  multithreaded round-trip test (%d threads)...",
		  THREADS));
    PJ_LOG(3,(THIS_FILE, "    this will take approx %d seconds, please wait..",
		INTERVAL));

    /* Make sure msg logger is disabled. */
    logger_enabled = msg_logger_set_enabled(0);

    /* Register module (if not yet registered) */
    if (rt_module.id == -1) {
	status = pjsip_endpt_register_module( endpt, &rt_module );
	if (status != PJ_SUCCESS) {
	    app_perror("   error: unable to register module", status);
	    return -600;
	}
    }

    /* Create pool for this test. */
    pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000);
    if (!pool)
	return -610;

    /* Initialize static test data. */
    pj_ansi_strcpy(rt_target_uri, target_url);
    rt_call_id = pj_str("RT-Call-Id/");
    rt_stop = PJ_FALSE;

    /* Initialize thread data. */
    for (i=0; i<THREADS; ++i) {
	char buf[1];
	pj_str_t str_id;
	
	pj_strset(&str_id, buf, 1);
	pj_bzero(&rt_test_data[i], sizeof(rt_test_data[i]));

	/* Init timer entry */
	rt_test_data[i].tx_timer.id = i;
	rt_test_data[i].tx_timer.cb = &rt_tx_timer;
	rt_test_data[i].timeout_timer.id = i;
	rt_test_data[i].timeout_timer.cb = &rt_timeout_timer;

	/* Generate Call-ID for each thread. */
	rt_test_data[i].call_id.ptr = (char*) pj_pool_alloc(pool, rt_call_id.slen+1);
	pj_strcpy(&rt_test_data[i].call_id, &rt_call_id);
	buf[0] = '0' + (char)i;
	pj_strcat(&rt_test_data[i].call_id, &str_id);

	/* Init mutex. */
	status = pj_mutex_create_recursive(pool, "rt", &rt_test_data[i].mutex);
	if (status != PJ_SUCCESS) {
	    app_perror("   error: unable to create mutex", status);
	    return -615;
	}

	/* Create thread, suspended. */
	status = pj_thread_create(pool, "rttest%p", &rt_worker_thread, (void*)(long)i, 0,
				  PJ_THREAD_SUSPENDED, &rt_test_data[i].thread);
	if (status != PJ_SUCCESS) {
	    app_perror("   error: unable to create thread", status);
	    return -620;
	}
    }

    /* Start threads! */
    for (i=0; i<THREADS; ++i) {
	pj_time_val delay = {0,0};
	pj_thread_resume(rt_test_data[i].thread);

	/* Schedule first message transmissions. */
	rt_test_data[i].tx_timer.user_data = (void*)1;
	pjsip_endpt_schedule_timer(endpt, &rt_test_data[i].tx_timer, &delay);
    }

    /* Sleep for some time. */
    pj_thread_sleep(INTERVAL * 1000);

    /* Signal thread to stop. */
    rt_stop = PJ_TRUE;

    /* Wait threads to complete. */
    for (i=0; i<THREADS; ++i) {
	pj_thread_join(rt_test_data[i].thread);
	pj_thread_destroy(rt_test_data[i].thread);
    }

    /* Destroy rt_test_data */
    for (i=0; i<THREADS; ++i) {
	pj_mutex_destroy(rt_test_data[i].mutex);
	pjsip_endpt_cancel_timer(endpt, &rt_test_data[i].timeout_timer);
    }

    /* Gather statistics. */
    pj_bzero(&total_time, sizeof(total_time));
    pj_bzero(&zero_time, sizeof(zero_time));
    usec_rt = total_sent = total_recv = 0;
    for (i=0; i<THREADS; ++i) {
	total_sent += rt_test_data[i].sent_request_count;
	total_recv +=  rt_test_data[i].recv_response_count;
	pj_add_timestamp(&total_time, &rt_test_data[i].total_rt_time);
    }

    /* Display statistics. */
    if (total_recv)
	total_time.u64 = total_time.u64/total_recv;
    else
	total_time.u64 = 0;
    usec_rt = pj_elapsed_usec(&zero_time, &total_time);
    PJ_LOG(3,(THIS_FILE, "    done."));
    PJ_LOG(3,(THIS_FILE, "    total %d messages sent", total_sent));
    PJ_LOG(3,(THIS_FILE, "    average round-trip=%d usec", usec_rt));

    pjsip_endpt_release_pool(endpt, pool);

    *lost = total_sent-total_recv;

    /* Flush events. */
    flush_events(500);

    /* Restore msg logger. */
    msg_logger_set_enabled(logger_enabled);

    return 0;
}
コード例 #20
0
ファイル: dsound.c プロジェクト: deveck/Deveck.TAM
/*
 * Destroy stream.
 */
PJ_DEF(pj_status_t) pjmedia_snd_stream_close(pjmedia_snd_stream *stream)
{
    PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);

    pjmedia_snd_stream_stop(stream);

    if (stream->thread) {
	pj_assert(stream->thread_quit_event);
	SetEvent(stream->thread_quit_event);
	pj_thread_join(stream->thread);
	pj_thread_destroy(stream->thread);
	stream->thread = NULL;
    }

    if (stream->thread_quit_event) {
	CloseHandle(stream->thread_quit_event);
	stream->thread_quit_event = NULL;
    }

    if (stream->play_strm.lpDsNotify) {
	IDirectSoundNotify_Release( stream->play_strm.lpDsNotify );
	stream->play_strm.lpDsNotify = NULL;
    }
    
    if (stream->play_strm.hEvent) {
	CloseHandle(stream->play_strm.hEvent);
	stream->play_strm.hEvent = NULL;
    }

    if (stream->play_strm.ds.play.lpDsBuffer) {
	IDirectSoundBuffer_Release( stream->play_strm.ds.play.lpDsBuffer );
	stream->play_strm.ds.play.lpDsBuffer = NULL;
    }

    if (stream->play_strm.ds.play.lpDs) {
	IDirectSound_Release( stream->play_strm.ds.play.lpDs );
	stream->play_strm.ds.play.lpDs = NULL;
    }

    if (stream->rec_strm.lpDsNotify) {
	IDirectSoundNotify_Release( stream->rec_strm.lpDsNotify );
	stream->rec_strm.lpDsNotify = NULL;
    }
    
    if (stream->rec_strm.hEvent) {
	CloseHandle(stream->rec_strm.hEvent);
	stream->rec_strm.hEvent = NULL;
    }

    if (stream->rec_strm.ds.capture.lpDsBuffer) {
	IDirectSoundCaptureBuffer_Release( stream->rec_strm.ds.capture.lpDsBuffer );
	stream->rec_strm.ds.capture.lpDsBuffer = NULL;
    }

    if (stream->rec_strm.ds.capture.lpDs) {
	IDirectSoundCapture_Release( stream->rec_strm.ds.capture.lpDs );
	stream->rec_strm.ds.capture.lpDs = NULL;
    }


    pj_pool_release(stream->pool);

    return PJ_SUCCESS;
}
コード例 #21
0
ファイル: os.hpp プロジェクト: 0x0B501E7E/pjproject
 //
 // Destroy thread
 //
 static pj_status_t destroy(pj_thread_t *thread)
 {
     return pj_thread_destroy(thread);
 }
コード例 #22
0
ファイル: thread.c プロジェクト: avble/natClientEx
/*
 * timeslice_test()
 */
static int timeslice_test(void)
{
    enum { NUM_THREADS = 4 };
    pj_pool_t *pool;
    pj_uint32_t counter[NUM_THREADS], lowest, highest, diff;
    pj_thread_t *thread[NUM_THREADS];
    unsigned i;
    pj_status_t rc;

    quit_flag = 0;

    pool = pj_pool_create(mem, NULL, 4000, 4000, NULL);
    if (!pool)
        return -10;

    PJ_LOG(3,(THIS_FILE, "..timeslice testing with %d threads", NUM_THREADS));

    /* Create all threads in suspended mode. */
    for (i=0; i<NUM_THREADS; ++i) {
        counter[i] = i;
        rc = pj_thread_create(pool, "thread", (pj_thread_proc*)&thread_proc,
			      &counter[i],
                              PJ_THREAD_DEFAULT_STACK_SIZE,
                              PJ_THREAD_SUSPENDED,
                              &thread[i]);
        if (rc!=PJ_SUCCESS) {
            app_perror("...ERROR in pj_thread_create()", rc);
            return -20;
        }
    }

    /* Sleep for 1 second.
     * The purpose of this is to test whether all threads are suspended.
     */
    TRACE__((THIS_FILE, "    Main thread waiting.."));
    pj_thread_sleep(1000);
    TRACE__((THIS_FILE, "    Main thread resuming.."));

    /* Check that all counters are still zero. */
    for (i=0; i<NUM_THREADS; ++i) {
        if (counter[i] > i) {
            PJ_LOG(3,(THIS_FILE, "....ERROR! Thread %d-th is not suspended!",
		      i));
            return -30;
        }
    }

    /* Now resume all threads. */
    for (i=0; i<NUM_THREADS; ++i) {
	TRACE__((THIS_FILE, "    Resuming thread %d [%p]..", i, thread[i]));
        rc = pj_thread_resume(thread[i]);
        if (rc != PJ_SUCCESS) {
            app_perror("...ERROR in pj_thread_resume()", rc);
            return -40;
        }
    }

    /* Main thread sleeps for some time to allow threads to run.
     * The longer we sleep, the more accurate the calculation will be,
     * but it'll make user waits for longer for the test to finish.
     */
    TRACE__((THIS_FILE, "    Main thread waiting (5s).."));
    pj_thread_sleep(5000);
    TRACE__((THIS_FILE, "    Main thread resuming.."));

    /* Signal all threads to quit. */
    quit_flag = 1;

    /* Wait until all threads quit, then destroy. */
    for (i=0; i<NUM_THREADS; ++i) {
	TRACE__((THIS_FILE, "    Main thread joining thread %d [%p]..",
			    i, thread[i]));
        rc = pj_thread_join(thread[i]);
        if (rc != PJ_SUCCESS) {
            app_perror("...ERROR in pj_thread_join()", rc);
            return -50;
        }
	TRACE__((THIS_FILE, "    Destroying thread %d [%p]..", i, thread[i]));
        rc = pj_thread_destroy(thread[i]);
        if (rc != PJ_SUCCESS) {
            app_perror("...ERROR in pj_thread_destroy()", rc);
            return -60;
        }
    }

    TRACE__((THIS_FILE, "    Main thread calculating time slices.."));

    /* Now examine the value of the counters.
     * Check that all threads had equal proportion of processing.
     */
    lowest = 0xFFFFFFFF;
    highest = 0;
    for (i=0; i<NUM_THREADS; ++i) {
        if (counter[i] < lowest)
            lowest = counter[i];
        if (counter[i] > highest)
            highest = counter[i];
    }

    /* Check that all threads are running. */
    if (lowest < 2) {
        PJ_LOG(3,(THIS_FILE, "...ERROR: not all threads were running!"));
        return -70;
    }

    /* The difference between lowest and higest should be lower than 50%.
     */
    diff = (highest-lowest)*100 / ((highest+lowest)/2);
    if ( diff >= 50) {
        PJ_LOG(3,(THIS_FILE,
		  "...ERROR: thread didn't have equal timeslice!"));
        PJ_LOG(3,(THIS_FILE,
		  ".....lowest counter=%u, highest counter=%u, diff=%u%%",
                  lowest, highest, diff));
        return -80;
    } else {
        PJ_LOG(3,(THIS_FILE,
                  "...info: timeslice diff between lowest & highest=%u%%",
                  diff));
    }

    pj_pool_release(pool);
    return 0;
}
コード例 #23
0
ファイル: ioq_perf.c プロジェクト: RyanLee27/pjproject
/* Calculate the bandwidth for the specific test configuration.
 * The test is simple:
 *  - create sockpair_cnt number of producer-consumer socket pair.
 *  - create thread_cnt number of worker threads.
 *  - each producer will send buffer_size bytes data as fast and
 *    as soon as it can.
 *  - each consumer will read buffer_size bytes of data as fast 
 *    as it could.
 *  - measure the total bytes received by all consumers during a
 *    period of time.
 */
static int perform_test(pj_bool_t allow_concur,
			int sock_type, const char *type_name,
                        unsigned thread_cnt, unsigned sockpair_cnt,
                        pj_size_t buffer_size, 
                        pj_size_t *p_bandwidth)
{
    enum { MSEC_DURATION = 5000 };
    pj_pool_t *pool;
    test_item *items;
    pj_thread_t **thread;
    pj_ioqueue_t *ioqueue;
    pj_status_t rc;
    pj_ioqueue_callback ioqueue_callback;
    pj_uint32_t total_elapsed_usec, total_received;
    pj_highprec_t bandwidth;
    pj_timestamp start, stop;
    unsigned i;

    TRACE_((THIS_FILE, "    starting test.."));

    ioqueue_callback.on_read_complete = &on_read_complete;
    ioqueue_callback.on_write_complete = &on_write_complete;

    thread_quit_flag = 0;

    pool = pj_pool_create(mem, NULL, 4096, 4096, NULL);
    if (!pool)
        return -10;

    items = (test_item*) pj_pool_alloc(pool, sockpair_cnt*sizeof(test_item));
    thread = (pj_thread_t**)
    	     pj_pool_alloc(pool, thread_cnt*sizeof(pj_thread_t*));

    TRACE_((THIS_FILE, "     creating ioqueue.."));
    rc = pj_ioqueue_create(pool, sockpair_cnt*2, &ioqueue);
    if (rc != PJ_SUCCESS) {
        app_perror("...error: unable to create ioqueue", rc);
        return -15;
    }

    rc = pj_ioqueue_set_default_concurrency(ioqueue, allow_concur);
    if (rc != PJ_SUCCESS) {
	app_perror("...error: pj_ioqueue_set_default_concurrency()", rc);
        return -16;
    }

    /* Initialize each producer-consumer pair. */
    for (i=0; i<sockpair_cnt; ++i) {
        pj_ssize_t bytes;

        items[i].ioqueue = ioqueue;
        items[i].buffer_size = buffer_size;
        items[i].outgoing_buffer = (char*) pj_pool_alloc(pool, buffer_size);
        items[i].incoming_buffer = (char*) pj_pool_alloc(pool, buffer_size);
        items[i].bytes_recv = items[i].bytes_sent = 0;

        /* randomize outgoing buffer. */
        pj_create_random_string(items[i].outgoing_buffer, buffer_size);

        /* Create socket pair. */
	TRACE_((THIS_FILE, "      calling socketpair.."));
        rc = app_socketpair(pj_AF_INET(), sock_type, 0, 
                            &items[i].server_fd, &items[i].client_fd);
        if (rc != PJ_SUCCESS) {
            app_perror("...error: unable to create socket pair", rc);
            return -20;
        }

        /* Register server socket to ioqueue. */
	TRACE_((THIS_FILE, "      register(1).."));
        rc = pj_ioqueue_register_sock(pool, ioqueue, 
                                      items[i].server_fd,
                                      &items[i], &ioqueue_callback,
                                      &items[i].server_key);
        if (rc != PJ_SUCCESS) {
            app_perror("...error: registering server socket to ioqueue", rc);
            return -60;
        }

        /* Register client socket to ioqueue. */
	TRACE_((THIS_FILE, "      register(2).."));
        rc = pj_ioqueue_register_sock(pool, ioqueue, 
                                      items[i].client_fd,
                                      &items[i],  &ioqueue_callback,
                                      &items[i].client_key);
        if (rc != PJ_SUCCESS) {
            app_perror("...error: registering server socket to ioqueue", rc);
            return -70;
        }

        /* Start reading. */
	TRACE_((THIS_FILE, "      pj_ioqueue_recv.."));
        bytes = items[i].buffer_size;
        rc = pj_ioqueue_recv(items[i].server_key, &items[i].recv_op,
                             items[i].incoming_buffer, &bytes,
			     0);
        if (rc != PJ_EPENDING) {
            app_perror("...error: pj_ioqueue_recv", rc);
            return -73;
        }

        /* Start writing. */
	TRACE_((THIS_FILE, "      pj_ioqueue_write.."));
        bytes = items[i].buffer_size;
        rc = pj_ioqueue_send(items[i].client_key, &items[i].send_op,
                             items[i].outgoing_buffer, &bytes, 0);
        if (rc != PJ_SUCCESS && rc != PJ_EPENDING) {
            app_perror("...error: pj_ioqueue_write", rc);
            return -76;
        }

        items[i].has_pending_send = (rc==PJ_EPENDING);
    }

    /* Create the threads. */
    for (i=0; i<thread_cnt; ++i) {
	struct thread_arg *arg;

	arg = (struct thread_arg*) pj_pool_zalloc(pool, sizeof(*arg));
	arg->id = i;
	arg->ioqueue = ioqueue;
	arg->counter = 0;

        rc = pj_thread_create( pool, NULL, 
                               &worker_thread, 
                               arg, 
                               PJ_THREAD_DEFAULT_STACK_SIZE, 
                               PJ_THREAD_SUSPENDED, &thread[i] );
        if (rc != PJ_SUCCESS) {
            app_perror("...error: unable to create thread", rc);
            return -80;
        }
    }

    /* Mark start time. */
    rc = pj_get_timestamp(&start);
    if (rc != PJ_SUCCESS)
        return -90;

    /* Start the thread. */
    TRACE_((THIS_FILE, "     resuming all threads.."));
    for (i=0; i<thread_cnt; ++i) {
        rc = pj_thread_resume(thread[i]);
        if (rc != 0)
            return -100;
    }

    /* Wait for MSEC_DURATION seconds. 
     * This should be as simple as pj_thread_sleep(MSEC_DURATION) actually,
     * but unfortunately it doesn't work when system doesn't employ
     * timeslicing for threads.
     */
    TRACE_((THIS_FILE, "     wait for few seconds.."));
    do {
	pj_thread_sleep(1);

	/* Mark end time. */
	rc = pj_get_timestamp(&stop);

	if (thread_quit_flag) {
	    TRACE_((THIS_FILE, "      transfer limit reached.."));
	    break;
	}

	if (pj_elapsed_usec(&start,&stop)<MSEC_DURATION * 1000) {
	    TRACE_((THIS_FILE, "      time limit reached.."));
	    break;
	}

    } while (1);

    /* Terminate all threads. */
    TRACE_((THIS_FILE, "     terminating all threads.."));
    thread_quit_flag = 1;

    for (i=0; i<thread_cnt; ++i) {
	TRACE_((THIS_FILE, "      join thread %d..", i));
        pj_thread_join(thread[i]);
    }

    /* Close all sockets. */
    TRACE_((THIS_FILE, "     closing all sockets.."));
    for (i=0; i<sockpair_cnt; ++i) {
        pj_ioqueue_unregister(items[i].server_key);
        pj_ioqueue_unregister(items[i].client_key);
    }

    /* Destroy threads */
    for (i=0; i<thread_cnt; ++i) {
        pj_thread_destroy(thread[i]);
    }

    /* Destroy ioqueue. */
    TRACE_((THIS_FILE, "     destroying ioqueue.."));
    pj_ioqueue_destroy(ioqueue);

    /* Calculate actual time in usec. */
    total_elapsed_usec = pj_elapsed_usec(&start, &stop);

    /* Calculate total bytes received. */
    total_received = 0;
    for (i=0; i<sockpair_cnt; ++i) {
        total_received = (pj_uint32_t)items[i].bytes_recv;
    }

    /* bandwidth = total_received*1000/total_elapsed_usec */
    bandwidth = total_received;
    pj_highprec_mul(bandwidth, 1000);
    pj_highprec_div(bandwidth, total_elapsed_usec);
    
    *p_bandwidth = (pj_uint32_t)bandwidth;

    PJ_LOG(3,(THIS_FILE, "   %.4s    %2d        %2d       %8d KB/s",
              type_name, thread_cnt, sockpair_cnt,
              *p_bandwidth));

    /* Done. */
    pj_pool_release(pool);

    TRACE_((THIS_FILE, "    done.."));
    return 0;
}
コード例 #24
0
ファイル: endpoint.c プロジェクト: ananse-im/pjproject
/**
 * Initialize and get the instance of media endpoint.
 */
PJ_DEF(pj_status_t) pjmedia_endpt_create2(pj_pool_factory *pf,
					  pj_ioqueue_t *ioqueue,
					  unsigned worker_cnt,
					  pjmedia_endpt **p_endpt)
{
    pj_pool_t *pool;
    pjmedia_endpt *endpt;
    unsigned i;
    pj_status_t status;

    status = pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE,
				  &pjmedia_strerror);
    pj_assert(status == PJ_SUCCESS);

    PJ_ASSERT_RETURN(pf && p_endpt, PJ_EINVAL);
    PJ_ASSERT_RETURN(worker_cnt <= MAX_THREADS, PJ_EINVAL);

    pool = pj_pool_create(pf, "med-ept", 512, 512, NULL);
    if (!pool)
	return PJ_ENOMEM;

    endpt = PJ_POOL_ZALLOC_T(pool, struct pjmedia_endpt);
    endpt->pool = pool;
    endpt->pf = pf;
    endpt->ioqueue = ioqueue;
    endpt->thread_cnt = worker_cnt;
    endpt->has_telephone_event = PJ_TRUE;

    /* Initialize audio subsystem.
     * To avoid pjmedia's dependendy on pjmedia-audiodev, the initialization
     * (and shutdown) of audio subsystem will be done in the application
     * level instead, when it calls inline functions pjmedia_endpt_create()
     * and pjmedia_endpt_destroy().
     */
    //status = pjmedia_aud_subsys_init(pf);
    //if (status != PJ_SUCCESS)
    //	goto on_error;

    /* Init codec manager. */
    status = pjmedia_codec_mgr_init(&endpt->codec_mgr, endpt->pf);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Initialize exit callback list. */
    pj_list_init(&endpt->exit_cb_list);

    /* Create ioqueue if none is specified. */
    if (endpt->ioqueue == NULL) {
	
	endpt->own_ioqueue = PJ_TRUE;

	status = pj_ioqueue_create( endpt->pool, PJ_IOQUEUE_MAX_HANDLES,
				    &endpt->ioqueue);
	if (status != PJ_SUCCESS)
	    goto on_error;

	if (worker_cnt == 0) {
	    PJ_LOG(4,(THIS_FILE, "Warning: no worker thread is created in"  
				 "media endpoint for internal ioqueue"));
	}
    }

    /* Create worker threads if asked. */
    for (i=0; i<worker_cnt; ++i) {
	status = pj_thread_create( endpt->pool, "media", &worker_proc,
				   endpt, 0, 0, &endpt->thread[i]);
	if (status != PJ_SUCCESS)
	    goto on_error;
    }


    *p_endpt = endpt;
    return PJ_SUCCESS;

on_error:

    /* Destroy threads */
    for (i=0; i<endpt->thread_cnt; ++i) {
	if (endpt->thread[i]) {
	    pj_thread_destroy(endpt->thread[i]);
	}
    }

    /* Destroy internal ioqueue */
    if (endpt->ioqueue && endpt->own_ioqueue)
	pj_ioqueue_destroy(endpt->ioqueue);

    pjmedia_codec_mgr_destroy(&endpt->codec_mgr);
    //pjmedia_aud_subsys_shutdown();
    pj_pool_release(pool);
    return status;
}
コード例 #25
0
ファイル: endpoint.c プロジェクト: max3903/SFLphone
/**
 * Initialize and get the instance of media endpoint.
 */
PJ_DEF(pj_status_t) pjmedia_endpt_create(pj_pool_factory *pf,
					 pj_ioqueue_t *ioqueue,
					 unsigned worker_cnt,
					 pjmedia_endpt **p_endpt)
{
    pj_pool_t *pool;
    pjmedia_endpt *endpt;
    unsigned i;
    pj_status_t status;

    if (!error_subsys_registered) {
	pj_register_strerror(PJMEDIA_ERRNO_START, PJ_ERRNO_SPACE_SIZE, 
			     &pjmedia_strerror);
	error_subsys_registered = 1;
    }

    PJ_ASSERT_RETURN(pf && p_endpt, PJ_EINVAL);
    PJ_ASSERT_RETURN(worker_cnt <= MAX_THREADS, PJ_EINVAL);

    pool = pj_pool_create(pf, "med-ept", 512, 512, NULL);
    if (!pool)
	return PJ_ENOMEM;

    endpt = PJ_POOL_ZALLOC_T(pool, struct pjmedia_endpt);
    endpt->pool = pool;
    endpt->pf = pf;
    endpt->ioqueue = ioqueue;
    endpt->thread_cnt = worker_cnt;

    /* Sound */
    status = pjmedia_aud_subsys_init(pf);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Init codec manager. */
    status = pjmedia_codec_mgr_init(&endpt->codec_mgr);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Create ioqueue if none is specified. */
    if (endpt->ioqueue == NULL) {
	
	endpt->own_ioqueue = PJ_TRUE;

	status = pj_ioqueue_create( endpt->pool, PJ_IOQUEUE_MAX_HANDLES,
				    &endpt->ioqueue);
	if (status != PJ_SUCCESS)
	    goto on_error;

	if (worker_cnt == 0) {
	    PJ_LOG(4,(THIS_FILE, "Warning: no worker thread is created in"  
				 "media endpoint for internal ioqueue"));
	}
    }

    /* Create worker threads if asked. */
    for (i=0; i<worker_cnt; ++i) {
	status = pj_thread_create( endpt->pool, "media", &worker_proc,
				   endpt, 0, 0, &endpt->thread[i]);
	if (status != PJ_SUCCESS)
	    goto on_error;
    }


    *p_endpt = endpt;
    return PJ_SUCCESS;

on_error:

    /* Destroy threads */
    for (i=0; i<endpt->thread_cnt; ++i) {
	if (endpt->thread[i]) {
	    pj_thread_destroy(endpt->thread[i]);
	}
    }

    /* Destroy internal ioqueue */
    if (endpt->ioqueue && endpt->own_ioqueue)
	pj_ioqueue_destroy(endpt->ioqueue);

    pjmedia_aud_subsys_shutdown();
    pj_pool_release(pool);
    return status;
}
コード例 #26
0
/* Start loop transport. */
PJ_DEF(pj_status_t) pjsip_loop_start( pjsip_endpoint *endpt,
				      pjsip_transport **transport)
{
    pj_pool_t *pool;
    struct loop_transport *loop;
    pj_status_t status;

    /* Create pool. */
    pool = pjsip_endpt_create_pool(endpt, "loop", 4000, 4000);
    if (!pool)
	return PJ_ENOMEM;

    /* Create the loop structure. */
    loop = pj_pool_zalloc(pool, sizeof(struct loop_transport));
    
    /* Initialize transport properties. */
    pj_ansi_snprintf(loop->base.obj_name, sizeof(loop->base.obj_name), 
		     "loop%p", loop);
    loop->base.pool = pool;
    status = pj_atomic_create(pool, 0, &loop->base.ref_cnt);
    if (status != PJ_SUCCESS)
	goto on_error;
    status = pj_lock_create_recursive_mutex(pool, "loop", &loop->base.lock);
    if (status != PJ_SUCCESS)
	goto on_error;
    loop->base.key.type = PJSIP_TRANSPORT_LOOP_DGRAM;
    //loop->base.key.rem_addr.sa_family = PJ_AF_INET;
    loop->base.type_name = "LOOP-DGRAM";
    loop->base.info = "LOOP-DGRAM";
    loop->base.flag = PJSIP_TRANSPORT_DATAGRAM;
    loop->base.local_name.host = pj_str(ADDR_LOOP_DGRAM);
    loop->base.local_name.port = 
	pjsip_transport_get_default_port_for_type(loop->base.key.type);
    loop->base.addr_len = sizeof(pj_sockaddr_in);
    loop->base.endpt = endpt;
    loop->base.tpmgr = pjsip_endpt_get_tpmgr(endpt);
    loop->base.send_msg = &loop_send_msg;
    loop->base.destroy = &loop_destroy;

    pj_list_init(&loop->recv_list);
    pj_list_init(&loop->send_list);

    /* Create worker thread. */
    status = pj_thread_create(pool, "loop", 
			      &loop_transport_worker_thread, loop, 0, 
			      PJ_THREAD_SUSPENDED, &loop->thread);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Register to transport manager. */
    status = pjsip_transport_register( loop->base.tpmgr, &loop->base);
    if (status != PJ_SUCCESS)
	goto on_error;

    /* Start the thread. */
    status = pj_thread_resume(loop->thread);
    if (status != PJ_SUCCESS)
	goto on_error;

    /*
     * Done.
     */

    if (transport)
	*transport = &loop->base;

    return PJ_SUCCESS;

on_error:
    if (loop->base.lock)
	pj_lock_destroy(loop->base.lock);
    if (loop->thread)
	pj_thread_destroy(loop->thread);
    if (loop->base.ref_cnt)
	pj_atomic_destroy(loop->base.ref_cnt);
    pjsip_endpt_release_pool(endpt, loop->pool);
    return status;
}
コード例 #27
0
ファイル: android_jni_dev.c プロジェクト: talk-to/PjSip-Repo
/* 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;
}
コード例 #28
0
/*
 * Perform unregistration test.
 *
 * This will create ioqueue and register a server socket. Depending
 * on the test method, either the callback or the main thread will
 * unregister and destroy the server socket after some period of time.
 */
static int perform_unreg_test(pj_ioqueue_t *ioqueue,
			      pj_pool_t *test_pool,
			      const char *title, 
			      pj_bool_t other_socket)
{
    enum { WORKER_CNT = 1, MSEC = 500, QUIT_MSEC = 500 };
    int i;
    pj_thread_t *thread[WORKER_CNT];
    struct sock_data osd;
    pj_ioqueue_callback callback;
    pj_time_val end_time;
    pj_status_t status;


    /* Sometimes its important to have other sockets registered to
     * the ioqueue, because when no sockets are registered, the ioqueue
     * will return from the poll early.
     */
    if (other_socket) {
	status = app_socket(pj_AF_INET(), pj_SOCK_DGRAM(), 0, 56127, &osd.sock);
	if (status != PJ_SUCCESS) {
	    app_perror("Error creating other socket", status);
	    return -12;
	}

	pj_bzero(&callback, sizeof(callback));
	status = pj_ioqueue_register_sock(test_pool, ioqueue, osd.sock,
					  NULL, &callback, &osd.key);
	if (status != PJ_SUCCESS) {
	    app_perror("Error registering other socket", status);
	    return -13;
	}

    } else {
	osd.key = NULL;
	osd.sock = PJ_INVALID_SOCKET;
    }

    /* Init both time duration of testing */
    thread_quitting = 0;
    pj_gettimeofday(&time_to_unregister);
    time_to_unregister.msec += MSEC;
    pj_time_val_normalize(&time_to_unregister);

    end_time = time_to_unregister;
    end_time.msec += QUIT_MSEC;
    pj_time_val_normalize(&end_time);

    
    /* Create polling thread */
    for (i=0; i<WORKER_CNT; ++i) {
	status = pj_thread_create(test_pool, "unregtest", &worker_thread,
				   ioqueue, 0, 0, &thread[i]);
	if (status != PJ_SUCCESS) {
	    app_perror("Error creating thread", status);
	    return -20;
	}
    }

    /* Create pair of client/server sockets */
    status = app_socketpair(pj_AF_INET(), pj_SOCK_DGRAM(), 0, 
			    &sock_data.sock, &sock_data.csock);
    if (status != PJ_SUCCESS) {
	app_perror("app_socketpair error", status);
	return -30;
    }


    /* Initialize test data */
    sock_data.pool = pj_pool_create(mem, "sd", 1000, 1000, NULL);
    sock_data.buffer = (char*) pj_pool_alloc(sock_data.pool, 128);
    sock_data.bufsize = 128;
    sock_data.op_key = (pj_ioqueue_op_key_t*) 
    		       pj_pool_alloc(sock_data.pool, 
				     sizeof(*sock_data.op_key));
    sock_data.received = 0;
    sock_data.unregistered = 0;

    pj_ioqueue_op_key_init(sock_data.op_key, sizeof(*sock_data.op_key));

    status = pj_mutex_create_simple(sock_data.pool, "sd", &sock_data.mutex);
    if (status != PJ_SUCCESS) {
	app_perror("create_mutex() error", status);
	return -35;
    }

    /* Register socket to ioqueue */
    pj_bzero(&callback, sizeof(callback));
    callback.on_read_complete = &on_read_complete;
    status = pj_ioqueue_register_sock(sock_data.pool, ioqueue, sock_data.sock,
				      NULL, &callback, &sock_data.key);
    if (status != PJ_SUCCESS) {
	app_perror("pj_ioqueue_register error", status);
	return -40;
    }

    /* Bootstrap the first send/receive */
    on_read_complete(sock_data.key, sock_data.op_key, 0);

    /* Loop until test time ends */
    for (;;) {
	pj_time_val now, timeout;

	pj_gettimeofday(&now);

	if (test_method == UNREGISTER_IN_APP && 
	    PJ_TIME_VAL_GTE(now, time_to_unregister) &&
	    sock_data.pool) 
	{
	    pj_mutex_lock(sock_data.mutex);

	    sock_data.unregistered = 1;
	    pj_ioqueue_unregister(sock_data.key);
	    pj_mutex_unlock(sock_data.mutex);
	    pj_mutex_destroy(sock_data.mutex);
	    pj_pool_release(sock_data.pool);
	    sock_data.pool = NULL;
	}

	if (PJ_TIME_VAL_GT(now, end_time) && sock_data.unregistered)
	    break;

	timeout.sec = 0; timeout.msec = 10;
	pj_ioqueue_poll(ioqueue, &timeout);
	//pj_thread_sleep(1);

    }

    thread_quitting = 1;

    for (i=0; i<WORKER_CNT; ++i) {
	pj_thread_join(thread[i]);
	pj_thread_destroy(thread[i]);
    }

    if (other_socket) {
	pj_ioqueue_unregister(osd.key);
    }

    pj_sock_close(sock_data.csock);

    PJ_LOG(3,(THIS_FILE, "....%s: done (%d KB/s)",
	      title, sock_data.received * 1000 / MSEC / 1000));
    return 0;
}
コード例 #29
0
ファイル: server.c プロジェクト: imace/mbgapp
/*
 * Destroy the server.
 */
PJ_DEF(pj_status_t) pj_turn_srv_destroy(pj_turn_srv *srv)
{
    pj_hash_iterator_t itbuf, *it;
    unsigned i;

    /* Stop all worker threads */
    srv->core.quit = PJ_TRUE;
    for (i=0; i<srv->core.thread_cnt; ++i) {
	if (srv->core.thread[i]) {
	    pj_thread_join(srv->core.thread[i]);
	    pj_thread_destroy(srv->core.thread[i]);
	    srv->core.thread[i] = NULL;
	}
    }

    /* Destroy all allocations FIRST */
    if (srv->tables.alloc) {
	it = pj_hash_first(srv->tables.alloc, &itbuf);
	while (it != NULL) {
	    pj_turn_allocation *alloc = (pj_turn_allocation*)
					pj_hash_this(srv->tables.alloc, it);
	    pj_hash_iterator_t *next = pj_hash_next(srv->tables.alloc, it);
	    pj_turn_allocation_destroy(alloc);
	    it = next;
	}
    }
    
    /* Destroy all listeners. */
    for (i=0; i<srv->core.lis_cnt; ++i) {
	if (srv->core.listener[i]) {
	    pj_turn_listener_destroy(srv->core.listener[i]);
	    srv->core.listener[i] = NULL;
	}
    }

    /* Destroy STUN session */
    if (srv->core.stun_sess) {
	pj_stun_session_destroy(srv->core.stun_sess);
	srv->core.stun_sess = NULL;
    }

    /* Destroy hash tables (well, sort of) */
    if (srv->tables.alloc) {
	srv->tables.alloc = NULL;
	srv->tables.res = NULL;
    }
    
    /* Destroy timer heap */
    if (srv->core.timer_heap) {
	pj_timer_heap_destroy(srv->core.timer_heap);
	srv->core.timer_heap = NULL;
    }

    /* Destroy ioqueue */
    if (srv->core.ioqueue) {
	pj_ioqueue_destroy(srv->core.ioqueue);
	srv->core.ioqueue = NULL;
    }

    /* Destroy thread local IDs */
    if (srv->core.tls_key != -1) {
	pj_thread_local_free(srv->core.tls_key);
	srv->core.tls_key = -1;
    }
    if (srv->core.tls_data != -1) {
	pj_thread_local_free(srv->core.tls_data);
	srv->core.tls_data = -1;
    }

    /* Destroy server lock */
    if (srv->core.lock) {
	pj_lock_destroy(srv->core.lock);
	srv->core.lock = NULL;
    }

    /* Release pool */
    if (srv->core.pool) {
	pj_pool_t *pool = srv->core.pool;
	srv->core.pool = NULL;
	pj_pool_release(pool);
    }

    /* Done */
    return PJ_SUCCESS;
}