[En-Nut-Discussion] NutTcpAccept blocks the tread

Nathan Moore nategoose at gmail.com
Thu Oct 22 16:54:09 CEST 2009


Hey Henrik,
I think there's a window of time where the port won't be listened to if this
is done the way I imagined it.  This time
window's size increases as the system is busier.
In my annotations to the code below I refer to the thread that this code is
running in as "this thread".

>
>    for (;;)
>    {
>        sock = NutTcpCreateSocket();
>        while (NutTcpAccept(sock, myPort) == 0) ...
>
This thread sleeps on an event within the call to NutTcpAccept.
The time out happens so the thread is moved to the run queue behind all
other threads which share the same priority.
The network interface's RX thread is run (before this thread) and finds a
SYN packet for myPort waiting, and tries to
find a TCP socket for it, but none are in the Accepting state.  The packet
is discarded.  The network interface's RX
thread sleeps on it's event.
This thread is run and returns from NutTcpAccept.

>        {
>           threadStillAlive++;
>           if (settingsHaveChanged())
>           {
>              myPort = settings.port;
>           }
>        }
>        threadStillAlive++;
>        stream = _fdopen((int) sock, "r+b");
>        processsRequest(stream);
>        fclose(stream);
>        NutTcpCloseSocket(sock);
>    }
>
> As NutTcpAccept is called again after the time-out I would assume this
> would
> have no side-effect on connect attempts as long as the socket value stays
> the same. Is this assumption correct?
>
>
I may have misunderstood the way your way works and you may have accounted
for this via the second of the ideas
I had while writing this.

The first was to have a callback function and argument pointer that would be
called upon socket listen timeout.  This
callback's return value would specify what action would happen (rewait or
unlisten-return).  This is not pretty.

My second idea was to have the wakeup of "this thread" happen before
changing the state of the socket to closed.
Then when "this thread" is run code within NutTcpAccept
(NutTcpPassiveOpenEvent, actually) will:
  1. examine the state of the socket and decide if this is strictly a
timeout.
     (note:  if the timeout happens at the same time as an incoming SYN this
would give preference to the SYN)
  2. If it is strictly timeout it would asyncronously change the socket's
state to closed and return a value to let the
      caller know that a timeout has happened.
This way if "this thread" doesn't sleep before it calls NutTcpAccept again
there can be no moment where a network
interface's RX thread is running while the socket is not listening.

This second method probably overlooks something, so most likely more would
need to be done than what I have
stated, but it seems easier than a callback/argument pair being kept up
with.


Nathan



More information about the En-Nut-Discussion mailing list