tcp connection setup的实现(三)
2009-09-10 00:00:00 来源:WEB开发网然后是reqsk_queue_get_child,他主要是从accept队列中得到一个sock:
Java代码
static inline struct sock *reqsk_queue_get_child(struct request_sock_queue *queue,
struct sock *parent)
{
///首先从accept队列中remove这个socket并返回.
struct request_sock *req = reqsk_queue_remove(queue);
///取得socket.
struct sock *child = req->sk;
WARN_ON(child == NULL);
///这里主要是将sk_ack_backlog减一,也就是accept当前的数目减一.
sk_acceptq_removed(parent);
__reqsk_free(req);
return child;
}
这里还有一个inet_csk_wait_for_connect,它是用来在accept队列为空的情况下,休眠掉一段时间 (这里每个socket都有一个等待队列的(等待队列的用法请google,我这里就不阐述了).这里是每个调用的进程都会声明一个wait队列,然后将它连接到主的socket的等待队列链表中,然后休眠,等到唤醒.
Java代码
static int inet_csk_wait_for_connect(struct sock *sk, long timeo)
{
struct inet_connection_sock *icsk = inet_csk(sk);
///定义一个waitqueue.
DEFINE_WAIT(wait);
int err;
..................................................
for (;;) {
///这里也就是把当前的进程的等待队列挂入sk中的sk_sleep队列,sk也就是主的那个socket.
prepare_to_wait_exclusive(sk->sk_sleep, &wait,
TASK_INTERRUPTIBLE);
release_sock(sk);
///再次判断是否为空.
if (reqsk_queue_empty(&icsk->icsk_accept_queue))
///这个函数里面会休眠timeo时间(调用schedule让出cpu),或者被当accept队列有数据时唤醒(我们前面也有介绍这个)主的等待队列链表.,
timeo = schedule_timeout(timeo);
lock_sock(sk);
err = 0;
///非空则跳出.
if (!reqsk_queue_empty(&icsk->icsk_accept_queue))
break;
err = -EINVAL;
if (sk->sk_state != TCP_LISTEN)
break;
err = sock_intr_errno(timeo);
if (signal_pending(current))
break;
///设置错误号.
err = -EAGAIN;
///时间为0则直接退出.
if (!timeo)
break;
}
///这里也就会从sk_sleep中remove掉当前的wait队列.
finish_wait(sk->sk_sleep, &wait);
return err;
}
Tags:tcp connection setup
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接