Graceful NLM Demise
In most environments, the program is finished when it runs as it should. However, an NLM is not finished until it can terminate successfully. Here are some rules to consider when writing an NLM.
Rule One: "Everyone put away your own things when you are finished with them."
If your NLM application allocates a resource, it must free it when no longer needed; but this rule does not stop there. If an NLM thread allocates a resource, it must free it when no longer needed.
Some NLM developers attempt to write an all purpose "clean up" procedure. Such a procedure is inherently very difficult because it attempts to free resources that it did not allocate. Don't do this. Having each thread free its own allocated resources is much more efficient.
Rule Two: Implement a signal(SIGTERM) handler.
Users can attempt to unload your NLM using the UNLOAD command. Your NLM must be prepared for this event. The best way to handle this is to use the signal() function to implement a SIGTERM signal handler. Then, do not allow your SIGTERM handler to "return" until your main() thread, and any other NLM threads, have terminated.
When I write an NLM, I instinctively create two global integer variables; NLM_exiting and NLM_threadCnt. Initially, NLM_exiting is set to FALSE (0), and NLM_threadCnt is set to zero (0). The first statement in my NLMs main() is ++NLM_threadCnt. The last statement before my NLM main()'s final "return" statement is --NLM_threadCnt. Further, the NLM_exiting variable is monitored by all loops within my NLM. If NLM_exiting is ever true, all threads free any allocated resources and then self terminate. Given this, my NLMs SIGTERM signal handler looks something like the following: