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

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

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

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)这个函数所回调的地方,有个宏定义的信号量,这个宏定义有点奇怪.

#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那里去了,,

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

找到了这个函数

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"..


问题就终于解决啦..


你可能感兴趣的:(信号量,SIP,doubango,idoubs)