diff options
author | Neal H. Walfield <neal@gnu.org> | 2005-08-29 08:29:35 +0000 |
---|---|---|
committer | Neal H. Walfield <neal@gnu.org> | 2005-08-29 08:29:35 +0000 |
commit | 1e5a9b2969616b26f7b0e5808e3281c611146fdc (patch) | |
tree | b25425f7d78970fbc36697f89152513fd2e43b1f /pflocal/socket.c | |
parent | 5c3011ee1de9a9b231270044ea52649f84cdac66 (diff) | |
download | hurd-1e5a9b2969616b26f7b0e5808e3281c611146fdc.tar.gz hurd-1e5a9b2969616b26f7b0e5808e3281c611146fdc.tar.bz2 hurd-1e5a9b2969616b26f7b0e5808e3281c611146fdc.zip |
pflocal/
2005-05-17 Neal H. Walfield <neal@gnu.org>
* connq.h (struct connq_request): Remove forward.
(connq_listen): Wait for a request to be queued not until there is
a connection attempt. Remove REQ parameter. Update callers.
(connq_request_complete): Remove declaration.
(connq_connect): Wait for a slot to queue a request not until
there is an acceptor. Remove SOCK parameter. Update callers.
(connq_connect_complete): New declaration.
(connq_connect_cancel): New declaration.
* connq.c (struct connq): Remove fields noqueue, queue, length,
head and tail. Add fields head, tail, count, max, connectors and
num_connectors. That is, replace the circular buffer with a
singly linked list.
(qnext): Remove function.
(struct connq_request): Remove field signal, lock, completed and
err. Add field next.
(connq_request_init): Rewrite according to new semantics.
(connq_request_enqueue): New function.
(connq_request_dequeue): New function.
(connq_create): Update according to new semantics.
(connq_destroy): Likewise.
(connq_listen): Rewrite to not block until there is a connector
but until there is a request in the queue.
(connq_request_complete): Remove function.
(connq_connect): Rewrite to not block until there is an acceptor
but until there is space for a request.
(connq_connect_complete): New function.
(connq_connect_cancel): New function.
(connq_compress): Remove dead code.
(connq_set_length): Rewrite.
* socket.c (S_socket_connect): Create the server socket here...
(S_socket_accept): ... not here.
Diffstat (limited to 'pflocal/socket.c')
-rw-r--r-- | pflocal/socket.c | 74 |
1 files changed, 38 insertions, 36 deletions
diff --git a/pflocal/socket.c b/pflocal/socket.c index 0bc72066..1cf78657 100644 --- a/pflocal/socket.c +++ b/pflocal/socket.c @@ -1,6 +1,6 @@ /* Socket-specific operations - Copyright (C) 1995 Free Software Foundation, Inc. + Copyright (C) 1995, 2005 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> @@ -110,7 +110,7 @@ S_socket_connect (struct sock_user *user, struct addr *addr) else if (sock->flags & SOCK_CONNECTED) /* SOCK_CONNECTED is only set for connection-oriented sockets, which can only ever connect once. [If we didn't do this test - here, it would eventually fail when it the listening socket + here, it would eventually fail when the listening socket tried to accept our connection request.] */ err = EISCONN; else @@ -118,16 +118,35 @@ S_socket_connect (struct sock_user *user, struct addr *addr) /* Assert that we're trying to connect, so anyone else trying to do so will fail with EALREADY. */ sock->connect_queue = cq; - mutex_unlock (&sock->lock); /* Unlock SOCK while waiting. */ + /* Unlock SOCK while waiting. */ + mutex_unlock (&sock->lock); - /* Try to connect. */ - err = connq_connect (cq, sock->flags & SOCK_NONBLOCK, sock); + err = connq_connect (peer->listen_queue, + sock->flags & SOCK_NONBLOCK); + if (!err) + { + struct sock *server; + + err = sock_clone (peer, &server); + if (!err) + { + err = sock_connect (sock, server); + if (!err) + connq_connect_complete (peer->listen_queue, server); + else + sock_free (server); + } - /* We can safely set CONNECT_QUEUE to NULL, as no one else can + mutex_lock (&sock->lock); + if (err) + connq_connect_cancel (peer->listen_queue); + } + + /* We must set CONNECT_QUEUE to NULL, as no one else can set it until we've done so. */ - mutex_lock (&sock->lock); sock->connect_queue = NULL; } + mutex_unlock (&sock->lock); } else @@ -157,42 +176,25 @@ S_socket_accept (struct sock_user *user, err = ensure_connq (sock); if (!err) { - struct connq_request *req; struct sock *peer_sock; - err = - connq_listen (sock->listen_queue, sock->flags & SOCK_NONBLOCK, - &req, &peer_sock); + err = connq_listen (sock->listen_queue, sock->flags & SOCK_NONBLOCK, + &peer_sock); if (!err) { - struct sock *conn_sock; - - err = sock_clone (sock, &conn_sock); + struct addr *peer_addr; + *port_type = MACH_MSG_TYPE_MAKE_SEND; + err = sock_create_port (peer_sock, port); + if (!err) + err = sock_get_addr (peer_sock, &peer_addr); if (!err) { - err = sock_connect (conn_sock, peer_sock); - if (!err) - { - struct addr *peer_addr; - *port_type = MACH_MSG_TYPE_MAKE_SEND; - err = sock_create_port (conn_sock, port); - if (!err) - err = sock_get_addr (peer_sock, &peer_addr); - if (!err) - { - *peer_addr_port = ports_get_right (peer_addr); - *peer_addr_port_type = MACH_MSG_TYPE_MAKE_SEND; - ports_port_deref (peer_addr); - } - else - /* TEAR DOWN THE CONNECTION XXX */; - } - if (err) - sock_free (conn_sock); + *peer_addr_port = ports_get_right (peer_addr); + *peer_addr_port_type = MACH_MSG_TYPE_MAKE_SEND; + ports_port_deref (peer_addr); } - - /* Communicate any error (or success) to the connecting thread. */ - connq_request_complete (req, err); + else + /* TEAR DOWN THE CONNECTION XXX */; } } |