/**************************************** 
            API: create stream 
*****************************************/
static pj_status_t stream_stopBDIMAD(pjmedia_aud_stream *s)
{
    struct bd_stream *strm = (struct bd_stream*)s;
    pj_status_t status = PJ_SUCCESS;
    int i, err = 0;

    PJ_ASSERT_RETURN(strm != NULL, PJ_EINVAL);

    strm->go = 0;    
    
    for (i=0; !strm->rec_thread_exited && i<100; ++i)
	pj_thread_sleep(10);
    for (i=0; !strm->play_thread_exited && i<100; ++i)
	pj_thread_sleep(10);

    pj_thread_sleep(1);

    PJ_LOG(5,(THIS_FILE, "Stopping stream.."));

    strm->play_thread_initialized = 0;
    strm->rec_thread_initialized = 0;

    PJ_LOG(5,(THIS_FILE, "Done, status=%d", err));

    return status;
}
static pj_status_t stream_destroyBDIMAD(pjmedia_aud_stream *s)
{
    struct bd_stream *strm = (struct bd_stream*)s;
    int i = 0;

    PJ_ASSERT_RETURN(strm != NULL, PJ_EINVAL);

    stream_stopBDIMAD(s);

    // DeInit BDIMAD
    bdIMADpj_FreeAEC(&strm->bdIMADpjInstance); 
	PJ_LOG(4, (THIS_FILE, "Free AEC"));

    bdIMADpj_FreeStructures(&strm->bdIMADpjSettingsPtr, 
			    &strm->bdIMADpjWarningPtr);
    PJ_LOG(4, (THIS_FILE, "Free AEC Structure"));

    strm->bdIMADpjInstance = NULL;
    strm->bdIMADpjSettingsPtr = NULL;
    strm->bdIMADpjWarningPtr = NULL;    

    strm->quit_flag = 1;
    for (i=0; !strm->rec_thread_exited && i<100; ++i) {
	pj_thread_sleep(1);
    }
    for (i=0; !strm->play_thread_exited && i<100; ++i) {
	pj_thread_sleep(1);
    }

    PJ_LOG(5,(THIS_FILE, "Destroying stream.."));

    pj_pool_release(strm->pool);
    return PJ_SUCCESS;
}
Example #3
0
/* API: stop stream. */
static pj_status_t strm_stop(pjmedia_aud_stream *s)
{
    struct pa_aud_stream *stream = (struct pa_aud_stream*)s;
    int i, err = 0;

    stream->quit_flag = 1;
    for (i=0; !stream->rec_thread_exited && i<100; ++i)
	pj_thread_sleep(10);
    for (i=0; !stream->play_thread_exited && i<100; ++i)
	pj_thread_sleep(10);

    pj_thread_sleep(1);

    PJ_LOG(5,(THIS_FILE, "Stopping stream.."));

    if (stream->play_strm)
	err = Pa_StopStream(stream->play_strm);

    if (stream->rec_strm && stream->rec_strm != stream->play_strm)
	err = Pa_StopStream(stream->rec_strm);

    stream->play_thread_initialized = 0;
    stream->rec_thread_initialized = 0;

    PJ_LOG(5,(THIS_FILE, "Done, status=%d", err));

    return err ? PJMEDIA_AUDIODEV_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
Example #4
0
/* API: destroy stream. */
static pj_status_t strm_destroy(pjmedia_aud_stream *s)
{
    struct pa_aud_stream *stream = (struct pa_aud_stream*)s;
    int i, err = 0;

    stream->quit_flag = 1;
    for (i=0; !stream->rec_thread_exited && i<100; ++i) {
	pj_thread_sleep(1);
    }
    for (i=0; !stream->play_thread_exited && i<100; ++i) {
	pj_thread_sleep(1);
    }

    PJ_LOG(5,(THIS_FILE, "Closing %.*s: %lu underflow, %lu overflow",
			 (int)stream->name.slen,
			 stream->name.ptr,
			 stream->underflow, stream->overflow));

    if (stream->play_strm)
	err = Pa_CloseStream(stream->play_strm);

    if (stream->rec_strm && stream->rec_strm != stream->play_strm)
	err = Pa_CloseStream(stream->rec_strm);

    pj_pool_release(stream->pool);

    return err ? PJMEDIA_AUDIODEV_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
Example #5
0
static int stun_destroy_test_session(struct stun_test_session *test_sess)
{

    unsigned i;
    pj_stun_sock_cb stun_cb;
    pj_status_t status;
    pj_stun_sock *stun_sock[MAX_SOCK_CLIENTS];

    pj_bzero(&stun_cb, sizeof(stun_cb));
    stun_cb.on_status = &stun_sock_on_status;

    pj_event_reset(test_sess->server_event);

    /* Create all clients first */
    for (i=0; i<MAX_SOCK_CLIENTS; ++i) {
	char name[10];
	sprintf(name, "stun%02d", i);
	status = pj_stun_sock_create(&test_sess->stun_cfg, name, pj_AF_INET(),
	                             &stun_cb, NULL, test_sess,
	                             &stun_sock[i]);
	if (status != PJ_SUCCESS) {
	    PJ_PERROR(1,(THIS_FILE, status, "Error creating stun socket"));
	    return -10;
	}
    }

    /* Start resolution */
    for (i=0; i<MAX_SOCK_CLIENTS; ++i) {
	pj_str_t server_ip = pj_str("127.0.0.1");
	status = pj_stun_sock_start(stun_sock[i], &server_ip,
	                            (pj_uint16_t)test_sess->server_port, NULL);
	if (status != PJ_SUCCESS) {
	    PJ_PERROR(1,(THIS_FILE, status, "Error starting stun socket"));
	    return -20;
	}
    }

    /* settle down */
    pj_thread_sleep(test_sess->param.client_sleep_after_start);

    /* Resume server threads */
    pj_event_set(test_sess->server_event);

    pj_thread_sleep(test_sess->param.client_sleep_before_destroy);

    /* Destroy clients */
    for (i=0; i<MAX_SOCK_CLIENTS; ++i) {
	status = pj_stun_sock_destroy(stun_sock[i]);
	if (status != PJ_SUCCESS) {
	    PJ_PERROR(1,(THIS_FILE, status, "Error destroying stun socket"));
	}
    }

    /* Give some time to ioqueue to free sockets */
    pj_thread_sleep(PJ_IOQUEUE_KEY_FREE_DELAY);

    return 0;
}
Example #6
0
static void benchmark(void)
{
    FILETIME creation_time, exit_time;
    struct Times start, end;
    DWORD ts, te;
    LARGE_INTEGER elapsed;
    BOOL rc;
    int i;
    double pct;

    puts("Test started!"); fflush(stdout);

    ts = GetTickCount();
    rc = GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
			 &start.kernel_time, &start.user_time);
    for (i=DURATION; i>0; --i) {
	printf("\r%d ", i); fflush(stdout);
	pj_thread_sleep(1000);
    }
    rc = GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,
			 &end.kernel_time, &end.user_time);
    te = GetTickCount();

    process(&start);
    process(&end);

    elapsed.QuadPart = end.u_total.QuadPart - start.u_total.QuadPart;

    pct = elapsed.QuadPart * 100.0 / ((te-ts)*10000.0);

    printf("CPU usage=%6.4f%%\n", pct); fflush(stdout);
}
Example #7
0
static int simple_sleep_test(void)
{
    enum { COUNT = 10 };
    int i;
    pj_status_t rc;
    
    PJ_LOG(3,(THIS_FILE, "..will write messages every 1 second:"));
    
    for (i=0; i<COUNT; ++i) {
	pj_time_val tv;
	pj_parsed_time pt;

	rc = pj_thread_sleep(1000);
	if (rc != PJ_SUCCESS) {
	    app_perror("...error: pj_thread_sleep()", rc);
	    return -10;
	}

	rc = pj_gettimeofday(&tv);
	if (rc != PJ_SUCCESS) {
	    app_perror("...error: pj_gettimeofday()", rc);
	    return -11;
	}

	pj_time_decode(&tv, &pt);

	PJ_LOG(3,(THIS_FILE, 
		  "...%04d-%02d-%02d %02d:%02d:%02d.%03d",
		  pt.year, pt.mon, pt.day,
		  pt.hour, pt.min, pt.sec, pt.msec));

    }

    return 0;
}
Example #8
0
/* 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);
}
Example #9
0
static int timer_thread_run(void* p)
{
    pj_time_val tick = {0, 10};

    timer_running = 1;

    while (timer_running)
    {
        if (pj_timer_heap_count(timer) == 0)
        {
            pj_sem_wait(timer_sem);
        }
        else
        {
            pj_thread_sleep(PJ_TIME_VAL_MSEC(tick));
            pj_timer_heap_poll(timer, NULL);
        }
    }
    pj_timer_heap_destroy(timer);
    timer = NULL;
    pj_sem_destroy(timer_sem);
    timer_sem = NULL;
    pj_pool_release(timer_pool);
    timer_pool = NULL;
    timer_initialized = 0;
    return 0;
}
Example #10
0
static void on_response(pj_http_req *hreq, const pj_http_resp *resp)
{
    pj_size_t i;

    PJ_UNUSED_ARG(hreq);
    PJ_UNUSED_ARG(resp);
    PJ_UNUSED_ARG(i);

#ifdef VERBOSE
    printf("%.*s, %d, %.*s\n", STR_PREC(resp->version),
           resp->status_code, STR_PREC(resp->reason));
    for (i = 0; i < resp->headers.count; i++) {
        printf("%.*s : %.*s\n", 
               STR_PREC(resp->headers.header[i].name),
               STR_PREC(resp->headers.header[i].value));
    }
#endif

    if (test_cancel) {
	/* Need to delay closing the client socket here, otherwise the
	 * server will get SIGPIPE when sending response.
	 */
	pj_thread_sleep(100);
        pj_http_req_cancel(hreq, PJ_TRUE);
        test_cancel = PJ_FALSE;
    }
}
Example #11
0
static int timestamp_accuracy()
{
    pj_timestamp freq, t1, t2;
    pj_time_val tv1, tv2, tvtmp;
    pj_uint32_t msec, tics;
    pj_int64_t diff;

    PJ_LOG(3,(THIS_FILE, "...testing frequency accuracy (pls wait)"));

    pj_get_timestamp_freq(&freq);

    /* Get the start time */
    pj_gettimeofday(&tvtmp);
    do {
	pj_gettimeofday(&tv1);
    } while (PJ_TIME_VAL_EQ(tvtmp, tv1));
    pj_get_timestamp(&t1);

    /* Sleep for 5 seconds */
    pj_thread_sleep(10000);

    /* Get end time */
    pj_gettimeofday(&tvtmp);
    do {
	pj_gettimeofday(&tv2);
    } while (PJ_TIME_VAL_EQ(tvtmp, tv2));
    pj_get_timestamp(&t2);

    /* Get the elapsed time */
    PJ_TIME_VAL_SUB(tv2, tv1);
    msec = PJ_TIME_VAL_MSEC(tv2);

    /* Check that the frequency match the elapsed time */
    tics = (unsigned)(t2.u64 - t1.u64);
    diff = tics - (msec * freq.u64 / 1000);
    if (diff < 0)
	diff = -diff;

    /* Only allow 1 msec mismatch */
    if (diff > (pj_int64_t)(freq.u64 / 1000)) {
	PJ_LOG(3,(THIS_FILE, "....error: timestamp drifted by %d usec after "
			     "%d msec", 
			     (pj_uint32_t)(diff * 1000000 / freq.u64), 
			     msec));
	return -2000;

    /* Otherwise just print warning if timestamp drifted by >1 usec */
    } else if (diff > (pj_int64_t)(freq.u64 / 1000000)) {
	PJ_LOG(3,(THIS_FILE, "....warning: timestamp drifted by %d usec after "
			     "%d msec", 
			     (pj_uint32_t)(diff * 1000000 / freq.u64), 
			     msec));
    } else {
	PJ_LOG(3,(THIS_FILE, "....good. Timestamp is accurate down to"
			     " nearest usec."));
    }

    return 0;
}
Example #12
0
int echo_srv_common_loop(pj_atomic_t *bytes_counter)
{
    pj_highprec_t last_received, avg_bw, highest_bw;
    pj_time_val last_print;
    unsigned count;
    const char *ioqueue_name;

    last_received = 0;
    pj_gettimeofday(&last_print);
    avg_bw = highest_bw = 0;
    count = 0;

    ioqueue_name = pj_ioqueue_name();

    for (;;) {
        pj_highprec_t received, cur_received, bw;
        unsigned msec;
        pj_time_val now, duration;

        pj_thread_sleep(1000);

        received = cur_received = pj_atomic_get(bytes_counter);
        cur_received = cur_received - last_received;

        pj_gettimeofday(&now);
        duration = now;
        PJ_TIME_VAL_SUB(duration, last_print);
        msec = PJ_TIME_VAL_MSEC(duration);
        
        bw = cur_received;
        pj_highprec_mul(bw, 1000);
        pj_highprec_div(bw, msec);

        last_print = now;
        last_received = received;

        avg_bw = avg_bw + bw;
        count++;

        PJ_LOG(3,("", "%s UDP (%d threads): %u KB/s (avg=%u KB/s) %s", 
		  ioqueue_name,
                  ECHO_SERVER_MAX_THREADS, 
                  (unsigned)(bw / 1000),
                  (unsigned)(avg_bw / count / 1000),
                  (count==20 ? "<ses avg>" : "")));

        if (count==20) {
            if (avg_bw/count > highest_bw)
                highest_bw = avg_bw/count;

            count = 0;
            avg_bw = 0;

            PJ_LOG(3,("", "Highest average bandwidth=%u KB/s",
                          (unsigned)(highest_bw/1000)));
        }
    }
    PJ_UNREACHED(return 0;)
}
Example #13
0
/*
 * Clock thread
 */
