The daemon thread is then started, which basically runs a SockAccept() loop until a quit event is posted, at which point it calls SockClose( socket ) and then signals the main program to exit.
This works fine about 80% of the time. Sometimes, however, I discover once the program has exited that the socket is still open, stalled in TIME_WAIT status. It usually stays that way for about 20 seconds or so, during which time of course I can't restart the daemon successfully.
I've tried with SO_LINGER both enabled and disabled. It makes no apparent difference.
How can I make sure this wretched socket gets closed when the program does?
> The daemon thread is then started, which basically runs a SockAccept() loop > until a quit event is posted, at which point it calls SockClose( socket ) > and then signals the main program to exit.
> This works fine about 80% of the time. Sometimes, however, I discover > once the program has exited that the socket is still open, stalled in > TIME_WAIT status. It usually stays that way for about 20 seconds or so, > during which time of course I can't restart the daemon successfully.
> I've tried with SO_LINGER both enabled and disabled. It makes no apparent > difference.
> How can I make sure this wretched socket gets closed when the program > does?
Do you do anything to unblock the receiving thread before exiting? Or is the thread killed "harshly" when the main thread exits?
-- [Reverse the parts of the e-mail address to reply.]
On Sun, 17 May 2009 04:46:35 UTC, Marty <n...@comcast.martyamodeo> wrote: > > The daemon thread is then started, which basically runs a SockAccept() > > loop until a quit event is posted, at which point it calls SockClose( > > socket ) and then signals the main program to exit.
> > This works fine about 80% of the time. Sometimes, however, I discover > > once the program has exited that the socket is still open, stalled in > > TIME_WAIT status. It usually stays that way for about 20 seconds or so, > > during which time of course I can't restart the daemon successfully.
> Do you do anything to unblock the receiving thread before exiting? Or > is the thread killed "harshly" when the main thread exits?
As I say, on program exit, I post an event to the daemon thread which tells it to break out of its loop. At that point, it calls SockClose, then posts an event back to the main program tell it that it's safe to exit.
When the user goes to exit the program, I post this event to the daemon thread:
IF listener.!thread > 0 THEN DO rc = VRMethod('Application', 'PostQueue',, listener.!thread, 0, 'finished = 1') END
(I also post termination messages to any client socket threads that may be active, but that part seems to be working as it should.)
The daemon thread's loop looks like this:
finished = 0 CALL VRInit DO WHILE finished == 0 csock = SockAccept( socket ) IF csock > 0 THEN DO CALL VRMethod 'Application', 'PostQueue', 0, 1,, 'CALL Event_Incoming', 'ClientSocket', csock END _VREEvent = VREvent('N') INTERPRET _VREEvent END IF socket > 0 THEN DO rc = SockClose( socket ) IF rc \= 0 THEN CALL SockPSock_ErrNo() END CALL VRMethod 'Application', 'PostQueue', 0, 1, 'CALL Quit' CALL VRFini
At which point the "Quit" method in the main program simply destroys the window and exits, as usual.
On 17 May 2009 02:41:01 -0500, Alex Taylor <mail...@reply.to.address> wrote:
> The daemon thread is then started, which basically runs a SockAccept() loop > until a quit event is posted, at which point it calls SockClose( socket ) > and then signals the main program to exit.
> This works fine about 80% of the time. Sometimes, however, I discover > once the program has exited that the socket is still open, stalled in > TIME_WAIT status. It usually stays that way for about 20 seconds or so, > during which time of course I can't restart the daemon successfully.
> I've tried with SO_LINGER both enabled and disabled. It makes no apparent > difference.
> How can I make sure this wretched socket gets closed when the program > does?
It's all very annoying. I've never got to the bottom of it. Have you tried putting in a SockShutDown() to see if that helps?
<ab...@orac12.clara34.co56.uk78> wrote: >>> > How can I make sure this wretched socket gets closed when the program >>> > does?
>>> It's all very annoying. I've never got to the bottom of it.
>> Ah, so it's not just me? Not sure if that's a relief or a worry. :)
>> Does it happen only with RXSOCK, or with sockets in general?
> In general I think.
>>> Have you tried putting in a SockShutDown() to see if that helps?
>> Well, now I have. And no, it doesn't help. :(
> Oh well, worth a shot. I think you'll just have to learn to live with it.
Actually, having pursued this a bit more, I find that my server only fails to bind with an "Address in use" error if it had connected clients at the time I closed it, despite disconnecting them properly. If it had no clients it restarted fine every time. "netstat -s" never showed any lingering sockets either way.
Subsequent to this, I added a SO_REUSEADDR setsocketopt() to the socket before binding and it now works properly all the time. I can't remember why I didn't do this before...
This is on a machine with a 16 bit TCP/IP stack though. Perhaps I should try it on a 32 bit stack as well.
Alex Taylor wrote: > On Sun, 17 May 2009 04:46:35 UTC, Marty <n...@comcast.martyamodeo> wrote:
>>> The daemon thread is then started, which basically runs a SockAccept() >>> loop until a quit event is posted, at which point it calls SockClose( >>> socket ) and then signals the main program to exit.
>>> This works fine about 80% of the time. Sometimes, however, I discover >>> once the program has exited that the socket is still open, stalled in >>> TIME_WAIT status. It usually stays that way for about 20 seconds or so, >>> during which time of course I can't restart the daemon successfully. >> Do you do anything to unblock the receiving thread before exiting? Or >> is the thread killed "harshly" when the main thread exits?
> As I say, on program exit, I post an event to the daemon thread which tells > it to break out of its loop. At that point, it calls SockClose, then posts > an event back to the main program tell it that it's safe to exit.
> When the user goes to exit the program, I post this event to the daemon > thread:
> IF listener.!thread > 0 THEN DO > rc = VRMethod('Application', 'PostQueue',, > listener.!thread, 0, 'finished = 1') > END
> (I also post termination messages to any client socket threads that may be > active, but that part seems to be working as it should.)
> The daemon thread's loop looks like this:
> finished = 0 > CALL VRInit > DO WHILE finished == 0 > csock = SockAccept( socket ) > IF csock > 0 THEN DO > CALL VRMethod 'Application', 'PostQueue', 0, 1,, > 'CALL Event_Incoming', 'ClientSocket', csock > END > _VREEvent = VREvent('N') > INTERPRET _VREEvent > END > IF socket > 0 THEN DO > rc = SockClose( socket ) > IF rc \= 0 THEN CALL SockPSock_ErrNo() > END > CALL VRMethod 'Application', 'PostQueue', 0, 1, 'CALL Quit' > CALL VRFini
> At which point the "Quit" method in the main program simply destroys the > window and exits, as usual.
Is there some chance that the main application can post its message to terminate the thread, but not give up the rest of its timeslice and exit before the thread gets the message? In C-land, I would have some kind of DosWaitThread type of thing in there.
-- [Reverse the parts of the e-mail address to reply.]
On Tue, 19 May 2009 13:19:14 UTC, Marty <n...@comcast.martyamodeo> wrote: > > As I say, on program exit, I post an event to the daemon thread which > > tells it to break out of its loop. At that point, it calls SockClose, > > then posts an event back to the main program tell it that it's safe to > > exit.
> Is there some chance that the main application can post its message to > terminate the thread, but not give up the rest of its timeslice and exit > before the thread gets the message? In C-land, I would have some kind > of DosWaitThread type of thing in there.
I don't see how. If the daemon thread is active, then the main program can only quit once it receives the 'done' message from the listener.
But I have no way of knowing what the VX-REXX runtime is doing internally, of course...
<ab...@orac12.clara34.co56.uk78> wrote: > Actually, having pursued this a bit more, I find that my server only > fails to bind with an "Address in use" error if it had connected clients > at the time I closed it, despite disconnecting them properly. > If it had no clients it restarted fine every time. > "netstat -s" never showed any lingering sockets either way.
> Subsequent to this, I added a SO_REUSEADDR setsocketopt() to the socket > before binding and it now works properly all the time. > I can't remember why I didn't do this before...
> This is on a machine with a 16 bit TCP/IP stack though. Perhaps I should > try it on a 32 bit stack as well.
Well, so far it seems to work here (crossing fingers). MPTS WR08708 (eCS 2.0rc4).