Good day

I found very easy sollution. I will show in small example

//-----------------------------------------------------------------------------------------

sig_atomic_t finishApplication(0);              // initialize exit flag

//-----------------------------------------------------------------------------------------
// this code set handler function:
sigset_t mask;
struct sigaction act;

memset(&act, 0 , sizeof(act));
sigemptyset(&mask);

act.sa_mask = mask;
act.sa_sigaction = handler_sigkill;
act.sa_flags = SA_SIGINFO;

sigaction(SIGTERM, &act, NULL);
sigaction(SIGINT, &act, NULL);
sigaction(SIGHUP, &act, NULL);

//-----------------------------------------------------------------------------------------

// signal handler function
void handler_sigkill(int signo, siginfo_t* info, void* f) {
        finishApplication = 1;          

        std::cout << "server got signal, waiting for stopping server";
}



//-----------------------------------------------------------------------------------------

// ... some code

this->accept_timeout = 5;                       // if no connection, every 5 
seconds accept     
                                                                // function 
will be unblocked

// main thread loop, wait for new connections
for (;;) {
        
        SOAP_SOCKET socketDescriptor = accept();

        // check for exit flag
        if (finishApplication) {
                // if accept return valid descriptor, return to client 
soap_fault, and 
                // close connection

                // signal to all threads about application stop
                // wait for threads

                break;  // quit from application :-)
        }

        if (!soap_valid_socket(socketDescriptor)) {
                if (this->errnum) {
                                // fatal error, stop all treads and quit from 
application
                                break;
                        } else {
                                // accept unblocked by timeout
                                //"server timed out     
                                continue;                                       
                        }
                }
        }

// ... some code

}

//-----------------------------------------------------------------------------------------

Comments:
if no connection, accept function wake up every 5 seconds. After accept 
function, main thread check for finishApplication flag. If it set, main thread 
will signall all threads to stop, and then exit from thread loop and finish 
application. I can safely set/get finishApplication value, because 
sig_atomic_t atomic datatype (datatype, that can be change/read without any 
mutex locks, because this datatype simple)

Thanks


-- 
With best wishes, Maxim Sditanov


> Thanks for your help. As i thought.
> 
> From man 7 signal, section "Interruption of System Calls and Library
> Functions by Signal Handlers"
> 
> ---------------------------------------------------------------------------
> -----------------------
> 
> If a signal handler is invoked while a system call or library function call
> is blocked, then either:
>        * the call is automatically restarted after the signal handler
> returns; or
>        * the call fails with the error EINTR.
> 
>        Which of these two behaviors occurs depends on the interface and
> whether or not the signal handler was established  using  the  SA_RESTART
> flag  (see  sigaction(2)).  The details vary across Unix systems; below,
> the details for Linux.
> 
>  If  a  blocked call to one of the following interfaces is interrupted by a
> signal handler, then the call will be automatically restarted after the
> signal handler returns if the SA_RESTART flag was used; otherwise the call
> will fail with the error EINTR:
> 
> * Socket  interfaces:  accept(2),  connect(2),  recv(2), recvfrom(2),
> recvmsg(2), send(2), sendto(2), and sendmsg(2), unless a timeout has been
> set on the socket (see below).
> 
> ---------------------------------------------------------------------------
> -----------------------
> 
> I tried to pass to all this->*_timeout variables = 0, but it didn't help
> :-( and i checked code... i think, gsoap pass timeout value to socket, and
> if i set timeout to 0, it pass to socket some default value. Yesterday i
> will check gsoap sources.
> 
> Thank you for you help
> 
> PS. I don't know, how to make reply at yahoo gsoap newsgroup.
> 
> > Hi,
> > 
> > Spin another thread when you get the signal and make a connection back
> > into your own server.  This will unblock your accept.  It's the only
> > reliable way I have found to cleanly shutdown servers.
> > 
> > Karl
> > 
> > --- In gsoap@yahoogroups.com, "feni...@..." <feni...@...> wrote:
> > > Good day
> > > 
> > > I wrote standalone threaded gsoap server, and i have small problem.
> > > Main thread waiting for connection and blocked in accept call. When i
> > > got Signal (SIGTERM), i turn on flag, that i want to stop server. And
> > > if i have no connections, main thread blocked by accept call. In
> > > signal documentation said, that theoretical accept call will be
> > > terminated and unblocked, when signal will arrive to application. But,
> > > this is only theoretical. I tried to set " this->accept_timeout = 5;      
"
> > > (server on C++), but accept call blocked. Can someone help?

Reply via email to