Skip to main content

Using Callin with Multithreading

Using Callin with Multithreading

InterSystems IRIS has been enhanced so that Callin can be used by threaded programs running under some versions of Windows and UNIX® (see “Other Supported Features” in the InterSystems Supported Platforms document for this release for a list). A threaded application must link against libirisdbt.so or irisdbt.lib.

A program can spawn multiple threads (pthreads in a UNIX® environment) and each thread can establish a separate connection to InterSystems IRIS by calling IrisSecureStart. Threads may not share a single connection to InterSystems IRIS; each thread which wants to use InterSystems IRIS must call IrisSecureStart. If a thread attempts to use a Callin function and it has not called IrisSecureStart, a IRIS_NOCON error is returned.

If IrisSecureStart is being used to specify credentials as part of the login, each thread must call IrisSecureStart and provide the correct username/password for the connection, since credentials are not shared between the threads. There is a performance penalty within InterSystems IRIS using threads because of the extra code the C compiler has to generate to access thread local storage (which uses direct memory references in non-threaded builds).

Threads and UNIX® Signal Handling

On UNIX®, InterSystems IRIS uses a number of signals. If your application uses the same signals, you should be aware of how InterSystems IRIS deals with them. All signals have a default action specified by the OS. Applications may choose to leave the default action, or can choose to handle or ignore the signal. If the signal is handled, the application may further select which threads will block the signal and which threads will receive the signal. Some signals cannot be blocked, ignored, or handled. Since the default action for many signals is to halt the process, leaving the default action in place is not an option. The following signals cannot be caught or ignored, and terminate the process:

SIGNAL DISPOSITION
SIGKILL terminate process immediately
SIGSTOP stop process for later resumption

The actions that an application establishes for each signal are process-wide. Whether or not the signal can be delivered to each thread is thread-specific. Each thread may specify how it will deal with signals, independently of other threads. One thread may block all signals, while another thread may allow all signals to be sent to that thread. What happens when a signal is sent to the thread depends on the process-wide handling established for that signal.

Signal Processing

InterSystems IRIS integrates with application signal handling by saving application handlers and signal masks, then restoring them at the appropriate time. Signals are processed in the following ways:

Generated signals

InterSystems IRIS installs its own signal handler for all generated signals. It saves the current (application) signal handler. If the thread catches a generated signal, the signal handler disconnects the thread from InterSystems IRIS, calls the applications signal handling function (if any), then does pthread_exit.

Since signal handlers are process-wide, threads not connected to InterSystems IRIS will also go into the signal handler. If InterSystems IRIS detects that the thread is not connected, it calls the application handler and then does pthread_exit.

Synchronous Signals

InterSystems IRIS establishes signal handlers for all synchronous signals, and unblocks these signals for each thread when the thread connects to InterSystems IRIS (see “Synchronous Signals” for details).

Asynchronous Signals

InterSystems IRIS handles all asynchronous signals that would terminate the process (see “Asynchronous Signals” for details).

Save/Restore Handlers

The system saves the signal state when the first thread connects to it. When the last thread disconnects, InterSystems IRIS restores the signal state for every signal that it has handled.

Save/Restore Thread Signal Mask

The thread signal mask is saved on connect, and restored when the thread disconnects.

Synchronous Signals

Synchronous signals are generated by the application itself (for example, SIGSEGV). InterSystems IRIS establishes signal handlers for all synchronous signals, and unblocks these signals for each thread when it connects to InterSystems IRIS.

Synchronous signals are caught by the thread that generated the signal. If the application has not specified a handler for a signal it has generated (for example, SIGSEGV), or if the thread has blocked the signal, then the OS will halt the entire process. If the thread enters the signal handler, that thread may exit cleanly (via pthread_exit) with no impact to any other thread. If a thread attempts to return from the handler, the OS will halt the entire process. The following signals cause thread termination:

SIGNAL DISPOSITION
SIGABRT process abort signal
SIGBUS bus error
SIGEMT EMT instruction
SIGFPE floating point exception
SIGILL illegal instruction
SIGSEGV access violation
SIGSYS bad argument to system call
SIGTRAP trace trap
SIGXCPU CPU time limit exceeded (setrlimit)

Asynchronous signals

Asynchronous signals are generated outside the application (for example, SIGALRM, SIGINT, and SIGTERM). InterSystems IRIS handles all asynchronous signals that would terminate the process.

Asynchronous signals may be caught by any thread that has not blocked the signal. The system chooses which thread to use. Any signal whose default action is to cause the process to exit must be handled, with at least one thread eligible to receive it, or else it must be specifically ignored.

The application must establish a signal handler for those signals it wants to handle, and must start a thread that does not block those signals. That thread will then be the only one eligible to receive the signal and handle it. Both the handler and the eligible thread must exist before the application makes its first call to IrisStart. On the first call to IrisStart, the following actions are performed for all asynchronous signals that would terminate the process:

  • InterSystems IRIS looks for a handler for these signals. If a handler is found, InterSystems IRIS leaves it in place. Otherwise, it sets the signal to SIG_IGN (ignore the signal).

  • InterSystems IRIS blocks all of these signals for connected threads, whether or not a signal has a handler. Thus, if there is a handler, only a thread that is not connected to InterSystems IRIS can catch the signal.

The following signals are affected by this process:

SIGNAL DISPOSITION
SIGALRM timer
SIGCHLD blocked by threads
SIGDANGER ignore if unhandled
SIGHUP ignore if unhandled
SIGINT ignore if unhandled
SIGPIPE ignore if unhandled
SIGQUIT ignore if unhandled
SIGTERM If SIGTERM is unhandled, InterSystems IRIS will handle it. On receipt of a SIGTERM signal, the InterSystems IRIS handler will disconnect all threads and no new connections will be permitted. Handlers for SIGTERM are not stacked.
SIGUSR1 inter-process communication
SIGUSR2 inter-process communication
SIGVTALRM virtual timer
SIGXFSZ InterSystems IRIS asynchronous thread rundown
FeedbackOpens in a new tab