sem_t 信号量致使 两个doubango应用(idoubs)接收注册消息不正常.

最近在研究sip相关的一些东西,单个idoubs在iphone上能够正常运行,可是同时运行两个的话,会有一个注册不到服务器,抓包跟了很久都不知道是什么问题,例如如今有两个idoubs在iphone上,,暂且命名为idoubs1和idoubs2吧.它们两个是分别链接到不一样的服务,接收的端口也是不同的. 服务器

若是我先运行idoubs1,正常链接以后,再开启idoubs2,这时idoubs2却链接不上服务器了.实际上idoubs2有发了注册消息给服务器.服务器也返回了消息给idoubs2.可是sip层中用于接收sip消息的函数 iphone

static int tsip_transport_layer_stream_cb(const tnet_transport_event_t* e)却没有响应,接着,我只能把断点设到udp层的recvfrom()函数里面,调试了不少次发现设在recvfrom()函数前面的断点没有停,弄了很久也不知道什么缘由,觉得不是用recvfrom()来接收udp消息的,但那又不可能呀..后来把工程cleanup一遍,recvfrom()前的断点终于停下来了,把收到的消息打印出来,发现程序是收到了消息的.关键是在把消息传到sip层的时候出了问题. 函数

     接着发了在static int tsip_transport_layer_stream_cb(const tnet_transport_event_t* e)这个函数所回调的地方,有个宏定义的信号量,这个宏定义有点奇怪. spa

#define TSK_RUNNABLE_RUN_BEGIN(self) \
	TSK_RUNNABLE(self)->running = tsk_true;	\
	for(;;) { \
		tsk_semaphore_decrement(TSK_RUNNABLE(self)->semaphore); \
		if(!TSK_RUNNABLE(self)->running &&  \
			(!TSK_RUNNABLE(self)->important || (TSK_RUNNABLE(self)->important && TSK_LIST_IS_EMPTY(TSK_RUNNABLE(self)->objects)))) \
			break;
		

#define TSK_RUNNABLE_RUN_END(self) \
	} \
	TSK_RUNNABLE(self)->running = tsk_false;
两个宏, ,,其实就是把一段代码拆分到两个宏定义里面,而后回调函数就是在两个宏之间:

TSK_RUNNABLE_RUN_BEGIN(transport);
	
	if((curr = TSK_RUNNABLE_POP_FIRST_SAFE(TSK_RUNNABLE(transport)))){
		const tnet_transport_event_t *e = (const tnet_transport_event_t*)curr->data;
		
		if(transport->callback){
			transport->callback(e);
		}
		tsk_object_unref(curr);
	}
	
	TSK_RUNNABLE_RUN_END(transport);
注意到第一个宏里面的
tsk_semaphore_decrement()
原来doubango里面udp层和sip层之间是用sem_t信号量来通讯的.由于信号量是能够实现进程间通讯的,忽然间明白为何idoubs2的收不到sip消息了,若是信号量的标识符是同样的话,那idoubs2的消息有可能发到idoubs1那里去了,,

接着再去查信号量的初始化 调试

找到了这个函数 code

tsk_semaphore_handle_t* tsk_semaphore_create_2(int initial_val) 进程

tsk_semaphore_handle_t* tsk_semaphore_create_2(int initial_val)
{
	SEMAPHORE_T handle = tsk_null;
	
#if TSK_UNDER_WINDOWS
	handle = CreateSemaphore(NULL, initial_val, 0x7FFFFFFF, NULL);
#else
	handle = tsk_calloc(1, sizeof(SEMAPHORE_S));
	
#if TSK_USE_NAMED_SEM
	named_sem_t * nsem = (named_sem_t*)handle;
	tsk_sprintf(&(nsem->name), "/sem-%d", sem_count++);
	if((nsem->sem = sem_open(nsem->name, O_CREAT /*| O_EXCL*/, S_IRUSR | S_IWUSR, initial_val)) == SEM_FAILED)
	{
		TSK_FREE(nsem->name);
#else
	if(sem_init((SEMAPHORE_T)handle, 0, initial_val))
	{
#endif
		TSK_FREE(handle);
		TSK_DEBUG_ERROR("Failed to initialize the new semaphore (errno=%d).", errno);
	}
#endif
	
	if(!handle){
		TSK_DEBUG_ERROR("Failed to create new semaphore");
	}
	return handle;
}
查了一下资料,,定位到

tsk_sprintf(&(nsem->name), "/sem-%d", sem_count++);
只要把"/sem-%d" 改为不同就好了.."/1sem-%d"..


问题就终于解决啦.. ip

相关文章
相关标签/搜索