首页 > 其他 > 详细

网络子系统85_sock事件通知进程

时间:2014-03-01 05:43:43      阅读:399      评论:0      收藏:0      [点我收藏+]
//	socket初始化
//	调用路径:inet_create->sock_init_data
1.1 void sock_init_data(struct socket *sock, struct sock *sk)
{
	...
	//sock状态改变的回调函数,当sock的状态变迁(如从established到close_wait)就会调用这个函数
	sk->sk_state_change	=	sock_def_wakeup;
	//sock有输入数据的时被调用
	sk->sk_data_ready	=	sock_def_readable;
	//sock有可写空间时被调用
	sk->sk_write_space	=	sock_def_write_space;
	//sock出错(如收到一个rst)会被调
	sk->sk_error_report	=	sock_def_error_report;
	sk->sk_destruct		=	sock_def_destruct;
	...
}


//	唤醒sock上阻塞的进程
//	步骤:
//		1.检查struct sock->sk_wq上是否有阻塞的进程
//			1.2 唤醒struct sock->sk_wq上的进程
2.1 static void sock_def_wakeup(struct sock *sk)
{
	struct socket_wq *wq;

	rcu_read_lock();
	wq = rcu_dereference(sk->sk_wq);
	if (wq_has_sleeper(wq))
		wake_up_interruptible_all(&wq->wait);
	rcu_read_unlock();
}


//	有可用输入数据
//	调用路径:raw_local_deliver->sock_def_readable
//	步骤:
//		1.检查struct sock->sk_wq上是否有阻塞的进程
//			1.1 唤醒struct sock->sk_wq上的进程
//		2.唤醒在用户空间设置了信号io的进程
2.2 static void sock_def_readable(struct sock *sk, int len)
{
	struct socket_wq *wq;

	rcu_read_lock();
	//sock的wait_queue
	wq = rcu_dereference(sk->sk_wq);
	//唤醒在wait_queue上等待可用数据的进程
	if (wq_has_sleeper(wq))
		wake_up_interruptible_sync_poll(&wq->wait, POLLIN | POLLPRI |
						POLLRDNORM | POLLRDBAND);
	//处理O_ASYNC
	sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
	rcu_read_unlock();
}

//	有可用输出空间
//	步骤:
//		1.判断是否有足够可用内存
//			1.1 空闲内存量 >= 50%
//		2.唤醒在wait_queue上等待可用内存的进程
//		3.处理信号io
2.3 static void sock_def_write_space(struct sock *sk)
{
	struct socket_wq *wq;

	rcu_read_lock();

	//判断是否有足够内存
	//	可用内存>=50%
	if ((atomic_read(&sk->sk_wmem_alloc) << 1) <= sk->sk_sndbuf) {
		wq = rcu_dereference(sk->sk_wq);
		//唤醒wait_queue上的进程
		if (wq_has_sleeper(wq))
			wake_up_interruptible_sync_poll(&wq->wait, POLLOUT |
						POLLWRNORM | POLLWRBAND);
		//处理信号io
		if (sock_writeable(sk))
			sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT);
	}

	rcu_read_unlock();
}

//	sock发生错误
//		1. 检查sock上是否有进程在阻塞
//			1.1 唤醒进程有错误发生
//		2. 处理信号io
2.4 static void sock_def_error_report(struct sock *sk)
{
	struct socket_wq *wq;

	rcu_read_lock();
	wq = rcu_dereference(sk->sk_wq);
	if (wq_has_sleeper(wq))
		wake_up_interruptible_poll(&wq->wait, POLLERR);
	sk_wake_async(sk, SOCK_WAKE_IO, POLL_ERR);
	rcu_read_unlock();
}

网络子系统85_sock事件通知进程,布布扣,bubuko.com

网络子系统85_sock事件通知进程

原文:http://blog.csdn.net/nerdx/article/details/20127985

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!