Blame view
net/core/stream.c
5.11 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 8 9 10 11 |
/* * SUCS NET3: * * Generic stream handling routines. These are generic for most * protocols. Even IP. Tonight 8-). * This is used because TCP, LLC (others too) layer all have mostly * identical sendmsg() and recvmsg() code. * So we (will) share it here. * * Authors: Arnaldo Carvalho de Melo <acme@conectiva.com.br> * (from old tcp.c code) |
113aa838e net: Rationalise ... |
12 |
* Alan Cox <alan@lxorguk.ukuu.org.uk> (Borrowed comments 8-)) |
1da177e4c Linux-2.6.12-rc2 |
13 14 15 16 17 18 19 20 21 22 23 |
*/ #include <linux/module.h> #include <linux/net.h> #include <linux/signal.h> #include <linux/tcp.h> #include <linux/wait.h> #include <net/sock.h> /** * sk_stream_write_space - stream socket write_space callback. |
4dc3b16ba [PATCH] DocBook: ... |
24 |
* @sk: socket |
1da177e4c Linux-2.6.12-rc2 |
25 26 27 28 29 30 |
* * FIXME: write proper description */ void sk_stream_write_space(struct sock *sk) { struct socket *sock = sk->sk_socket; |
438154823 net: sock_def_rea... |
31 |
struct socket_wq *wq; |
1da177e4c Linux-2.6.12-rc2 |
32 33 34 |
if (sk_stream_wspace(sk) >= sk_stream_min_wspace(sk) && sock) { clear_bit(SOCK_NOSPACE, &sock->flags); |
438154823 net: sock_def_rea... |
35 36 37 38 |
rcu_read_lock(); wq = rcu_dereference(sk->sk_wq); if (wq_has_sleeper(wq)) wake_up_interruptible_poll(&wq->wait, POLLOUT | |
9dc20c5f7 tcp: tcp_prequeue... |
39 |
POLLWRNORM | POLLWRBAND); |
438154823 net: sock_def_rea... |
40 |
if (wq && wq->fasync_list && !(sk->sk_shutdown & SEND_SHUTDOWN)) |
8d8ad9d7c [NET]: Name magic... |
41 |
sock_wake_async(sock, SOCK_WAKE_SPACE, POLL_OUT); |
438154823 net: sock_def_rea... |
42 |
rcu_read_unlock(); |
1da177e4c Linux-2.6.12-rc2 |
43 44 |
} } |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 48 |
EXPORT_SYMBOL(sk_stream_write_space); /** * sk_stream_wait_connect - Wait for a socket to get into the connected state |
4dc3b16ba [PATCH] DocBook: ... |
49 50 |
* @sk: sock to wait on * @timeo_p: for how long to wait |
1da177e4c Linux-2.6.12-rc2 |
51 52 53 54 55 56 57 |
* * Must be called with the socket locked. */ int sk_stream_wait_connect(struct sock *sk, long *timeo_p) { struct task_struct *tsk = current; DEFINE_WAIT(wait); |
6151b31c9 [NET]: Fix race c... |
58 |
int done; |
1da177e4c Linux-2.6.12-rc2 |
59 |
|
6151b31c9 [NET]: Fix race c... |
60 |
do { |
c1cbe4b7a [NET]: Avoid atom... |
61 62 63 |
int err = sock_error(sk); if (err) return err; |
1da177e4c Linux-2.6.12-rc2 |
64 65 66 67 68 69 |
if ((1 << sk->sk_state) & ~(TCPF_SYN_SENT | TCPF_SYN_RECV)) return -EPIPE; if (!*timeo_p) return -EAGAIN; if (signal_pending(tsk)) return sock_intr_errno(*timeo_p); |
aa3951451 net: sk_sleep() h... |
70 |
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1da177e4c Linux-2.6.12-rc2 |
71 |
sk->sk_write_pending++; |
6151b31c9 [NET]: Fix race c... |
72 |
done = sk_wait_event(sk, timeo_p, |
c1cbe4b7a [NET]: Avoid atom... |
73 |
!sk->sk_err && |
4ec93edb1 [NET] CORE: Fix w... |
74 |
!((1 << sk->sk_state) & |
6151b31c9 [NET]: Fix race c... |
75 |
~(TCPF_ESTABLISHED | TCPF_CLOSE_WAIT))); |
aa3951451 net: sk_sleep() h... |
76 |
finish_wait(sk_sleep(sk), &wait); |
1da177e4c Linux-2.6.12-rc2 |
77 |
sk->sk_write_pending--; |
6151b31c9 [NET]: Fix race c... |
78 |
} while (!done); |
1da177e4c Linux-2.6.12-rc2 |
79 80 |
return 0; } |
1da177e4c Linux-2.6.12-rc2 |
81 82 83 84 |
EXPORT_SYMBOL(sk_stream_wait_connect); /** * sk_stream_closing - Return 1 if we still have things to send in our buffers. |
4dc3b16ba [PATCH] DocBook: ... |
85 |
* @sk: socket to verify |
1da177e4c Linux-2.6.12-rc2 |
86 87 88 89 90 91 92 93 94 95 96 97 98 |
*/ static inline int sk_stream_closing(struct sock *sk) { return (1 << sk->sk_state) & (TCPF_FIN_WAIT1 | TCPF_CLOSING | TCPF_LAST_ACK); } void sk_stream_wait_close(struct sock *sk, long timeout) { if (timeout) { DEFINE_WAIT(wait); do { |
aa3951451 net: sk_sleep() h... |
99 |
prepare_to_wait(sk_sleep(sk), &wait, |
1da177e4c Linux-2.6.12-rc2 |
100 101 102 103 |
TASK_INTERRUPTIBLE); if (sk_wait_event(sk, &timeout, !sk_stream_closing(sk))) break; } while (!signal_pending(current) && timeout); |
aa3951451 net: sk_sleep() h... |
104 |
finish_wait(sk_sleep(sk), &wait); |
1da177e4c Linux-2.6.12-rc2 |
105 106 |
} } |
1da177e4c Linux-2.6.12-rc2 |
107 108 109 110 |
EXPORT_SYMBOL(sk_stream_wait_close); /** * sk_stream_wait_memory - Wait for more memory for a socket |
4dc3b16ba [PATCH] DocBook: ... |
111 112 |
* @sk: socket to wait for memory * @timeo_p: for how long |
1da177e4c Linux-2.6.12-rc2 |
113 114 115 116 117 118 119 120 121 122 123 124 125 |
*/ int sk_stream_wait_memory(struct sock *sk, long *timeo_p) { int err = 0; long vm_wait = 0; long current_timeo = *timeo_p; DEFINE_WAIT(wait); if (sk_stream_memory_free(sk)) current_timeo = vm_wait = (net_random() % (HZ / 5)) + 2; while (1) { set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); |
aa3951451 net: sk_sleep() h... |
126 |
prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); |
1da177e4c Linux-2.6.12-rc2 |
127 128 129 130 131 132 133 134 135 136 137 138 139 |
if (sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN)) goto do_error; if (!*timeo_p) goto do_nonblock; if (signal_pending(current)) goto do_interrupted; clear_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); if (sk_stream_memory_free(sk) && !vm_wait) break; set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); sk->sk_write_pending++; |
482964e56 net: Fix the cond... |
140 141 142 143 |
sk_wait_event(sk, ¤t_timeo, sk->sk_err || (sk->sk_shutdown & SEND_SHUTDOWN) || (sk_stream_memory_free(sk) && !vm_wait)); |
1da177e4c Linux-2.6.12-rc2 |
144 145 146 147 148 149 150 151 152 153 154 155 156 |
sk->sk_write_pending--; if (vm_wait) { vm_wait -= current_timeo; current_timeo = *timeo_p; if (current_timeo != MAX_SCHEDULE_TIMEOUT && (current_timeo -= vm_wait) < 0) current_timeo = 0; vm_wait = 0; } *timeo_p = current_timeo; } out: |
aa3951451 net: sk_sleep() h... |
157 |
finish_wait(sk_sleep(sk), &wait); |
1da177e4c Linux-2.6.12-rc2 |
158 159 160 161 162 163 164 165 166 167 168 169 |
return err; do_error: err = -EPIPE; goto out; do_nonblock: err = -EAGAIN; goto out; do_interrupted: err = sock_intr_errno(*timeo_p); goto out; } |
1da177e4c Linux-2.6.12-rc2 |
170 |
EXPORT_SYMBOL(sk_stream_wait_memory); |
1da177e4c Linux-2.6.12-rc2 |
171 172 173 174 175 176 177 178 |
int sk_stream_error(struct sock *sk, int flags, int err) { if (err == -EPIPE) err = sock_error(sk) ? : -EPIPE; if (err == -EPIPE && !(flags & MSG_NOSIGNAL)) send_sig(SIGPIPE, current, 0); return err; } |
1da177e4c Linux-2.6.12-rc2 |
179 |
EXPORT_SYMBOL(sk_stream_error); |
1da177e4c Linux-2.6.12-rc2 |
180 181 182 183 184 185 186 187 188 |
void sk_stream_kill_queues(struct sock *sk) { /* First the read buffer. */ __skb_queue_purge(&sk->sk_receive_queue); /* Next, the error queue. */ __skb_queue_purge(&sk->sk_error_queue); /* Next, the write queue. */ |
547b792ca net: convert BUG_... |
189 |
WARN_ON(!skb_queue_empty(&sk->sk_write_queue)); |
1da177e4c Linux-2.6.12-rc2 |
190 191 |
/* Account for returned memory. */ |
3ab224be6 [NET] CORE: Intro... |
192 |
sk_mem_reclaim(sk); |
1da177e4c Linux-2.6.12-rc2 |
193 |
|
547b792ca net: convert BUG_... |
194 195 |
WARN_ON(sk->sk_wmem_queued); WARN_ON(sk->sk_forward_alloc); |
1da177e4c Linux-2.6.12-rc2 |
196 197 198 199 200 201 |
/* It is _impossible_ for the backlog to contain anything * when we get here. All user references to this socket * have gone away, only the net layer knows can touch it. */ } |
1da177e4c Linux-2.6.12-rc2 |
202 |
EXPORT_SYMBOL(sk_stream_kill_queues); |