NutTcpAccept blocks the tread

View: New views
20 Messages — Rating Filter:   Alert me  
< Prev | 1 - 2 | Next >

NutTcpAccept blocks the tread

by urbi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

I have to handel some different incomming TCP-connections in my application. So I would like to have one thread that controls (sequently) all the incoming connactions.

The function NutTcpAccept() is blocking the calling thread, so I have to spend for each connection his own thread. In this way I have a lot of unnecessary taskswitches and I block unnecessary Memory.

Is there an other way (not blocking) for waiting for a connection (with an Error-Message "no actual connection")?

thank you for any help, Urban

Re: NutTcpAccept blocks the tread

by Ole Reinhardt-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello!

> The function NutTcpAccept() is blocking the calling thread, so I have to
> spend for each connection his own thread. In this way I have a lot of
> unnecessary taskswitches and I block unnecessary Memory.
> Is there an other way (not blocking) for waiting for a connection (with an
> Error-Message "no actual connection")?

No, not directly. NutTcpAccept calls NutTcpStatePassiveOpenEvent, an
internal function of the tcp state machine, which sets the socket into
the listen state and then waits for an event on the sock->so_pc_tq event
queue.

This functions waits infinit. So your application will block at this
point until the socket gets connected.

I don't have enough deep knowledge of the tcp state machine, but
would'nt it be possible to add a timeout parameter to NutTcpAccept which
will be passed to the NutEventWait?

Bye,

Ole

--
 _____________________________________________________________
|                                                             |
| Embedded-IT                                                 |
|                                                             |
| Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
| Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
| 57076 Siegen         eMail:    ole.reinhardt@... |
| Germany              Web:         http://www.embedded-it.de |
|_____________________________________________________________|

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Henrik Maier-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi all,

I proposed quite some time ago to make NutTcpAccept time-out. I think I
recommended to make NutTcpAccept to honour the receive time-out. Harald was
concerned to change the behaviour of NutTcpAccept back then and proposed a
separate time-out parameter instead. However that proposal never got
implemented in the core as for most applications the current blocking
behaviour is suitable.

I actually created a private patch of NutTcpAccept for my applications to
use the receive time-out.
 
Henrik

> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Ole Reinhardt
> Sent: Tuesday, 20 October 2009 2:01 AM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] NutTcpAccept blocks the tread
>
> Hello!
>
> > The function NutTcpAccept() is blocking the calling thread, so I have to
> > spend for each connection his own thread. In this way I have a lot of
> > unnecessary taskswitches and I block unnecessary Memory.
> > Is there an other way (not blocking) for waiting for a connection (with
an

> > Error-Message "no actual connection")?
>
> No, not directly. NutTcpAccept calls NutTcpStatePassiveOpenEvent, an
> internal function of the tcp state machine, which sets the socket into
> the listen state and then waits for an event on the sock->so_pc_tq event
> queue.
>
> This functions waits infinit. So your application will block at this
> point until the socket gets connected.
>
> I don't have enough deep knowledge of the tcp state machine, but
> would'nt it be possible to add a timeout parameter to NutTcpAccept which
> will be passed to the NutEventWait?
>
> Bye,
>
> Ole
>
> --
>  _____________________________________________________________
> |                                                             |
> | Embedded-IT                                                 |
> |                                                             |
> | Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
> | Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
> | 57076 Siegen         eMail:    ole.reinhardt@... |
> | Germany              Web:         http://www.embedded-it.de |
> |_____________________________________________________________|
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Ole Reinhardt-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Henrik

> I proposed quite some time ago to make NutTcpAccept time-out. I think I
> recommended to make NutTcpAccept to honour the receive time-out. Harald was
> concerned to change the behaviour of NutTcpAccept back then and proposed a
> separate time-out parameter instead. However that proposal never got
> implemented in the core as for most applications the current blocking
> behaviour is suitable.

Might this patch be interesting to include in the main code? Perhaps we
should review it and include it?

Bye,

Ole

--
 _____________________________________________________________
|                                                             |
| Embedded-IT                                                 |
|                                                             |
| Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
| Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
| 57076 Siegen         eMail:    ole.reinhardt@... |
| Germany              Web:         http://www.embedded-it.de |
|_____________________________________________________________|

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Henrik Maier-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Ole,

> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Ole Reinhardt
> Sent: Tuesday, 20 October 2009 8:29 PM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] NutTcpAccept blocks the tread
>
> Might this patch be interesting to include in the main code? Perhaps we
> should review it and include it?

