Local sockets: Remove some ill-conceived logic

This commit is contained in:
Gregory Nutt 2015-01-27 07:03:20 -06:00
parent 5e39788489
commit 1f7b40ce15
4 changed files with 28 additions and 71 deletions

View File

@ -76,16 +76,34 @@ enum local_state_s
LOCAL_STATE_UNBOUND = 0, /* Created by socket, but not bound */
LOCAL_STATE_BOUND, /* Bound to an path */
/* SOCK_STREAM only */
/* SOCK_STREAM server only */
LOCAL_STATE_LISTENING, /* Server listening for connections */
LOCAL_STATE_CLOSED, /* Server closed, no longer connecting */
/* SOCK_STREAM peers only */
LOCAL_STATE_ACCEPT, /* Client waiting for a connection */
LOCAL_STATE_CONNECTED, /* Peer connected */
LOCAL_STATE_DISCONNECTED /* Peer disconnected */
};
/* Representation of a local connection */
/* Representation of a local connection. There are four types of
* connection structures:
*
* 1. Server. A SOCK_STREAM that only listens for and accepts
* connections from server.
* 2. Client. A SOCK_STREAM peer that connects via the server.
* 3. Peer. A connected SOCK_STREAM that sends() and recvs() packets.
* May either be the client that connect with the server of the
* new peer connect generated with the connection was accepted by
* the server.
*
* And
*
* 4. Connectionless. Like a peer but using a connectionless datagram
* style of communication. SOCK_DRAM support has not yet been
* implemented.
*/
struct local_conn_s
{
@ -121,14 +139,12 @@ struct local_conn_s
uint8_t lc_pending; /* Number of pending connections */
uint8_t lc_backlog; /* Maximum number of pending connections */
dq_queue_t lc_waiters; /* List of connections waiting to be accepted */
dq_queue_t lc_conns; /* List of connections */
} server;
/* Fields unique to the connecting client side */
struct
{
FAR struct local_conn_s *lc_server; /* Server connection */
volatile int lc_result; /* Result of the connection operation */
} client;
} u;

View File

@ -176,10 +176,6 @@ int psock_local_accept(FAR struct socket *psock, FAR struct sockaddr *addr,
{
DEBUGASSERT(conn->lc_infd >= 0);
/* Add the waiting connection to list of clients */
dq_addlast(&client->lc_node, &server->u.server.lc_conns);
/* Return the address family */
if (addr)

View File

@ -248,7 +248,6 @@ int local_connect(FAR struct local_conn_s *client,
*/
if (conn->lc_state == LOCAL_STATE_UNBOUND ||
conn->lc_state == LOCAL_STATE_CLOSED ||
conn->lc_family != client->lc_family ||
conn->lc_type != client->lc_type)
{

View File

@ -74,48 +74,20 @@ int local_release(FAR struct local_conn_s *conn)
DEBUGASSERT(conn->lc_crefs == 0);
state = net_lock();
/* We should not bet here with states LOCAL_STATE_CLOSED or with
* LOCAL_STATE_ACCEPT. Those are internal states that should be atomic
* with respect to socket operations.
/* We should not bet here with state LOCAL_STATE_ACCEPT. That is an
* internal state that should be atomic with respect to socket operations.
*/
DEBUGASSERT(conn->lc_state != LOCAL_STATE_CLOSED &&
conn->lc_state != LOCAL_STATE_ACCEPT);
DEBUGASSERT(conn->lc_state != LOCAL_STATE_ACCEPT);
/* If the socket is connected (SOCK_STREAM client), then disconnect it */
if (conn->lc_state == LOCAL_STATE_CONNECTED ||
conn->lc_state == LOCAL_STATE_DISCONNECTED)
{
FAR struct local_conn_s *server;
DEBUGASSERT(conn->lc_family == SOCK_STREAM);
server = conn->u.client.lc_server;
DEBUGASSERT(server &&
(server->lc_state == LOCAL_STATE_LISTENING ||
server->lc_state == LOCAL_STATE_CLOSED) &&
!dq_empty(&server->u.server.lc_conns));
/* Remove ourself from the list of connections */
dq_rem(&conn->lc_node, &server->u.server.lc_conns);
/* Is the list of pending connections now empty? Was the connection
* already closed?
*/
if (dq_empty(&server->u.server.lc_waiters) &&
server->lc_state == LOCAL_STATE_CLOSED)
{
/* Yes, free the server connection as well */
local_free(server);
}
/* Now we can free this connection structure */
local_free(conn);
/* Just free the connection structure */
}
/* Is the socket is listening socket (SOCK_STREAM server) */
@ -123,7 +95,6 @@ int local_release(FAR struct local_conn_s *conn)
else if (conn->lc_state == LOCAL_STATE_LISTENING)
{
FAR struct local_conn_s *client;
FAR struct local_conn_s *next;
DEBUGASSERT(conn->lc_family == SOCK_STREAM);
@ -135,47 +106,22 @@ int local_release(FAR struct local_conn_s *conn)
{
client->u.client.lc_result = -ENOTCONN;
sem_post(&client->lc_waitsem);
conn->lc_state = LOCAL_STATE_CLOSED;
}
conn->u.server.lc_pending = 0;
/* Disconnect any previous client connections */
for (client = (FAR struct local_conn_s *)conn->u.server.lc_conns.head;
client;
client = next)
{
next = (FAR struct local_conn_s *)dq_next(&client->lc_node);
dq_rem(&client->lc_node, &conn->u.server.lc_conns);
client->lc_state = LOCAL_STATE_DISCONNECTED;
}
/* Remove the server from the list of listeners */
/* Remove the server from the list of listeners. */
dq_rem(&conn->lc_node, &g_local_listeners);
/* Can we free the connection structure now? We cannot
* if there are still pending connection requested to
* be resolved.
*/
conn->u.server.lc_backlog = 0;
if (conn->lc_state == LOCAL_STATE_CLOSED)
{
local_free(conn);
}
}
/* For the remaining states (LOCAL_STATE_UNBOUND and LOCAL_STATE_UNBOUND),
* we simply free the connection structure.
*/
else
{
local_free(conn);
}
/* Free the connection structure */
local_free(conn);
net_unlock(state);
return OK;
}