static int clock_thread(void *arg)
{
    pj_timestamp now;
    pjmedia_clock *clock = (pjmedia_clock*) arg;

    /* Set thread priority to maximum unless not wanted. */
    if ((clock->options & PJMEDIA_CLOCK_NO_HIGHEST_PRIO) == 0) {
	int max = pj_thread_get_prio_max(pj_thread_this());
	if (max > 0)
	    pj_thread_set_prio(pj_thread_this(), max);
    }

    //printf("%s:------------11--------------\n", THIS_FILE);
    /* Get the first tick */
    pj_get_timestamp(&clock->next_tick);
    clock->next_tick.u64 += clock->interval.u64;


    while (!clock->quitting) {

	pj_get_timestamp(&now);

	/* Wait for the next tick to happen */
	if (now.u64 < clock->next_tick.u64) {
	    unsigned msec;
	    msec = pj_elapsed_msec(&now, &clock->next_tick);
	    pj_thread_sleep(msec);
	}
    //printf("%s:------------12--------------, 0x%02x, %d\n", THIS_FILE, clock, (int)(clock->quitting));
	/* Skip if not running */
	if (!clock->running) {
	    /* Calculate next tick */
	    clock_calc_next_tick(clock, &now);
	    continue;
	}

	pj_lock_acquire(clock->lock);
    //printf("%s:------------13--------------, 0x%02x, %d\n", THIS_FILE, clock, (int)(clock->quitting));
	/* Call callback, if any */
	if (clock->cb)
	    (*clock->cb)(&clock->timestamp, clock->user_data);

	/* Best effort way to detect if we've been destroyed in the callback */
	if (clock->quitting)
	    break;

	/* Increment timestamp */
	clock->timestamp.u64 += clock->timestamp_inc;
    //printf("%s:------------14--------------, 0x%02x, %d\n", THIS_FILE, clock, (int)(clock->quitting));
	/* Calculate next tick */
	clock_calc_next_tick(clock, &now);
    //printf("%s:------------15--------------\n", THIS_FILE);
	pj_lock_release(clock->lock);
    }

    return 0;
}
Example #14
0
/*
 * Poll the I/O Queue for completed events.
 */
