[En-Nut-Discussion] NutTcpAccept blocks the tread

Bernd Walter enut at cicely.de
Thu Oct 22 01:34:34 CEST 2009


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 at bwct.de> http://www.bwct.de
Modbus/TCP Ethernet I/O Baugruppen, ARM basierte FreeBSD Rechner uvm.



More information about the En-Nut-Discussion mailing list