Chinaunix首页 | 论坛 | 博客
  • 博客访问: 131854
  • 博文数量: 12
  • 博客积分: 1616
  • 博客等级: 上尉
  • 技术积分: 206
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-18 13:38
文章分类
文章存档

2013年(3)

2012年(9)

我的朋友

分类: LINUX

2012-06-11 16:05:24

通过上一篇分析,可以判断出do_monitor线程死锁的地方,并给出了两个临时解决办法:

1.如果发生死锁,将当前的事件抛弃掉,不予处理。
2.如果将要发生死锁,并且消息是CLF、CCL、RSC等事件,可以将chan的bridged进行hangup。等通道线程从write中返回后,会立即挂断当前通话的两个channel。
经过上午的测试,可以看出使用方法2有效的解决这个问题。
问题的根本解决应该还是要追查关于write的问题,这个需要对驱动中关于write的处理进行分析,作为下一步要做的事情之一吧。
另外一个话题-----关于MTP层的日志和抓包
在chan_ss7中对于MTP层的日志进行了特殊处理,不是简单使用ast_log的方式,而是通过receivedbuf进行中转了一把。先将log通过fifo_log的方式将日志作为一种特殊的事件提交到receivedbuf中,再在do_monitor线程中取出event,进行log记录。
在chan_ss7中也提供了MTP2层的数据抓包,并且可以在CLI里通过ss7 dump start 的形式进行开启抓包。抓包的处理过程与log类似,也是通过receivedbuf来完成的。
可以看出,在chan_ss7代码中,为了避免死锁问题,作者已经用了多种方式来规避这个问题,receivedbuf就是一个例子。关于receivedbuf是提供了一段缓冲区存放从mtp层接收到需要处理的event。这段缓冲区是在初始化的时候就分配好的,运行过程中不会动态增加,这就是作为一个典型的生产者-消费者的概念。receivedbuf就是一个盘子。event就是盘子里的食物。
receivedbuf是一个lffifo结构,看这个结构的定义:
struct lffifo {
int size;
int start;
int end;
unsigned char buf[0];
};
接收到的event会存放到buf中,start记录存储开始位置,end记录存储结束位置,size记录buf大小。在lffifo.c中提供了对buf的访问方式,封装的较好,功能包括put、get等。




阅读(2592) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~