PJ_DEF(int) pj_ioqueue_poll( pj_ioqueue_t *ioq,
			     const pj_time_val *timeout)
{
    /* Polling is not necessary on UWP, since each socket handles
     * its events already.
     */
    PJ_UNUSED_ARG(ioq);

    pj_thread_sleep(PJ_TIME_VAL_MSEC(*timeout));

    return 0;
}
Example #15
0
static pj_status_t wait_play(pjmedia_frame *f)
{
    play_frm_copied = PJ_FALSE;
    play_frm = *f;
    play_frm_ready = PJ_TRUE;
    while (!play_frm_copied) {
	pj_thread_sleep(1);
    }
    play_frm_ready = PJ_FALSE;

    return PJ_SUCCESS;
}
Example #16
0
int do_test(void *user) {
    int i;
    pj_pool_t *pool = (pj_pool_t *)user;
    opool_init(&opool, 10, strlen(s)+10, pool);
    for (i = 0; i < 100; i++) {
        opool_item_t *p_item = opool_get(&opool);
        pj_memcpy(p_item->data, s, strlen(s));
        printf("%d: %s\n", i, p_item->data);
        pj_thread_sleep(pj_rand()%100);
        opool_free(&opool, p_item);
    }
    return 0;
}
Example #17
0
/* 
 * Handle timer and network events 
 */
