Exemplo n.º 1
0
static void print_timing( const char *msg ){
	#define MS_DELTA (1000.0)
	#define SS_DELTA (MS_DELTA * 1000.0)
	#define MM_DELTA (SS_DELTA * 60.0)
	#define HH_DELTA (MM_DELTA * 60.0)

	double ticks = get_uticks() - prev_uticks;

	if( ticks < MS_DELTA ){
	   printf( "%s\t : %lf us\n", msg, ticks );
	}
	else if( ticks < SS_DELTA ){
	   printf( "%s\t : %lf ms\n", msg, ticks / MS_DELTA );
	}
	else if( ticks < MM_DELTA ){
	   printf( "%s\t : %lf s\n", msg, ticks / SS_DELTA );
	}
	else if( ticks < HH_DELTA ){
	   printf( "%s\t : %lf m\n", msg, ticks / MM_DELTA );
	}
	else{
	   printf( "%s\t : %lf h\n", msg, ticks / HH_DELTA );
	}

	start_timer();
}
Exemplo n.º 2
0
/* similar to set_timer, except it allows only one-time
   timer setting and all later attempts are ignored */
void set_1timer( struct timer_link *new_tl, enum lists list_id,
												utime_t* ext_timeout )
{
	utime_t timeout;
	struct timer* list;


	if (list_id>=NR_OF_TIMER_LISTS) {
		LM_CRIT("unknown list: %d\n", list_id);
#ifdef EXTRA_DEBUG
		abort();
#endif
		return;
	}

	if (!ext_timeout) {
		timeout = timer_id2timeout[ list_id ];
	} else {
		timeout = *ext_timeout;
	}

	list= &(timertable[new_tl->set].timers[ list_id ]);

	lock(list->mutex);
	if (!new_tl->time_out) {
		insert_timer_unsafe( list, new_tl, timeout +
			((timer_id2type[list_id]==UTIME_TYPE)?get_uticks():get_ticks()));
	}
	unlock(list->mutex);
}
Exemplo n.º 3
0
static int async_usleep(struct sip_msg* msg, async_ctx *ctx, int *useconds)
{
	struct itimerspec its;
	int fd;

	LM_DBG("sleep %d useconds\n", *(unsigned int *)useconds);

	/* create the timer fd */
	if ( (fd=timerfd_create( CLOCK_REALTIME, 0))<0 ) {
		LM_ERR("failed to create new timer FD (%d) <%s>\n",
			errno, strerror(errno));
		return -1;
	}

	/* set the time */
	its.it_value.tv_sec = (*(unsigned int *)useconds / 1000000);
	its.it_value.tv_nsec = (*(unsigned int *)useconds % 1000000) * 1000;
	its.it_interval.tv_sec = 0;
	its.it_interval.tv_nsec = 0;
	if (timerfd_settime( fd, 0, &its, NULL)<0) {
		LM_ERR("failed to set timer FD (%d) <%s>\n",
			errno, strerror(errno));
		return -1;
	}

	/* start the async wait */
	ctx->resume_param = (void*)(unsigned long)
		(((unsigned long)-1) & (get_uticks()+*(unsigned int *)useconds));
	ctx->resume_f = resume_async_sleep;
	async_status = fd;

	return 1;
}
Exemplo n.º 4
0
int resume_async_sleep(int fd, struct sip_msg *msg, void *param)
{
	unsigned long now = (unsigned long)
		(((unsigned long)-1) & get_uticks());

	/* apply a sync correction if (for whatever reasons) the sleep
	 * did not cover the whole interval so far */
	if ( ((unsigned long)param) > (now+UTIMER_TICK) )
		sleep_us((unsigned int)((unsigned long)param - now));

	close (fd);
	async_status = ASYNC_DONE;

	return 1;
}
Exemplo n.º 5
0
/* determine timer length and put on a correct timer list
 * WARNING: - don't try to use it to "move" a timer from one list
 *            to another, you'll run into races
 *          - reset_timer; set_timer might not work, a reset'ed timer
 *             has no set_timer guarantee, it might be lost;
 *             same for an expired timer: only it's handler can
 *             set it again, an external set_timer has no guarantee
 */
