diff -u -p linux/net/bluetooth/af_bluetooth.j2.c linux/net/bluetooth/af_bluetooth.c --- linux/net/bluetooth/af_bluetooth.j2.c Wed Feb 4 18:51:55 2004 +++ linux/net/bluetooth/af_bluetooth.c Wed Feb 4 19:09:15 2004 @@ -200,6 +200,30 @@ struct sock *bt_accept_dequeue(struct so return NULL; } +static int bt_accept_checkqueue(struct sock *parent) +{ + struct list_head *p, *n; + struct sock *sk; + int num = 0; + + BT_DBG("parent %p", parent); + + /* Check the number of connected sockets. This is used in poll + * to know if the socket can really perform an accept. + * Jean II */ + list_for_each_safe(p, n, &bt_sk(parent)->accept_q) { + sk = (struct sock *) list_entry(p, struct bt_sock, accept_q); + + /* No need to lock, reading/writing ints is atomic and we + * don't need to synchronise. Jean II */ + if (sk->sk_state == BT_CONNECTED) + num++; + } + printk(KERN_DEBUG "J2 - %s - parent %p backlog %d num %d\n", + __FUNCTION__, parent, parent->sk_ack_backlog, num); + return num; +} + int bt_sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags) { @@ -252,15 +276,23 @@ unsigned int bt_sock_poll(struct file * if (sk->sk_shutdown == SHUTDOWN_MASK) mask |= POLLHUP; + /* Check is we can read() (== received packet) or + * if we can accept() (== incomming connection) or + * if the socket died. Jean II */ if (!skb_queue_empty(&sk->sk_receive_queue) || - !list_empty(&bt_sk(sk)->accept_q) || + (!list_empty(&bt_sk(sk)->accept_q) && + bt_accept_checkqueue(sk) > 0) || (sk->sk_shutdown & RCV_SHUTDOWN)) mask |= POLLIN | POLLRDNORM; if (sk->sk_state == BT_CLOSED) mask |= POLLHUP; - if (sk->sk_state == BT_CONNECT || sk->sk_state == BT_CONNECT2) + /* Socket can't be writeable if it's not yet connected, check + * l2cap_sock_sendmsg() for details. Jean II */ + if (sk->sk_state == BT_CONNECT || + sk->sk_state == BT_CONNECT2 || + sk->sk_state == BT_CONFIG) return mask; if (sock_writeable(sk))