static void srv_handle_events(pj_turn_srv *srv, const pj_time_val *max_timeout)
{
    /* timeout is 'out' var. This just to make compiler happy. */
    pj_time_val timeout = { 0, 0};
    unsigned net_event_count = 0;
    int c;

    /* Poll the timer. The timer heap has its own mutex for better 
     * granularity, so we don't need to lock the server. 
     */
    timeout.sec = timeout.msec = 0;
    c = pj_timer_heap_poll( srv->core.timer_heap, &timeout );

    /* timer_heap_poll should never ever returns negative value, or otherwise
     * ioqueue_poll() will block forever!
     */
    pj_assert(timeout.sec >= 0 && timeout.msec >= 0);
    if (timeout.msec >= 1000) timeout.msec = 999;

    /* If caller specifies maximum time to wait, then compare the value with
     * the timeout to wait from timer, and use the minimum value.
     */
    if (max_timeout && PJ_TIME_VAL_GT(timeout, *max_timeout)) {
	timeout = *max_timeout;
    }

    /* Poll ioqueue. 
     * Repeat polling the ioqueue while we have immediate events, because
     * timer heap may process more than one events, so if we only process
     * one network events at a time (such as when IOCP backend is used),
     * the ioqueue may have trouble keeping up with the request rate.
     *
     * For example, for each send() request, one network event will be
     *   reported by ioqueue for the send() completion. If we don't poll
     *   the ioqueue often enough, the send() completion will not be
     *   reported in timely manner.
     */
    do {
	c = pj_ioqueue_poll( srv->core.ioqueue, &timeout);
	if (c < 0) {
	    pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));
	    return;
	} else if (c == 0) {
	    break;
	} else {
	    net_event_count += c;
	    timeout.sec = timeout.msec = 0;
	}
    } while (c > 0 && net_event_count < MAX_NET_EVENTS);

}
Example #18
0
void queue_enqueue(queue_t *queue, void *value)
{
    pthread_mutex_lock(&(queue->mutex));
    while (queue->size == queue->capacity) {
        pj_thread_sleep(2);
        pthread_cond_wait(&(queue->cond_full), &(queue->mutex));
    }
    queue->buffer[queue->in] = value;
    ++ queue->size;
    ++ queue->in;
    queue->in %= queue->capacity;
    pthread_mutex_unlock(&(queue->mutex));
    pthread_cond_broadcast(&(queue->cond_empty));
}
Example #19
0
pj_status_t PJStunTurn::handle_events(unsigned max_msec, unsigned* p_count) {
  enum { MAX_NET_EVENTS = 1 };
  pj_time_val max_timeout = {0, 0};
  pj_time_val timeout = {0, 0};
  unsigned count = 0, net_event_count = 0;
  int c;
  max_timeout.msec = max_msec;
  /* Poll the timer to run it and also to retrieve the earliest entry. */
  timeout.sec = timeout.msec = 0;
  c = pj_timer_heap_poll(ice_cfg_.stun_cfg.timer_heap, &timeout);
  if (c > 0) count += c;
  /* timer_heap_poll should never ever returns negative value, or otherwise
   * ioqueue_poll() will block forever!
   */
  pj_assert(timeout.sec >= 0 && timeout.msec >= 0);
  if (timeout.msec >= 1000) timeout.msec = 999;
  /* compare the value with the timeout to wait from timer, and use the
   * minimum value.
   */
  if (PJ_TIME_VAL_GT(timeout, max_timeout)) timeout = max_timeout;
  /* Poll ioqueue.
   * Repeat polling the ioqueue while we have immediate events, because
   * timer heap may process more than one events, so if we only process
   * one network events at a time (such as when IOCP backend is used),
   * the ioqueue may have trouble keeping up with the request rate.
   *
   * For example, for each send() request, one network event will be
   *   reported by ioqueue for the send() completion. If we don't poll
   *   the ioqueue often enough, the send() completion will not be
   *   reported in timely manner.
   */
  do {
    c = pj_ioqueue_poll(ice_cfg_.stun_cfg.ioqueue, &timeout);
    if (c < 0) {
      pj_status_t err = pj_get_netos_error();
      pj_thread_sleep(PJ_TIME_VAL_MSEC(timeout));
      if (p_count) *p_count = count;
      return err;
    } else if (c == 0) {
      break;
    } else {
      net_event_count += c;
      timeout.sec = timeout.msec = 0;
    }
  } while (c > 0 && net_event_count < MAX_NET_EVENTS);
  count += net_event_count;
  if (p_count) *p_count = count;
  return PJ_SUCCESS;
}
Example #20
0
/*
 * Stop stream.
 */
