ToolTalk User's Guide

Using ToolTalk in a Multi-Threaded Environment

This section describes how to use ToolTalk in a multi-threaded environment.

Initialization

Using the ToolTalk library with multi-threaded clients requires an initialization call like the following call:

tt_feature_required(TT_FEATURE_MULTITHREADED);

The call must be invoked before any other ToolTalk call is made. Attempts to call tt_feature_required(TT_FEATURE_MULTITHREADED)after other ToolTalk API calls have been made will result in a TT_ERR_TOOLATE error.

Libraries and other reusable modules that use ToolTalk might want to query the ToolTalk library to determine if the invoking application has enabled the multi-thread feature of ToolTalk. The tt_feature_enabled() API call was added for this purpose. Top-level applications rarely need to use tt_feature_enabled() since the application would know if it had already done the initialization.

ToolTalk procids and sessions

When a ToolTalk client calls tt_open() or tt_session_join(), the new procid or session is the default for the thread (and not the entire process as would be the for a non-multi-threaded ToolTalk client). A thread's default procid and session, before any calls to tt_open() or tt_session_join() are made, are initially the same as the defaults for the creator of the thread. In addition to changing the defaults with tt_open() or tt_session_join(), tt_thread_procid_set() and tt_thread_session_set() can be used to switch to other defaults created previously. The default procid and session values can be retrieved using tt_thread_procid() and tt_thread_session(). The thread-specific procid and session values are managed through the use of thread-specific storage. If no value has yet been created in the thread, the default value for the entire ToolTalk process is the fallback value.


Note –

It is possible for the values returned by tt_default_procid() and tt_thread_procid() (and similarly, tt_default_session() and tt_thread_session()) to be different at any given time for some thread. This is so because tt_default_procid_set() and tt_default_session_set() do not affect the default values for a thread. They only affect the default values for the entire ToolTalk process.


Using threads with ToolTalk enabled applications is a natural implementation technique for programs that switch procids and sessions. These programs might, at some point, want to easily determine which ToolTalk procid is associated with a ToolTalk session. This was difficult to do in previous versions of ToolTalk. tt_procid_session() has been provided to accomplish this. Although tt_procid_session()does not depend on threads, it is useful for applications that use threads with ToolTalk.

ToolTalk storage

tt_mark() and tt_release()affect storage allocated on a per-thread basis, not a per-process basis. Therefore, one thread cannot use tt_release() to release storage that was marked by another thread using tt_mark().

Common Problems

Using one thread to send a message and another to process a message is a common technique. However, use care when destroying a message with tt_message_destroy() when another thread might be examining and processing the message contents. This typically results in a program crash when the receiving thread tries to access storage that was freed by another thread. This is the same as managing non-ToolTalk storage in multi-threaded applications, but easier to do using the ToolTalk API.