It is a very simple patch. Here is my post "NutTcpAccept() time-out
proposal" with the patch from March 2006:

"NutTcpAccept() does currently not honour any socket time-outs. It might be
useful for applications to perform some error management in case no server
connects within a given time.

I propose to change tcpsm.c so NutTcpAccept honours the read time-out.
In NutTcpStatePassiveOpenEvent change:

     NutEventWait(&sock->so_pc_tq, 0);
     return 0;

to:
     return NutEventWait(&sock->so_pc_tq, sock->so_read_to);
"

There has been a lot of discussion about this topic already in 2006. Refer
to these discussion threads:

http://lists.egnite.de/pipermail/en-nut-discussion/2006-March/006272.html
http://lists.egnite.de/pipermail/en-nut-discussion/2006-July/006745.html

Harald finally agreed to this implementation:

http://lists.egnite.de/pipermail/en-nut-discussion/2006-July/006829.html

But I never got around to implement it that way and to put it into the CVS.

Regards

Henrik





_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Henrik,

Henrik Maier wrote:

> I propose to change tcpsm.c so NutTcpAccept honours the read time-out.
> In NutTcpStatePassiveOpenEvent change:
>
>      NutEventWait(&sock->so_pc_tq, 0);
>      return 0;
>
> to:
>      return NutEventWait(&sock->so_pc_tq, sock->so_read_to);

...

> Harald finally agreed to this implementation:
>
> http://lists.egnite.de/pipermail/en-nut-discussion/2006-July/006829.html

I'm now confused by my own comments on this as it looks like I confirmed
 using special socket options. In fact I'd prefer to use the existing
SO_RCVTIMEO. Adding SO_ACCTIMEO and SO_CONNTIMEO would require 2
additional long values in the socket structure.

So, the patch given above exactly reflects my preference regarding the API.

Hoooooweeeever, after looking into this in more detail: Are you aware
that this would leave the socket in listening state? The next call to
NutTcpAccept will fail, because

    if (sock->so_state != TCPS_CLOSED)
        return (sock->so_last_error = EISCONN);

Furthermore, the function doc says

 return 0 if granted, error code otherwise.

but NutEventWait() will return -1 on time out.

IMHO, NutTcpAccept and NutTcpConnect are comparable to open. If it
fails, the status of the handle is still CLOSED.

May be there are even more difficulties with NutTcpConnect aka
NutTcpStateActiveOpenEvent. OK, different story. Let's handle the server
side first!

If we put the socket back to TCPS_CLOSED after time out, then any
connection attempt will be rejected until NutTcpAccept is called again.

Is that what you want? Probably not, but I'm not sure.

Harald


_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Ole Reinhardt-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Harald

> So, the patch given above exactly reflects my preference regarding the API.

Yes, I would agree too, as one could change the socket timeout later
again (when it is successfully opened)

> Hoooooweeeever, after looking into this in more detail: Are you aware
> that this would leave the socket in listening state? The next call to
> NutTcpAccept will fail, because

Right. I was afraid that this would become a problem when I first
thought about this issue without deeper knowledge of the internal tcp
state machine.


>     if (sock->so_state != TCPS_CLOSED)
>         return (sock->so_last_error = EISCONN);
>
> Furthermore, the function doc says
>
>  return 0 if granted, error code otherwise.
>
> but NutEventWait() will return -1 on time out.
> IMHO, NutTcpAccept and NutTcpConnect are comparable to open. If it
> fails, the status of the handle is still CLOSED.

Posix accept will return -1 in case of an error, the socket descriptor
otherwise. If an error occurs errno is set appropriate.

So perhaps we should implement it in the same way? If it fails it should
leave the socket definitely in the TCPS_CLOSED state.

> May be there are even more difficulties with NutTcpConnect aka
> NutTcpStateActiveOpenEvent. OK, different story. Let's handle the server
> side first!
>
> If we put the socket back to TCPS_CLOSED after time out, then any
> connection attempt will be rejected until NutTcpAccept is called again.
>
> Is that what you want? Probably not, but I'm not sure.

If I correctly understand Urbi he is searching for a posix accept like
solution where you just create one socket, put it in listening state
(listen) and then create a new file descriptor to the new connected
socket with accept where you then can read / write to. In this case you
can start a thread when you got a new connection and leave the main
thread in listening state...