PJ_DEF(pj_status_t) pjmedia_snd_stream_stop(pjmedia_snd_stream *stream)
{
    int i, err = 0;

    stream->quit_flag = 1;
    for (i=0; !stream->rec_thread_exited && i<100; ++i)
	pj_thread_sleep(10);
    for (i=0; !stream->play_thread_exited && i<100; ++i)
	pj_thread_sleep(10);

    pj_thread_sleep(1);

    PJ_LOG(5,(THIS_FILE, "Stopping stream.."));

    if (stream->play_strm)
	err = Pa_StopStream(stream->play_strm);

    if (stream->rec_strm && stream->rec_strm != stream->play_strm)
	err = Pa_StopStream(stream->rec_strm);

    PJ_LOG(5,(THIS_FILE, "Done, status=%d", err));

    return err ? PJMEDIA_ERRNO_FROM_PORTAUDIO(err) : PJ_SUCCESS;
}
Example #21
0
void *queue_dequeue(queue_t *queue)
{
    pthread_mutex_lock(&(queue->mutex));
    while (queue->size == 0) {
        pj_thread_sleep(2);
        pthread_cond_wait(&(queue->cond_empty), &(queue->mutex));
    }
    void *value = queue->buffer[queue->out];
    //printf("dequeue %d\n", *(int *)value);
    -- queue->size;
    ++ queue->out;
    queue->out %= queue->capacity;
    pthread_mutex_unlock(&(queue->mutex));
    pthread_cond_broadcast(&(queue->cond_full));
    return value;
}
Example #22
0
/*
 * Poll the clock. 
 */
PJ_DEF(pj_bool_t) pjmedia_clock_wait( pjmedia_clock *clock,
				      pj_bool_t wait,
				      pj_timestamp *ts)
{
    pj_timestamp now;
    pj_status_t status;

    PJ_ASSERT_RETURN(clock != NULL, PJ_FALSE);
    PJ_ASSERT_RETURN((clock->options & PJMEDIA_CLOCK_NO_ASYNC) != 0,
		     PJ_FALSE);
    PJ_ASSERT_RETURN(clock->running, PJ_FALSE);

    status = pj_get_timestamp(&now);
    if (status != PJ_SUCCESS)
	return PJ_FALSE;

    /* Wait for the next tick to happen */
    if (now.u64 < clock->next_tick.u64) {
	unsigned msec;

	if (!wait)
	    return PJ_FALSE;

	msec = pj_elapsed_msec(&now, &clock->next_tick);
	pj_thread_sleep(msec);
    }

    /* Call callback, if any */
    if (clock->cb)
	(*clock->cb)(&clock->timestamp, clock->user_data);

    /* Report timestamp to caller */
    if (ts)
	ts->u64 = clock->timestamp.u64;

    /* Increment timestamp */
    clock->timestamp.u64 += clock->samples_per_frame;

    /* Calculate next tick */
    clock->next_tick.u64 += clock->interval.u64;

    /* Done */
    return PJ_TRUE;
}
Example #23
0
static void ui_sleep(char menuin[])
{
    if (pj_ansi_strnicmp(menuin, "sleep", 5)==0) {
	pj_str_t tmp;
	int delay;

	tmp.ptr = menuin+6;
	tmp.slen = pj_ansi_strlen(menuin)-7;

	if (tmp.slen < 1) {
	    puts("Usage: sleep MSEC");
	    return;
	}

	delay = pj_strtoul(&tmp);
	if (delay < 0) delay = 0;
	pj_thread_sleep(delay);
    }
}
Example #24
0
/*
 * Clock thread
 */
