From 28ac0618357cd777265cff69fc7ec196b7ec51de Mon Sep 17 00:00:00 2001 From: patacongo Date: Wed, 16 Sep 2009 20:29:00 +0000 Subject: Sockets were not being closed when a task exits git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2070 42af7a65-404d-4744-a932-0658087f49c3 --- nuttx/net/net_close.c | 32 ++++++++++++++++++++++++++------ nuttx/net/net_internal.h | 5 +++++ nuttx/net/net_sockets.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 69 insertions(+), 14 deletions(-) (limited to 'nuttx/net') diff --git a/nuttx/net/net_close.c b/nuttx/net/net_close.c index 6dc160aca..02e648a8a 100644 --- a/nuttx/net/net_close.c +++ b/nuttx/net/net_close.c @@ -199,13 +199,13 @@ static inline void netclose_disconnect(FAR struct socket *psock) ****************************************************************************/ /**************************************************************************** - * Function: net_close + * Function: net_closesocket * * Description: - * Performs the close operation on socket descriptors + * Performs the close operation on asocket instance * * Parameters: - * sockfd Socket descriptor of socket + * psock Socket instance * * Returned Value: * 0 on success; -1 on error with errno set appropriately. @@ -214,9 +214,8 @@ static inline void netclose_disconnect(FAR struct socket *psock) * ****************************************************************************/ -int net_close(int sockfd) +int net_closesocket(FAR struct socket *psock) { - FAR struct socket *psock = sockfd_socket(sockfd); int err; /* Verify that the sockfd corresponds to valid, allocated socket */ @@ -298,7 +297,7 @@ int net_close(int sockfd) /* Then release our reference on the socket structure containing the connection */ - sockfd_release(sockfd); + sock_release(psock); return OK; errout: @@ -306,4 +305,25 @@ errout: return ERROR; } +/**************************************************************************** + * Function: net_close + * + * Description: + * Performs the close operation on socket descriptors + * + * Parameters: + * sockfd Socket descriptor of socket + * + * Returned Value: + * 0 on success; -1 on error with errno set appropriately. + * + * Assumptions: + * + ****************************************************************************/ + +int net_close(int sockfd) +{ + return net_closesocket(sockfd_socket(sockfd)); +} + #endif /* CONFIG_NET */ diff --git a/nuttx/net/net_internal.h b/nuttx/net/net_internal.h index a4b1fe4dd..c66f808e4 100644 --- a/nuttx/net/net_internal.h +++ b/nuttx/net/net_internal.h @@ -148,9 +148,14 @@ extern "C" { /* net_sockets.c *************************************************************/ EXTERN int sockfd_allocate(int minsd); +EXTERN void sock_release(FAR struct socket *psock); EXTERN void sockfd_release(int sockfd); EXTERN FAR struct socket *sockfd_socket(int sockfd); +/* net_close.c ***************************************************************/ + +EXTERN int net_closesocket(FAR struct socket *psock); + /* sockopt support ***********************************************************/ #if defined(CONFIG_NET_SOCKOPTS) && !defined(CONFIG_DISABLE_CLOCK) diff --git a/nuttx/net/net_sockets.c b/nuttx/net/net_sockets.c index 3db69519d..60141808a 100644 --- a/nuttx/net/net_sockets.c +++ b/nuttx/net/net_sockets.c @@ -161,6 +161,8 @@ int net_addreflist(FAR struct socketlist *list) int net_releaselist(FAR struct socketlist *list) { int crefs; + int ndx; + if (list) { /* Decrement the reference count on the list. @@ -182,12 +184,29 @@ int net_releaselist(FAR struct socketlist *list) */ if (crefs <= 0) - { + { + /* Close each open socket in the list + * REVISIT: net_closesocket() will attempt to use semaphores. + * If we actually are in the IDLE thread, then could this cause + * problems? Probably not, it the task has exited and crefs is + * zero, then there probably could not be a contender for the + * semaphore. + */ + + for (ndx = 0; ndx < CONFIG_NSOCKET_DESCRIPTORS; ndx++) + { + FAR struct socket *psock = &list->sl_sockets[ndx]; + if (psock->s_crefs > 0) + { + (void)net_closesocket(psock); + } + } + /* Destroy the semaphore and release the filelist */ (void)sem_destroy(&list->sl_sem); sched_free(list); - } + } } return OK; } @@ -226,14 +245,11 @@ int sockfd_allocate(int minsd) return ERROR; } -void sockfd_release(int sockfd) +void sock_release(FAR struct socket *psock) { - FAR struct socket *psock; - - /* Get the socket structure for this sockfd */ - - psock = sockfd_socket(sockfd); +#if CONFIG_DEBUG if (psock) +#endif { /* Take the list semaphore so that there will be no accesses * to this socket structure. @@ -262,6 +278,20 @@ void sockfd_release(int sockfd) } } +void sockfd_release(int sockfd) +{ + /* Get the socket structure for this sockfd */ + + FAR struct socket *psock = sockfd_socket(sockfd); + + /* Get the socket structure for this sockfd */ + + if (psock) + { + sock_release(psock); + } +} + FAR struct socket *sockfd_socket(int sockfd) { FAR struct socketlist *list; -- cgit v1.2.3