UNIX signal handling
In general, UNIX and iSeries systems have moved from a nonthreaded (process) environment to a multithreaded environment. In the nonthreaded environment, some functions could be implemented only by using signals, though most applications did not need to be aware of signals and signal handling. In the multithreaded environment, thread-based primitives support some of the functions that used to be implemented in the nonthreaded environments using signals.
In many instances, signals and signal handling, although supported, do not fit well into the multithreaded environment and various restrictions exist. This can be particularly problematic when you are integrating application code with different middleware libraries (running as part of the application) in a multithreaded environment where each is trying to handle signals. The traditional approach of saving and restoring signal handlers (defined per process), which worked when there was only one thread of execution within a process, does not work in a multithreaded environment. This is because many threads of execution could be trying to save and restore a process-wide resource, with unpredictable results.
Signal handling before MQSeries version 5.2
Signals in the non-threaded environment
Each MQI function sets up its own signal handler for the signals:
- SIGALRM
- SIGBUS
- SIGFPE
- SIGSEGV
Users' handlers for these are replaced for the duration of the MQI function call. Other signals can be caught in the normal way by user-written handlers. If you do not install a handler, the default actions (for example, ignore, core dump, or exit) are left in place.
On Solaris all applications are threaded even if they use a single thread.
Signals in the threaded environment
A thread is considered to be connected to MQSeries from MQCONN (or MQCONNX) until MQDISC.
Synchronous signals
Synchronous signals arise in a specific thread. UNIX safely allows the setting up of a signal handler for such signals for the whole process. However, MQSeries sets up its own handler for the following signals, in the application process, while any thread is connected to WebSphere MQ:
- SIGBUS
- SIGFPE
- SIGSEGV
If you are writing multithreaded applications, note that there is only one process-wide signal handler for each signal. MQSeries alters this signal handler when the application is connected to MQSeries. If one of these signals occurs while not on a thread connected to MQSeries, MQSeries attempts to call the signal handler that was in effect at the time of the first MQSeries connection within the process. Application threads must not establish signal handlers for these signals while there is any possibility that another thread of the same process is also connected to MQSeries.
Because signal handlers are saved and restored by WebSphere MQ, application threads ideally should not establish signal handlers for these signals while there is any possibility that another thread of the same process is also connected to WebSphere MQ.
Asynchronous signals
Asynchronous signals arise outside the whole process. UNIX does not guarantee predictable behavior for handling asynchronous signals, in certain situations, when running multithreaded. MQSeries must perform clean-up of thread and process resources as part of the termination from these asynchronous signals:
- SIGCHLD
- SIGHUP
- SIGINT
- SIGQUIT
- SIGTERM
MQSeries establishes a sigwait thread in the application process to intercept these signals.
These signals must not be used by the application when running multithreaded and when any thread is within an MQSeries connection. These signals should not be unmasked within any application thread; be aware of the default status of the signal mask for threads that do not make MQSeries calls.
Additional considerations
Fastpath (trusted) applications
Fastpath applications run in the same process as MQSeries and so are running in the multithreaded environment. In this environment the application should not use any signals or timer interrupts. If a Fastpath application intercepts such an event, the queue manager must be stopped and restarted, or it may be left in an undefined state. For a full list of the restrictions for Fastpath applications under MQCONNX see Connecting to a queue manager using the MQCONNX call.
MQI function calls within signal handlers
While you are in a signal handler, you cannot call an MQI function. If you call an MQI function, while another MQI function is active, MQRC_CALL_IN_PROGRESS is returned. If you call an MQI function, while no other MQI function is active, it is likely to fail because of the operating system restrictions on which calls can be issued from within a handler.
In the case of C++ destructor methods, which may be called automatically during program exit, you may not be able to stop the MQI functions from being called. Therefore, ignore any errors about MQRC_CALL_IN_PROGRESS. If a signal handler calls exit(), MQSeries backs out uncommitted messages in syncpoint as normal and closes any open queues.
Signals during MQI calls
MQI functions do not return the code EINTR or any equivalent to application programs. If a signal occurs during an MQI call, and the handler calls "return", the call continues to run as if the signal had not happened. In particular, MQGET cannot be interrupted by a signal to return control immediately to the application. If you want to break out of an MQGET, set the queue to GET_DISABLED; alternatively, use a loop around a call to MQGET with a finite time expiry (MQGMO_WAIT with gmo.WaitInterval set), and use your signal handler (in a nonthreaded environment) or equivalent function in a threaded environment to set a flag which breaks the loop.
User exits and installable services
User exits and installable services that run as part of an MQSeries process in a multithreaded environment have the same restrictions as for Fastpath applications. They should be considered as permanently connected to MQSeries and so not use signals or non-threadsafe operating system calls.
MQSeries use of SIGALRM
For communication purposes, MQSeries needs a signal for its internal use. The SIGALRM signal should not be used by an application while any thread is within an MQSeries connection.
Additional considerations for threaded client applications
MQSeries handles the following signals during I/O to a server. These signals are defined by the communications stack. An application should not establish a signal handler for these signals while a thread of the process is making an MQSeries call:
- SIGPIPE (for TCP/IP)
- SIGUSR1 (for LU 6.2)
Signal handling in version 5.2 and later releases
Unthreaded applications
(Not applicable on Solaris as all applications are considered threaded even if they only use a single thread.)
Each MQI function sets up its own signal handler for the signals:
- SIGALRM
- SIGBUS
- SIGFPE
- SIGSEGV
- SIGILL
Users' handlers for these are replaced for the duration of the MQI function call. Other signals can be caught in the normal way by user-written handlers. If you do not install a handler, the default actions (for example, ignore, core dump, or exit) are left in place.
Following the handling of a synchronous signal (SIGSEGV, SIGBUS, SIGFPE, SIGILL) by WebSphere MQ, it will attempt to pass the signal on to any signal handler registered before making the MQI function call.
Threaded applications
A thread is considered to be connected to WebSphere MQ from MQCONN (or MQCONNX) until MQDISC.
Synchronous signals
Synchronous signals arise in a specific thread. UNIX safely allows the setting up of a signal handler for such signals for the whole process. However, WebSphere MQ sets up its own handler for the following signals, in the application process, while any thread is connected to WebSphere MQ:
- SIGBUS
- SIGFPE
- SIGSEGV
- SIGILL
If you are writing multithreaded applications, note that there is only one process-wide signal handler for each signal. When WebSphere MQ sets up its own synchronous signal handlers it saves any previously registered handlers for each signal. Following the handling by WebSphere MQ of one of the signals listed above, WebSphere MQ attempts to call the signal handler that was in effect at the time of the first WebSphere MQ connection within the process. The previously registered handlers are restored when all application threads have disconnected from WebSphere MQ.
Because signal handlers are saved and restored by WebSphere MQ, application threads ideally should not establish signal handlers for these signals while there is any possibility that another thread of the same process is also connected to WebSphere MQ.
When an application, or a middleware library (running as part of an application), does establish a signal handler while a thread is connected to WebSphere MQ, the application's signal handler must call the corresponding WebSphere MQ handler during the processing of that signal.
When establishing and restoring signal handlers, the general principle is that the last signal handler to be saved must be the first to be restored:
- When an application establishes a signal handler after connecting to WebSphere MQ, the previous signal handler must be restored before the application disconnects from WebSphere MQ.
- When an application establishes a signal handler before connecting to WebSphere MQ, the application must disconnect from WebSphere MQ before restoring its signal handler.
Failure to observe the general principle that the last signal handler to be saved must be the first to be restored can result in unexpected signal handling in the application and, potentially, the loss of signals by the application.
Asynchronous signals
WebSphere MQ does not make use of any asynchronous signals in threaded applications unless they are client applications.
Additional considerations for threaded client applications
WebSphere MQ handles the following signals during I/O to a server. These signals are defined by the communications stack. The application should not establish a signal handler for these signals while a thread is connected to a queue manager:
- SIGPIPE (for TCP/IP)
Additional considerations
Fastpath (trusted) applications
Fastpath applications run in the same process as WebSphere MQ and so are running in the multithreaded environment. In this environment WebSphere MQ handles the synchronous signals SIGSEGV, SIGBUS, SIGFPE, and SIGILL. All other signals must not be delivered to the Fastpath application whilst it is connected to WebSphere MQ. Instead they must be blocked or handled by the application. If a Fastpath application intercepts such an event the queue manager must be stopped and restarted, or it may be left in an undefined state. For a full list of the restrictions for Fastpath applications under MQCONNX see Connecting to a queue manager using the MQCONNX call.
MQI function calls within signal handlers
While you are in a signal handler, you cannot call an MQI function. If you call an MQI function, while another MQI function is active, MQRC_CALL_IN_PROGRESS is returned. If you call an MQI function, while no other MQI function is active, it is likely to fail because of the operating system restrictions on which calls can be issued from within a handler.
In the case of C++ destructor methods, which may be called automatically during program exit, you may not be able to stop the MQI functions from being called. Therefore, ignore any errors about MQRC_CALL_IN_PROGRESS. If a signal handler calls exit(), WebSphere MQ backs out uncommitted messages in syncpoint as normal and closes any open queues.
Signals during MQI calls
MQI functions do not return the code EINTR or any equivalent to application programs. If a signal occurs during an MQI call, and the handler calls "return", the call continues to run as if the signal had not happened. In particular, MQGET cannot be interrupted by a signal to return control immediately to the application. If you want to break out of an MQGET, set the queue to GET_DISABLED; alternatively, use a loop around a call to MQGET with a finite time expiry (MQGMO_WAIT with gmo.WaitInterval set), and use your signal handler (in a nonthreaded environment) or equivalent function in a threaded environment to set a flag which breaks the loop.
In the AIX environment, WebSphere MQ requires that system calls interrupted by signals are restarted. When establishing your own signal handler with sigaction(2) set the SA_RESTART flag in the sa_flags field of the new action structure otherwise WebSphere MQ may be unable to complete any call interrupted by a signal.
User exits and installable services
User exits and installable services that run as part of an WebSphere MQ process in a multithreaded environment have the same restrictions as for Fastpath applications. They should be considered as permanently connected to WebSphere MQ and so not use signals or non-threadsafe operating system calls.
WebSphere is a trademark of the IBM Corporation in the United States, other countries, or both.
IBM is a trademark of the IBM Corporation in the United States, other countries, or both.
AIX is a trademark of the IBM Corporation in the United States, other countries, or both.