static int clock_thread(void *arg)
{
    pj_timestamp now;
    pjmedia_clock *clock = arg;

    /* Get the first tick */
    pj_get_timestamp(&clock->next_tick);
    clock->next_tick.u64 += clock->interval.u64;


    while (!clock->quitting) {

	pj_get_timestamp(&now);

	/* Wait for the next tick to happen */
	if (now.u64 < clock->next_tick.u64) {
	    unsigned msec;
	    msec = pj_elapsed_msec(&now, &clock->next_tick);
	    pj_thread_sleep(msec);
	}

	/* Skip if not running */
	if (!clock->running)
	    continue;

	pj_lock_acquire(clock->lock);

	/* Call callback, if any */
	if (clock->cb)
	    (*clock->cb)(&clock->timestamp, clock->user_data);

	/* Increment timestamp */
	clock->timestamp.u64 += clock->samples_per_frame;

	/* Calculate next tick */
	clock->next_tick.u64 += clock->interval.u64;

	pj_lock_release(clock->lock);
    }

    return 0;
}
Example #25
0
static void destroy_stack(void)
{
    enum { WAIT_CLEAR = 5000, WAIT_INTERVAL = 500 };
    unsigned i;

    PJ_LOG(3,(THIS_FILE, "Shutting down.."));

    /* Wait until all clear */
    hangup_all();
    for (i=0; i<WAIT_CLEAR/WAIT_INTERVAL; ++i) {
	unsigned j;

	for (j=0; j<MAX_CALLS; ++j) {
	    call_t *call = &app.call[j];
	    if (call->inv && call->inv->state <= PJSIP_INV_STATE_CONFIRMED)
		break;
	}

	if (j==MAX_CALLS)
	    return;

	pj_thread_sleep(WAIT_INTERVAL);
    }

    app.quit = PJ_TRUE;
    if (app.worker_thread) {
	pj_thread_join(app.worker_thread);
	app.worker_thread = NULL;
    }

    //if (app.med_endpt)
	//pjmedia_endpt_destroy(app.med_endpt);

    if (app.sip_endpt)
	pjsip_endpt_destroy(app.sip_endpt);

    if (app.pool)
	pj_pool_release(app.pool);

    dump_pool_usage(THIS_FILE, &app.cp);
    pj_caching_pool_destroy(&app.cp);
}
Example #26
0
static int rt_worker_thread(void *arg)
{
    int i;
    pj_time_val poll_delay = { 0, 10 };

    PJ_UNUSED_ARG(arg);

    /* Sleep to allow main threads to run. */
    pj_thread_sleep(10);

    while (!rt_stop) {
	pjsip_endpt_handle_events(endpt, &poll_delay);
    }

    /* Exhaust responses. */
    for (i=0; i<100; ++i)
	pjsip_endpt_handle_events(endpt, &poll_delay);

    return 0;
}
Example #27
0
int main() {
    pj_caching_pool cp;
    pj_pool_t *pool;
    int i;
    pj_thread_t *thread1;
    
    pj_log_set_level(3);
    CHECK(__FILE__, pj_init());
    pj_srand(123765);
    pj_caching_pool_init(&cp, NULL, 1024);

    pool = pj_pool_create(&cp.factory, "objpool", 128, 128, NULL);

    pj_thread_create(pool, "thread1", &do_test, pool, PJ_THREAD_DEFAULT_STACK_SIZE, 0, &thread1);
    pj_thread_sleep(500);
    do_test(pool);

    pj_thread_join(thread1);

    pj_pool_release(pool);
    pj_caching_pool_destroy(&cp);
    pj_shutdown();
    return 0;
}
Example #28
0
/*
 * main()
 */
