信号等待函数中的done 部分代码 逻辑应该可以优化 , 这部分的代码最终的目的就是找到符合接收到的信号的节点,然后将节点从线程链表中删除,并上传。
一个pre 指针 加上一个current指针应该就可以完成该功能。
源码中的逻辑似乎有些绕。
__done:
/* to get the first matched pending signals */
/*捕获到信号,则遍历信号链表,找到对应的节点*/
/*while 最终的目的 就是找到信号对应的节点 ,将该节点从链表中删除
*此处代码写的比较复杂,
*/
si_node = (struct siginfo_node *)tid->si_list;
while (si_node)
{
int signo;
signo = si_node->si.si_signo;
if (sig_mask(signo) & *set)
{
*si = si_node->si;
LOG_D("sigwait: %d sig raised!", signo);
/*si_prev 为NULL 代表是遍历杠开始第一个节点*/
if (si_prev)
si_prev->list.next = si_node->list.next;
else
{
struct siginfo_node *node_next;
/*如果线程重信号链表里面有多个节点且第一个节点就是捕获信号对应的节点,
*则将捕获到信号的这个节点从链表中移除并上传,线程信号链表头后移一个
*/
if (si_node->list.next)
{
node_next = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
tid->si_list = node_next;
}
else
{
tid->si_list = RT_NULL;
}
}
/* clear pending */
tid->sig_pending &= ~sig_mask(signo);
rt_mp_free(si_node);
break;
}
// 记录当前这个节点
si_prev = si_node;
/*将si_node 指向下一个节点*/
if (si_node->list.next)
{
si_node = (void *)rt_slist_entry(si_node->list.next, struct siginfo_node, list);
}
else
{
si_node = RT_NULL;
}
}