void set_timer( struct timer_link *new_tl, enum lists list_id,
												utime_t* ext_timeout )
{
	utime_t timeout;
	struct timer* list;

	if (list_id>=NR_OF_TIMER_LISTS) {
		LM_CRIT("unknown list: %d\n", list_id);
#ifdef EXTRA_DEBUG
		abort();
#endif
		return;
	}

	if (!ext_timeout) {
		timeout = timer_id2timeout[ list_id ];
	} else {
		timeout = *ext_timeout;
	}
	LM_DBG("relative timeout is %lld\n",timeout);

	list= &(timertable[new_tl->set].timers[ list_id ]);

	lock(list->mutex);
	/* check first if we are on the "detached" timer_routine list,
	 * if so do nothing, the timer is not valid anymore
	 * (side effect: reset_timer ; set_timer is not safe, a reseted timer
	 *  might be lost, depending on this race condition ) */
	if (new_tl->timer_list==DETACHED_LIST){
		LM_CRIT("set_timer for %d list called on a \"detached\" "
			"timer -- ignoring: %p\n", list_id, new_tl);
		goto end;
	}
	/* make sure I'm not already on a list */
	remove_timer_unsafe( new_tl );

	insert_timer_unsafe( list, new_tl, timeout +
			((timer_id2type[list_id]==UTIME_TYPE)?get_uticks():get_ticks()));
end:
	unlock(list->mutex);
}
Exemplo n.º 6
0
str* client_new(client_info_t* ci,b2b_notify_t b2b_cback,
		b2b_add_dlginfo_t add_dlginfo, str* param)
{
	int result;
	b2b_dlg_t* dlg;
	unsigned int hash_index;
	str* callid = NULL;
	int size;
	str ehdr = {0, 0};
	str* b2b_key_shm = NULL;
	dlg_t td;
	str from_tag;
	str random_info = {0, 0};

	if(ci == NULL || b2b_cback == NULL || param== NULL)
	{
		LM_ERR("Wrong parameters.\n");
		return NULL;
	}
	if(param && param->len > B2BL_MAX_KEY_LEN)
	{
		LM_ERR("parameter too long, received [%d], maximum [%d]\n",
				param->len, B2BL_MAX_KEY_LEN);
		return 0;
	}

	hash_index = core_hash(&ci->from_uri, &ci->to_uri, client_hsize);

	if(ci->from_tag)
		from_tag = *ci->from_tag;
	else
		generate_tag(&from_tag, &ci->from_uri, ci->extra_headers);

	/* create a dummy b2b dialog structure to be inserted in the hash table*/
	size = sizeof(b2b_dlg_t) + ci->to_uri.len + ci->from_uri.len
		+ ci->from_dname.len + ci->to_dname.len +
		from_tag.len + ci->local_contact.len + B2B_MAX_KEY_SIZE + B2BL_MAX_KEY_LEN;

	/* create record in hash table */
	dlg = (b2b_dlg_t*)shm_malloc(size);
	if(dlg == NULL)
	{
		LM_ERR("No more shared memory\n");
		return 0;
	}
	memset(dlg, 0, size);
	size = sizeof(b2b_dlg_t);

	CONT_COPY(dlg, dlg->from_uri, ci->from_uri);
	CONT_COPY(dlg, dlg->to_uri, ci->to_uri);
	if(ci->to_dname.s)
		CONT_COPY(dlg, dlg->to_dname, ci->to_dname);
	if(ci->from_dname.s)
		CONT_COPY(dlg, dlg->from_dname, ci->from_dname);
	CONT_COPY(dlg, dlg->tag[CALLER_LEG], from_tag);
	CONT_COPY(dlg, dlg->contact[CALLER_LEG], ci->local_contact);

	if(param && param->s)
	{
		dlg->param.s = (char*)dlg + size;
		memcpy(dlg->param.s, param->s, param->len);
		dlg->param.len = param->len;
		size+= B2BL_MAX_KEY_LEN;
	}
	dlg->b2b_cback = b2b_cback;
	dlg->add_dlginfo = add_dlginfo;
	if(parse_method(ci->method.s, ci->method.s+ci->method.len, &dlg->last_method)< 0)
	{
		LM_ERR("wrong method %.*s\n", ci->method.len, ci->method.s);
		shm_free(dlg);
		goto error;
	}
	dlg->state = B2B_NEW;
	dlg->cseq[CALLER_LEG] =(ci->cseq?ci->cseq:1);
	dlg->send_sock = ci->send_sock;

	/* if the callid should be the same in more instances running at the same time (replication)*/
	if(!replication_mode)
	{
		srand(get_uticks());
		random_info.s = int2str(rand(), &random_info.len);
	}

	dlg->send_sock = ci->send_sock;
	dlg->id = core_hash(&from_tag, random_info.s?&random_info:0, HASH_SIZE);

	/* callid must have the special format */
	dlg->db_flag = NO_UPDATEDB_FLAG;
	callid = b2b_htable_insert(client_htable, dlg, hash_index, B2B_CLIENT, 0);
	if(callid == NULL)
	{
		LM_ERR("Inserting new record in hash table failed\n");
		shm_free(dlg);
		goto error;
	}

	if(b2breq_complete_ehdr(ci->extra_headers, &ehdr, ci->body,
				&ci->local_contact)< 0)
	{
		LM_ERR("Failed to complete extra headers\n");
		goto error;
	}

	/* copy the key in shared memory to transmit it as a parameter to the tm callback */
	b2b_key_shm = b2b_key_copy_shm(callid);
	if(b2b_key_shm== NULL)
	{
		LM_ERR("no more shared memory\n");
		goto error;
	}
	CONT_COPY(dlg, dlg->callid, (*callid));

	/* create the tm dialog structure with the a costum callid */
	memset(&td, 0, sizeof(dlg_t));
	td.loc_seq.value = dlg->cseq[CALLER_LEG];
	dlg->last_invite_cseq = dlg->cseq[CALLER_LEG];
	td.loc_seq.is_set = 1;

	td.id.call_id = *callid;
	td.id.loc_tag = from_tag;
	td.id.rem_tag.s = 0;
	td.id.rem_tag.len = 0;

	td.rem_uri = ci->to_uri;
	if(ci->req_uri.s)
		td.rem_target    = ci->req_uri;
	else
		td.rem_target    = ci->to_uri;
	if(td.rem_target.s[0] == '<')
	{
		td.rem_target.s++;
		td.rem_target.len-=2;
	}

	td.rem_dname  = ci->to_dname;

	td.loc_uri    = ci->from_uri;
	td.loc_dname  = ci->from_dname;

	td.state= DLG_CONFIRMED;
	td.T_flags=T_NO_AUTOACK_FLAG|T_PASS_PROVISIONAL_FLAG ;

	td.send_sock = ci->send_sock;

	if(ci->dst_uri.len)
		td.obp = ci->dst_uri;

	td.avps = ci->avps;

	tmb.setlocalTholder(&dlg->uac_tran);

	/* send request */
	result= tmb.t_request_within
		(&ci->method,          /* method*/
		&ehdr,                 /* extra headers*/
		ci->body,              /* body*/
		&td,                   /* dialog structure*/
		b2b_client_tm_cback,   /* callback function*/
		b2b_key_shm,
		shm_free_param);       /* function to release the parameter*/

	if(td.route_set)
		pkg_free(td.route_set);
	if(result< 0)
	{
		LM_ERR("while sending request with t_request\n");
		pkg_free(callid);
		shm_free(b2b_key_shm);
		return NULL;
	}
	tmb.setlocalTholder(NULL);

	LM_DBG("new client entity [%p] callid=[%.*s] tag=[%.*s] param=[%.*s]"
			" last method=[%d] dlg->uac_tran=[%p]\n",
			dlg, callid->len, callid->s,
			dlg->tag[CALLER_LEG].len, dlg->tag[CALLER_LEG].s,
			dlg->param.len, dlg->param.s, dlg->last_method, dlg->uac_tran);

	return callid;

error:
	if(callid)
		pkg_free(callid);
	return NULL;
}
Exemplo n.º 7
0
static void start_timer(){
	prev_uticks = get_uticks();
}