Socket和Sock之间同步机制
基于linux-2.6.18-400.el5内核代码整理应用层和内核层报文任务的通告同步机制。
改造同步机制需要先理清现有的机制,覆盖各个同步场景。
通告接口
sock使用以下接口在不同情况下,通告应用层用层socket:
/* 在sock_init_data函数中进程初始化,函数在socket()过程中被调用 */
sk->sk_state_change = sock_def_wakeup;
sk->sk_data_ready = sock_def_readable;
sk->sk_write_space = sock_def_write_space;
sk->sk_error_report = sock_def_error_report;
sk->sk_destruct = sock_def_destruct;
以sock_def_readable函数为例,该接口唤醒睡眠在sk->sk_sleep等待队列,调用等待在其上的任务回调,根据回调处理返回结果进行任务唤醒或继续阻塞等待:
static void sock_def_readable(struct sock *sk, int len)
{
read_lock(&sk->sk_callback_lock);
if (sk_has_sleeper(sk))
wake_up_interruptible(sk->sk_sleep);
sk_wake_async(sk,1,POLL_IN);
read_unlock(&sk->sk_callback_lock);
}
sk->sk_sleep成员指向socket的wait成员,在服务器端监听sock进行连接accept时,执行sock_graft函数:
static inline void sock_graft(struct sock *sk, struct socket *parent)
{
write_lock_bh(&sk->sk_callback_lock);
/* parent 是代表客户端连接的socket实例,sk是代表客户端连接的sock实例 */
sk->sk_sleep = &parent->wait;
parent->sk = sk;
sk->sk_socket = parent;
security_sock_graft(sk, parent);
write_unlock_bh(&sk->sk_callback_lock);
}
函数sk_wake_async 调用sock_wake_async,根据实际情况判断选择是否通过信号(SIGIO/