lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [bug #19157] lwip_close problems


From: Frédéric BERNON
Subject: [lwip-devel] [bug #19157] lwip_close problems
Date: Mon, 26 Feb 2007 20:40:02 +0000
User-agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.1.2) Gecko/20070219 Firefox/2.0.0.2

URL:
  <http://savannah.nongnu.org/bugs/?19157>

                 Summary: lwip_close problems
                 Project: lwIP - A Lightweight TCP/IP stack
            Submitted by: fbernon
            Submitted on: lundi 26.02.2007 à 20:40
                Category: sockets
                Severity: 3 - Normal
              Item Group: Faulty Behaviour
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any

    _______________________________________________________

Details:

First, in lwip_close, I think that last sock_set_errno have to be set BEFORE
sys_sem_signal like this :
 
   sock->lastdata   = NULL;
   sock->lastoffset = 0;
   sock->conn       = NULL;
   sock_set_errno(sock, 0);
   sys_sem_signal(socksem);
 
Because with the "original" code :

   sys_sem_signal(socksem);
   sock_set_errno(sock, 0);

If between this two calls, if another thread (with higher priority) reopen
and use the same socket, and got an error, it will be masked by the
sock_set_errno.

Second, closing TCP sockets which just send data cause the data to be purged.
the "old" bug was already signals, but none of the fix are really correct. The
only solution seems to poll the unacked and unsent lists until they're empty,
until an error, or until a timeout. To handle this polling timeout, I use my
own sysarch.c function (there is no really same function in sys.h).

extern u32_t sys_start_tickcount ();
extern u32_t sys_stop_tickcount  ( u32_t tickcount);


//...
#define CLOSE_TIMEOUT 2000
//...
int
lwip_close(int s)
{
  struct lwip_socket *sock;
  u32_t  tickcount;

  LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s));

  sock = get_socket(s);
  if (!sock) {
      set_errno(EBADF);
      return -1;
  }

  if (sock->conn->type==NETCONN_TCP)
   { tickcount = sys_start_tickcount();  
     while (((sock->conn->pcb.tcp->unacked!=NULL) ||
(sock->conn->pcb.tcp->unsent!=NULL)) && (sock->conn->err==ERR_OK) &&
(sys_stop_tickcount(tickcount)<CLOSE_TIMEOUT))
      { sys_sleep(1);
      }
   }
   
  sys_sem_wait(socksem);
  netconn_close(sock->conn);//FB really usefull?
  
  netconn_delete(sock->conn);
  if (sock->lastdata) {
    netbuf_delete(sock->lastdata);
  }
  sock->lastdata   = NULL;
  sock->lastoffset = 0;
  sock->conn       = NULL;
  sock_set_errno(sock, 0);
  sys_sem_signal(socksem);
  return 0;
}

I think that code would have to be in netconn layer...





    _______________________________________________________

Reply to this item at:

  <http://savannah.nongnu.org/bugs/?19157>

_______________________________________________
  Message posté via/par Savannah
  http://savannah.nongnu.org/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]