If we don't want to rework the socket api totaly your solutions seems to
be what I would expect from it... (connections will be rejected as long
as NutTcpAccept() is not running.

But even if it's lot of work it might be reasonable to implement a posix
like socket api? This would allow us to use the same api calls for
different socket types (which might be implemented in the future). And
at least to listen on a port for multiple connections without starting
multiple threads.

Unfortunately my knowledge about the TCP statemachine internals are
quite limited so I can't estimate how much work this would be.

Bye,

Ole

--
 _____________________________________________________________
|                                                             |
| Embedded-IT                                                 |
|                                                             |
| Ole Reinhardt        Tel. / Fax:        +49 (0)271  7420433 |
| Luisenstraße 29      Mobil:             +49 (0)177  7420433 |
| 57076 Siegen         eMail:    ole.reinhardt@... |
| Germany              Web:         http://www.embedded-it.de |
|_____________________________________________________________|

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ole Reinhardt wrote:

> Posix accept will return -1 in case of an error, the socket descriptor
> otherwise. If an error occurs errno is set appropriate.

We are not in NutTcpAccept, but in NutTcpStatePassiveOpenEvent.
NutTcpAccept claims to return -1 in case of an error. Actually it
doesn't....


> So perhaps we should implement it in the same way? If it fails it should
> leave the socket definitely in the TCPS_CLOSED state.

Again my question then: Is that what you want on time out, rejecting
further connections? What could be the motivation for this?

I assume that this is not the desired goal, so why implement a time out
then at all?


> If I correctly understand Urbi he is searching for a posix accept like
> solution where you just create one socket, put it in listening state
> (listen) and then create a new file descriptor to the new connected
> socket with accept where you then can read / write to. In this case you
> can start a thread when you got a new connection and leave the main
> thread in listening state...

Good that you direct me to the original message. Indeed, I answered to
follow-ups, but Urban was asking for something different.

While the original Liquorice source was based on callbacks, I wanted to
have file streams attached to TCP connections. This required a Berkeley
style socket interface, which I tried to mimic with what was available.
I have no idea what a Berkeley socket compatible implementation would
cost. But I assume that this would be a bigger task.

Unfortunately Urban's request wasn't that specific: "...so I have to
spend for each connection his own thread." This would be true for
Berkeley/Posix sockets as well. Btw. dynamically creating threads on
incoming connections is shown in the current app/httpd sample.

Urban, can you please specify in more detail, what you are expecting?


> If we don't want to rework the socket api totaly your solutions seems to
> be what I would expect from it... (connections will be rejected as long
> as NutTcpAccept() is not running.

Berkeley sockets do have a similar problem. If more than one connection
are coming in at the same time, they will be rejected (or ignored?) as
well. However, the listen call allows to specify a backlog, which Nut/OS
doesn't.


> But even if it's lot of work it might be reasonable to implement a posix
> like socket api? This would allow us to use the same api calls for
> different socket types (which might be implemented in the future). And
> at least to listen on a port for multiple connections without starting
> multiple threads.
>
> Unfortunately my knowledge about the TCP statemachine internals are
> quite limited so I can't estimate how much work this would be.

I doubt that will never be able to implement all the internals, because
it is based on systems with far more memory resources. We will have to
simulate certain parts. I also have no idea, how much effort this may
require. In any case I'd suggest to implement this from scratch and add
it as an alternative to the existing interface.

Does anybody have experience with the optional lwIP Berkeley socket API
or does anybody know about another TCP stack for 8-bitters, providing a
Posix like socket interface?

Harald

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Bernd Walter-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Oct 21, 2009 at 05:31:23PM +0200, Harald Kipp wrote:

> Ole Reinhardt wrote:
>
> > Posix accept will return -1 in case of an error, the socket descriptor
> > otherwise. If an error occurs errno is set appropriate.
>
> We are not in NutTcpAccept, but in NutTcpStatePassiveOpenEvent.
> NutTcpAccept claims to return -1 in case of an error. Actually it
> doesn't....
>
>
> > So perhaps we should implement it in the same way? If it fails it should
> > leave the socket definitely in the TCPS_CLOSED state.
>
> Again my question then: Is that what you want on time out, rejecting
> further connections? What could be the motivation for this?
>
> I assume that this is not the desired goal, so why implement a time out
> then at all?

One good reason for listen timeout is FTP.
Wait for a data connection - if the client won't connect within a
given time cancel the request.

> > If we don't want to rework the socket api totaly your solutions seems to
> > be what I would expect from it... (connections will be rejected as long
> > as NutTcpAccept() is not running.
>
> Berkeley sockets do have a similar problem. If more than one connection
> are coming in at the same time, they will be rejected (or ignored?) as
> well. However, the listen call allows to specify a backlog, which Nut/OS
> doesn't.

If the listen queue is full the connect is rejected.
Having a listen queue qould be nice.
Having the ability to have a single thread listen to multiple services
would be nice as well.
But I've missed those Features more when I started with Ethernut than
I do today.
I'm running SAM7X256 systems with 40+ threads and 20+ active connections.
It requires a bit of finetuning stack and socket sizes, but it runs
stable.

> Does anybody have experience with the optional lwIP Berkeley socket API
> or does anybody know about another TCP stack for 8-bitters, providing a
> Posix like socket interface?

I tried it when I started with AT91SAM7X256 using FreeRTOS.
In the end I must say that it is full of problems.
You have a listen queue, but it is missing many timeouts and memory
handling is just horror.
lwIPs socket API sounds attractive at the first though because as a
FreeBSD person I'm used to sockets, but the implementation useless to
build rugged systems.
So far I've ported all systems to Ethernut, because it was easy porting,
since I'd already used Ethernet on Mega128.
I might use lwIP again some day, because of routing and 6LoWPAN supprt,
but definitively not using the socket API.

--
B.Walter <bernd@...> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by urbi :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Ethernut wrote:
>Unfortunately Urban's request wasn't that specific: "...so I have to
>spend for each connection his own thread." This would be true for
>Berkeley/Posix sockets as well. Btw. dynamically creating threads on
>incoming connections is shown in the current app/httpd sample.

>Urban, can you please specify in more detail, what you are expecting?
Ok. I will try to explaine wath I want to have. I use only in one project an operating sytem. On other projects I am programming with event driven state machins. The synchronisation for these state machins is implemented in the main-loop. In such systems It is importend to have non blocking functions.

In this project with ethernut the application is a simple gateway from some ethernet connections to a serial connection (in both directions). So I have to implement 5 different sockets, that are listining for a TCP/IP connection, read a request from the Host, send the request forward to the uart, waiting for an answer from uart and give it back to the socket. The next request follows on an answer.
The Gateway has to handle the  different concurrent requests from each socket. So I have one thread that query each open soket for data in the read buffer and control the concurrent requests.
So reading and writing to all opened socket I have realized in one thread.

In my actual application I use for each port one thread for oppening and colsing the connection because the blocking function NutTcpAccept().
I would like to have a non blocking function NutTcpAccept() that gives me back a socket when the connection is ready otherwise an Error. So I can query sequently in one thread each port for an incomming connection and handle this connection. In an other thread (in fact thats th main-loop) I am handling sequently reading and writing the data from all sockets and the uart.

Of corse there are other ways to handle the different sockets from the gateway functions, but with one thread and a sequently handling I have a lot of synchronisation problems solved.

Urban

 



Re: NutTcpAccept blocks the tread

by Henrik Maier-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Harald,

Unfortunately I don't have the complete patch anymore, but I remember now
that I had to do more than just the time-out when I experimented with it.

I have server tasks which work on a certain TCP ports. This TCP port shall
be configurable during run-time, eg change from port 80 to 8080 or something
similar. In addition I like every thread to increase a watchdog/alive
counter for system supervision.

Both requirements can be easily met if NutTcpAccept would time-out for
example every 1000 ms. The following simplified pseudo code illustrates this
concept:

    for (;;)
    {
        sock = NutTcpCreateSocket();
        while (NutTcpAccept(sock, myPort) == 0)
        {
           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?

Regards

Henrik


> -----Original Message-----
> From: en-nut-discussion-bounces@... [mailto:en-nut-discussion-
> bounces@...] On Behalf Of Harald Kipp
> Sent: Wednesday, 21 October 2009 6:30 PM
> To: Ethernut User Chat (English)
> Subject: Re: [En-Nut-Discussion] NutTcpAccept blocks the tread
>
> Hi Henrik,
>
> Henrik Maier wrote:
>
> > I propose to change tcpsm.c so NutTcpAccept honours the read time-out.
> > In NutTcpStatePassiveOpenEvent change:
> >
> >      NutEventWait(&sock->so_pc_tq, 0);
> >      return 0;
> >
> > to:
> >      return NutEventWait(&sock->so_pc_tq, sock->so_read_to);
>
> ...
>
> > Harald finally agreed to this implementation:
> >
> > http://lists.egnite.de/pipermail/en-nut-discussion/2006-July/006829.html
>
> I'm now confused by my own comments on this as it looks like I confirmed
>  using special socket options. In fact I'd prefer to use the existing
> SO_RCVTIMEO. Adding SO_ACCTIMEO and SO_CONNTIMEO would require 2
> additional long values in the socket structure.
>
> So, the patch given above exactly reflects my preference regarding the
> API.
>
> Hoooooweeeever, after looking into this in more detail: Are you aware
> that this would leave the socket in listening state? The next call to
> NutTcpAccept will fail, because
>
>     if (sock->so_state != TCPS_CLOSED)
>         return (sock->so_last_error = EISCONN);
>
> Furthermore, the function doc says
>
>  return 0 if granted, error code otherwise.
>
> but NutEventWait() will return -1 on time out.
>
> IMHO, NutTcpAccept and NutTcpConnect are comparable to open. If it
> fails, the status of the handle is still CLOSED.
>
> May be there are even more difficulties with NutTcpConnect aka
> NutTcpStateActiveOpenEvent. OK, different story. Let's handle the server
> side first!
>
> If we put the socket back to TCPS_CLOSED after time out, then any
> connection attempt will be rejected until NutTcpAccept is called again.
>
> Is that what you want? Probably not, but I'm not sure.
>
> Harald
>
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Bernd Walter-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Wed, Oct 21, 2009 at 02:31:08PM -0700, urbi wrote:

>
>
> Ethernut wrote:
> >
> >>Unfortunately Urban's request wasn't that specific: "...so I have to
> >>spend for each connection his own thread." This would be true for
> >>Berkeley/Posix sockets as well. Btw. dynamically creating threads on
> >>incoming connections is shown in the current app/httpd sample.
> >
> >>Urban, can you please specify in more detail, what you are expecting?
> >
>
> Ok. I will try to explaine wath I want to have. I use only in one project an
> operating sytem. On other projects I am programming with event driven state
> machins. The synchronisation for these state machins is implemented in the
> main-loop. In such systems It is importend to have non blocking functions.
>
> In this project with ethernut the application is a simple gateway from some
> ethernet connections to a serial connection (in both directions). So I have
> to implement 5 different sockets, that are listining for a TCP/IP
> connection, read a request from the Host, send the request forward to the
> uart, waiting for an answer from uart and give it back to the socket. The
> next request follows on an answer.
> The Gateway has to handle the  different concurrent requests from each
> socket. So I have one thread that query each open soket for data in the read
> buffer and control the concurrent requests.
> So reading and writing to all opened socket I have realized in one thread.
>
> In my actual application I use for each port one thread for oppening and
> colsing the connection because the blocking function NutTcpAccept().
> I would like to have a non blocking function NutTcpAccept() that gives me
> back a socket when the connection is ready otherwise an Error. So I can
> query sequently in one thread each port for an incomming connection and
> handle this connection. In an other thread (in fact thats th main-loop) I am
> handling sequently reading and writing the data from all sockets and the
> uart.

You need to split NutTcpAccept in listen and accept with listen
triggering a listen queue.
This is not supported and as I understood it is difficult to implement.
But you can do something simple as a workaround.
Create a thread (*) for each port looping over NutTcpAccept.
The thread just hands over the opened socket to your processing thread
and then calls NutTcpAccept again - for safety you might also want some
bookkeeping about open sockets to have an upper limit on opened sockets.
* - you actually want two threads for each Port, since noone is listen
during the time you are handing over the socket.
This sounds very resource intensive, but in fact it isn't because you
can keept the stack size quite low.
I use 256 Bytes on AVR and 512 on ARM, which probably can even be
smaller.
Keep in mind that every open connection can receive data and likely uses
much more RAM then the stacks.

> Of corse there are other ways to handle the different sockets from the
> gateway functions, but with one thread and a sequently handling I have a lot
> of synchronisation problems solved.

I don't know your exact processing with the sockets.
Only one of your processing functions can be run at the same time.
It is not that difficult to do the same with multiple threads.
Anyway - your processing threads might need more stacksize than just
a NutTcpAccept loop so the suggestion above might save some RAM.

--
B.Walter <bernd@...> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Nathan Moore-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

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
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Parent Message unknown Re: NutTcpAccept blocks the tread

by Michael Smola :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message



----- Ursprüngliche Nachricht -----
Von: Bernd Walter <enut@...>
Gesendet: Donnerstag, 22. Oktober 2009 01:34
An: Ethernut User Chat (English) <en-nut-discussion@...>
Betreff: Re: [En-Nut-Discussion] NutTcpAccept blocks the tread

On Wed, Oct 21, 2009 at 02:31:08PM -0700, urbi wrote:

>
>
> Ethernut wrote:
> >
> >>Unfortunately Urban's request wasn't that specific: "...so I have to
> >>spend for each connection his own thread." This would be true for
> >>Berkeley/Posix sockets as well. Btw. dynamically creating threads on
> >>incoming connections is shown in the current app/httpd sample.
> >
> >>Urban, can you please specify in more detail, what you are expecting?
> >
>
> Ok. I will try to explaine wath I want to have. I use only in one project an
> operating sytem. On other projects I am programming with event driven state
> machins. The synchronisation for these state machins is implemented in the
> main-loop. In such systems It is importend to have non blocking functions
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Nathan,

Nathan Moore wrote:

> 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.

Considered, that NutTcpPassiveOpenEvent had been changed following your
suggestion, the application will use the following pseudo code:

for (;;) {
  CreateSocket();
  SocketOption(Set read timeout);
  while (NutTcpAccept()) {
    /* Timout, do something else,
    ** but do not sleep. */
  }
  /* Handle the connection. */
  ...
  /* Finally */
  DestroySocket();
}

Is that what you meant?

Harald
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

urbi wrote:

> I would like to have a non blocking function NutTcpAccept() that gives me
> back a socket when the connection is ready otherwise an Error. So I can
> query sequently in one thread each port for an incomming connection and
> handle this connection. In an other thread (in fact thats th main-loop) I am
> handling sequently reading and writing the data from all sockets and the
> uart.

Thanks Urban, now I have a clear picture.

One idea was to implement a SYN buffer, which would not immediately
reject incoming SYNs if there is a socket on this port, even if not in
LISTEN state. The SYN-ACK would be send as soon as the application calls
NutTcpAccept again.

In your case this won't help, because the remote may time out before it
is his turn to get the next SYN-ACK. You need fully established connections.

As Bernd Walter pointed out, we may indeed split bind and accept. To
keep it simple, it is still not required to split the sockets into a
listening and established ones.

NutTcpBind may put a socket into listening state.

NutTcpAccept may work this way:

if (state = LISTEN) {
  if (NutEventWait(read_timeout))
    return (sock_error = E..);
  else
    return 0;
}
if (state != CLOSED) {
  return (sock_error = E..);
}
NutTcpStateChange(sock, TCPS_LISTEN);
if (NutEventWait(read_timeout)) {
  NutTcpStateChange(sock, TCPS_CLOSE);
  return (sock_error = E..);
}
return 0;

The last part is only required to maintain backward compatibility.

Did I overlook something essential?

Harald

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Ethernut :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Michael,

looks like you hit the send button before writing the message.

Harald

Michael Smola wrote:

_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Michael Smola :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Harald,

sorry, that was an accidental sent reply from my MobPhone.
Please ignore, no contribution from my side to this topic.

...sorry...
Michael

-------- Original-Nachricht --------
> Datum: Fri, 23 Oct 2009 11:57:00 +0200
> Von: Harald Kipp <harald.kipp@...>
> An: "Ethernut User Chat (English)" <en-nut-discussion@...>
> Betreff: Re: [En-Nut-Discussion] NutTcpAccept blocks the tread

> Hi Michael,
>
> looks like you hit the send button before writing the message.
>
> Harald
>
> Michael Smola wrote:
>
> _______________________________________________
> http://lists.egnite.de/mailman/listinfo/en-nut-discussion

--
GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Oliver Schulz :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Urban,

just to get it right, if you are talking about "different sockets" does that
mean, that you need to serve several sockets with different port numbers? Or
do they have all the same port number and you have several connections to
this port?

/Oliver.



_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion

Re: NutTcpAccept blocks the tread

by Nathan Moore-5 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Harald,

>
> Considered, that NutTcpPassiveOpenEvent had been changed following your
> suggestion, the application will use the following pseudo code:
>
> for (;;) {
>  CreateSocket();
>  SocketOption(Set read timeout);
>  while (NutTcpAccept()) {
>    /* Timout, do something else,
>    ** but do not sleep. */
>  }
>  /* Handle the connection. */
>  ...
>  /* Finally */
>  DestroySocket();
> }
>
> Is that what you meant?


Yes.  It could check a variable or something and never open the window of
not listening to that port.
If it did sleep there it would still work, but would introduce the
possibility that you wouldn't be listening for a moment..


Nathan
_______________________________________________
http://lists.egnite.de/mailman/listinfo/en-nut-discussion
< Prev | 1 - 2 | Next >