Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2008-08

SSocket: TSocketServer.StopAccepting

3 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Johann Glaser

Hi!

I'm using the SSocket unit with TSocketServer (and TInetServer) for TCP/IP communication in a multi-threaded application. To listen (and accept) connections from a client the method StartAccepting is called. This is a blocking function.

To quit the server I call StopAccepting. The implementation just sets a variable which is checked by StartAccepting.

There are two problems:
1) If using the TSocketStream in blocking mode, the accept() call used by StartAccepting does not return at all, so StopAccepting is somewhat useless here.
2) In non-blocking mode the internal variable is checked periodically, but not really often, so race conditions with Destroy can happen.

In both cases, when I want to quit my program, there is no safe way to stop accepting at the socket, except from OnConnect (as shown e.g. in /packages/fcl-base/examples/isocksvr.pp).

So there are some ideas to solve this.

First: Send a SIGTERM to this thread, accept() will return with EINTR, which should then be checked for in TInetServer.Accept, TUnixServer.Accept, ... and generate a special exception which is then again checked for in TSocketServer.StartAccepting which simply exits the loop.

Second: Do a dummy connect to myself and check for FAccepting directly after Accept returns and then leave the loop. I prefer this one. OTOH this depends on knowing one's own address and allowing this connection by the firewall rules.

In any case, I suggest that StopAccepting really waits and only returns after StartAccepting has finished. This also must be used in Destroy. Here we have to take care for the case if StopAccepting is called from OnConnect.

Did I miss something? Do you have other ideas? If you agree with my idea, I'll implement the changes and send a patch for that.

Bye
Hansi

Reply by email

Michael Green
to Johann Glaser

Hello Hansi,

I am using Synapse for all my socket work, so this might be a bit different for you. But for a blocking listener in a thread (waiting at an Accept), I call AbortSocket. It immediately stops all work on the socket and lets you do the things you need to do. I'm sure there's a similar "Abort" function in the package you are using.

-- Mike

Reply by email

Johann Glaser
to Michael Green

Hi!

Show quoted text 5 lines
I am using Synapse for all my socket work, so this might be a bit different for you. But for a blocking listener in a thread (waiting at an Accept), I call AbortSocket. It immediately stops all work on the socket and lets you do the things you need to do. I'm sure there's a similar "Abort" function in the package you are using.

Thanks for the hint. I looked at Synapse but it was too much of an overkill for me. I managed to get ssockets working by setting MaxConnections to 1, doing a dummy-connect to abort listening (which still has a problem if the listening didn't start) and a little patch to ssockets (http://mantis.freepascal.org/view.php?id=12040).

Bye
Hansi

Reply by email