Discussion:
[Openhpi-devel] Signal handling inside service threads
Mohan
2015-05-27 22:37:42 UTC
Permalink
Hello All,

The main thread creates three threads, discovery, evtpop and evtget,
that run all the time. In addition service threads are created as needed
to service the client connections. The plugins also may create the
threads to do their job. Only main thread can receive the user signal
and it can set variables to indicate to other threads that a signal was
received.

When a SIGTERM or SIGINT is issued, sig_hanlder in the main thread is
invoked to handle the signal. The following happens to ensure an orderly
shutdown of the daemon.
1. Quit event is posted to close the evtpop_thread. This thread exits
first
2. oh_server_request_stop is called to close all the client sockets.
This terminates all the client programs. But the threads that are
serving the connection are still active, till they complete the function
they are executing.
3. A static variable, stop, is set. stop=true does the following.
a. stop variable informs the server_run function that is servicing the
connections to exit the loop. It no longer creates additional threads.
But threads already created may be still servicing their last call.
b. Service threads that were created earlier check this variable from
the invite loop and they exit. If they are executing a function they
will catch it only after finishing it. This may take a long time and it
depends on the plugin code also.

At this point in time, the normal flow resumes to complete the shutdown.
Once server_run exits, oh_finit is called which calls close_handlers
first. When close_handlers is called, the plugin specific code could
inform its own threads that signal was issued and shut them down.
Service threads are not created by the plugin.
After the close_handlers, oh_threaded_stop is called to stop the other
threads. Here signal_stop is set, this does the following.
a. It is caught by the discovery_func and it stops the discovery loop
and returns.
b. evtget_func reads this variable in its while loop and returns.
After setting the variable the main thread waits for the evtpop, evtget
and discovery threads and cleans them.

The major problem is service threads that are already executing the
plugin code. If the code takes a long time it will not terminate within
a reasonable amount of time (say 5 or 10 seconds).
Discovery or power cycle (off/on) could take a long time. How do we
convey the signal status to the already executing function in the
service thread? Is it ok to introduce one more global variable at the
infrastructure level and use the same in the plugins?
In a related note, is it ok to change the order of the thread
termination? Right now it is evtpop, clients, service, plugin, evtget
and discovery and finally main. If signal_stop is set by the
sig_handler, then evtget and discovery threads also complete before
service and plugin threads.

Any and all suggestions are welcome.

Regards
Mohan




------------------------------------------------------------------------------
Loading...