int main(int argc, char *argv[])
{
    pj_caching_pool cp;
    pjmedia_endpt *med_endpt;
    pj_pool_t *pool;
    pjmedia_port *file_port;
    pjmedia_snd_port *snd_port;
    char tmp[10];
    pj_status_t status;


    if (argc != 2) {
    	puts("Error: filename required");
	puts(desc);
	return 1;
    }


    /* Must init PJLIB first: */
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Must create a pool factory before we can allocate any memory. */
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);

    /* 
     * Initialize media endpoint.
     * This will implicitly initialize PJMEDIA too.
     */
    status = pjmedia_endpt_create(&cp.factory, NULL, 1, &med_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Create memory pool for our file player */
    pool = pj_pool_create( &cp.factory,	    /* pool factory	    */
			   "wav",	    /* pool name.	    */
			   4000,	    /* init size	    */
			   4000,	    /* increment size	    */
			   NULL		    /* callback on error    */
			   );

    /* Create file media port from the WAV file */
    status = pjmedia_wav_player_port_create(  pool,	/* memory pool	    */
					      argv[1],	/* file to play	    */
					      20,	/* ptime.	    */
					      0,	/* flags	    */
					      0,	/* default buffer   */
					      &file_port/* returned port    */
					      );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to use WAV file", status);
	return 1;
    }

    /* Create sound player port. */
    status = pjmedia_snd_port_create_player( 
		 pool,				    /* pool		    */
		 -1,				    /* use default dev.	    */
		 file_port->info.clock_rate,	    /* clock rate.	    */
		 file_port->info.channel_count,	    /* # of channels.	    */
		 file_port->info.samples_per_frame, /* samples per frame.   */
		 file_port->info.bits_per_sample,   /* bits per sample.	    */
		 0,				    /* options		    */
		 &snd_port			    /* returned port	    */
		 );
    if (status != PJ_SUCCESS) {
	app_perror(THIS_FILE, "Unable to open sound device", status);
	return 1;
    }

    /* Connect file port to the sound player.
     * Stream playing will commence immediately.
     */
    status = pjmedia_snd_port_connect( snd_port, file_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);



    /* 
     * File should be playing and looping now, using sound device's thread. 
     */


    /* Sleep to allow log messages to flush */
    pj_thread_sleep(100);


    printf("Playing %s..\n", argv[1]);
    puts("");
    puts("Press <ENTER> to stop playing and quit");

    if (fgets(tmp, sizeof(tmp), stdin) == NULL) {
	puts("EOF while reading stdin, will quit now..");
    }

    
    /* Start deinitialization: */

    /* Disconnect sound port from file port */
    status = pjmedia_snd_port_disconnect(snd_port);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    /* Without this sleep, Windows/DirectSound will repeteadly
     * play the last frame during destroy.
     */
    pj_thread_sleep(100);

    /* Destroy sound device */
    status = pjmedia_snd_port_destroy( snd_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Destroy file port */
    status = pjmedia_port_destroy( file_port );
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);


    /* Release application pool */
    pj_pool_release( pool );

    /* Destroy media endpoint. */
    pjmedia_endpt_destroy( med_endpt );

    /* Destroy pool factory */
    pj_caching_pool_destroy( &cp );

    /* Shutdown PJLIB */
    pj_shutdown();


    /* Done. */
    return 0;
}
Example #29
0
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;
}
Example #30
0
/*
 * 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;
}