diff -ur linux-2.3.12-ref/include/linux/sched.h linux-2.3.12-accept/include/linux/sched.h --- linux-2.3.12-ref/include/linux/sched.h Wed Aug 4 15:40:54 1999 +++ linux-2.3.12-accept/include/linux/sched.h Fri Aug 6 11:14:28 1999 @@ -478,6 +478,8 @@ #define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE) #define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE) +#define wake_one(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE | TASK_EXCLUSIVE) +#define wake_one_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE | TASK_EXCLUSIVE) extern int in_group_p(gid_t); @@ -686,16 +688,6 @@ wq_write_lock_irqsave(&q->lock, flags); __add_wait_queue(q, wait); - wq_write_unlock_irqrestore(&q->lock, flags); -} - -extern inline void add_wait_queue_exclusive(wait_queue_head_t *q, - wait_queue_t * wait) -{ - unsigned long flags; - - wq_write_lock_irqsave(&q->lock, flags); - __add_wait_queue_tail(q, wait); wq_write_unlock_irqrestore(&q->lock, flags); } diff -ur linux-2.3.12-ref/include/linux/wait.h linux-2.3.12-accept/include/linux/wait.h --- linux-2.3.12-ref/include/linux/wait.h Wed Aug 4 15:38:39 1999 +++ linux-2.3.12-accept/include/linux/wait.h Fri Aug 6 11:15:28 1999 @@ -169,23 +169,6 @@ list_add(&new->task_list, &head->task_list); } -/* - * Used for wake-one threads: - */ -extern inline void __add_wait_queue_tail(wait_queue_head_t *head, - wait_queue_t *new) -{ -#if WAITQUEUE_DEBUG - if (!head || !new) - WQ_BUG(); - CHECK_MAGIC_WQHEAD(head); - CHECK_MAGIC(new->__magic); - if (!head->task_list.next || !head->task_list.prev) - WQ_BUG(); -#endif - list_add(&new->task_list, head->task_list.prev); -} - extern inline void __remove_wait_queue(wait_queue_head_t *head, wait_queue_t *old) { diff -ur linux-2.3.12-ref/include/net/tcp.h linux-2.3.12-accept/include/net/tcp.h --- linux-2.3.12-ref/include/net/tcp.h Wed Aug 4 15:40:27 1999 +++ linux-2.3.12-accept/include/net/tcp.h Fri Aug 6 13:45:12 1999 @@ -483,6 +483,8 @@ extern struct sock * tcp_accept(struct sock *sk, int flags); extern unsigned int tcp_poll(struct file * file, struct socket *sock, struct poll_table_struct *wait); extern void tcp_write_space(struct sock *sk); +extern void tcp_wakeup(struct sock *sk); +extern void tcp_data_ready(struct sock *sk, int len); extern int tcp_getsockopt(struct sock *sk, int level, int optname, char *optval, diff -ur linux-2.3.12-ref/kernel/sched.c linux-2.3.12-accept/kernel/sched.c --- linux-2.3.12-ref/kernel/sched.c Wed Aug 4 15:40:54 1999 +++ linux-2.3.12-accept/kernel/sched.c Fri Aug 6 11:16:50 1999 @@ -857,15 +857,7 @@ wq_write_lock_irqsave(&q->lock, flags); -#if WAITQUEUE_DEBUG - CHECK_MAGIC_WQHEAD(q); -#endif - head = &q->task_list; -#if WAITQUEUE_DEBUG - if (!head->next || !head->prev) - WQ_BUG(); -#endif tmp = head->next; while (tmp != head) { unsigned int state; @@ -873,17 +865,11 @@ tmp = tmp->next; -#if WAITQUEUE_DEBUG - CHECK_MAGIC(curr->__magic); -#endif p = curr->task; state = p->state; if (state & mode) { -#if WAITQUEUE_DEBUG - curr->__waker = (long)__builtin_return_address(0); -#endif wake_up_process(p); - if (state & TASK_EXCLUSIVE) + if (TASK_EXCLUSIVE & mode) break; } } diff -ur linux-2.3.12-ref/net/core/sock.c linux-2.3.12-accept/net/core/sock.c --- linux-2.3.12-ref/net/core/sock.c Wed Aug 4 15:38:39 1999 +++ linux-2.3.12-accept/net/core/sock.c Fri Aug 6 13:06:29 1999 @@ -742,9 +742,9 @@ if(sk->lock.users != 0) { DECLARE_WAITQUEUE(wait, current); - add_wait_queue_exclusive(&sk->lock.wq, &wait); + add_wait_queue(&sk->lock.wq, &wait); for(;;) { - current->state = TASK_EXCLUSIVE | TASK_UNINTERRUPTIBLE; + current->state = TASK_UNINTERRUPTIBLE; spin_unlock_bh(&sk->lock.slock); schedule(); spin_lock_bh(&sk->lock.slock); diff -ur linux-2.3.12-ref/net/ipv4/tcp.c linux-2.3.12-accept/net/ipv4/tcp.c --- linux-2.3.12-ref/net/ipv4/tcp.c Wed Aug 4 15:40:33 1999 +++ linux-2.3.12-accept/net/ipv4/tcp.c Fri Aug 6 13:48:43 1999 @@ -614,12 +614,31 @@ if (sk->dead) return; - wake_up_interruptible(sk->sleep); + wake_one_interruptible(sk->sleep); if (sock_wspace(sk) >= tcp_min_write_space(sk)) sock_wake_async(sk->socket, 2); } +/* + * Socket state_change callback. + */ +void tcp_wakeup(struct sock *sk) +{ + if(!sk->dead) + wake_one_interruptible(sk->sleep); +} + +/* + * Socket data_ready callback. + */ +void tcp_data_ready(struct sock *sk, int len) +{ + if(!sk->dead) { + wake_one_interruptible(sk->sleep); + sock_wake_async(sk->socket,1); + } +} int tcp_ioctl(struct sock *sk, int cmd, unsigned long arg) { @@ -1582,18 +1601,10 @@ * one process gets woken up, not the 'whole herd'. * Since we do not 'race & poll' for established sockets * anymore, the common case will execute the loop only once. - * - * Subtle issue: "add_wait_queue_exclusive()" will be added - * after any current non-exclusive waiters, and we know that - * it will always _stay_ after any new non-exclusive waiters - * because all non-exclusive waiters are added at the - * beginning of the wait-queue. As such, it's ok to "drop" - * our exclusiveness temporarily when we get woken up without - * having to remove and re-insert us on the wait queue. */ - add_wait_queue_exclusive(sk->sleep, &wait); + add_wait_queue(sk->sleep, &wait); for (;;) { - current->state = TASK_EXCLUSIVE | TASK_INTERRUPTIBLE; + current->state = TASK_INTERRUPTIBLE; release_sock(sk); schedule(); lock_sock(sk); diff -ur linux-2.3.12-ref/net/ipv4/tcp_ipv4.c linux-2.3.12-accept/net/ipv4/tcp_ipv4.c --- linux-2.3.12-ref/net/ipv4/tcp_ipv4.c Wed Aug 4 15:40:55 1999 +++ linux-2.3.12-accept/net/ipv4/tcp_ipv4.c Fri Aug 6 13:49:09 1999 @@ -1355,6 +1355,8 @@ newsk->backlog.head = newsk->backlog.tail = NULL; skb_queue_head_init(&newsk->error_queue); newsk->write_space = tcp_write_space; + newsk->state_change = tcp_wakeup; + newsk->data_ready = tcp_data_ready; #ifdef CONFIG_FILTER if ((filter = newsk->filter) != NULL) sk_filter_charge(newsk, filter); @@ -1940,6 +1942,8 @@ tp->rcv_mss = 536; sk->write_space = tcp_write_space; + sk->state_change = tcp_wakeup; + sk->data_ready = tcp_data_ready; /* Init SYN queue. */ tcp_synq_init(tp); diff -ur linux-2.3.12-ref/net/netsyms.c linux-2.3.12-accept/net/netsyms.c --- linux-2.3.12-ref/net/netsyms.c Wed Aug 4 15:40:35 1999 +++ linux-2.3.12-accept/net/netsyms.c Fri Aug 6 13:48:16 1999 @@ -296,6 +296,8 @@ EXPORT_SYMBOL(tcp_write_wakeup); EXPORT_SYMBOL(tcp_read_wakeup); EXPORT_SYMBOL(tcp_write_space); +EXPORT_SYMBOL(tcp_wakeup); +EXPORT_SYMBOL(tcp_data_ready); EXPORT_SYMBOL(tcp_poll); EXPORT_SYMBOL(tcp_ioctl); EXPORT_SYMBOL(tcp_shutdown);