Thread Safety

1 Introduction
2 Please Note
3 isThreaded
4 Installation

1 Introduction

Support for multi-threading is provided on two levels.

The base level implementation consists of a parallel collection of isam function calls that operate on file descriptor structures (as opposed to the usual integer file handles) and, other than requiring that you do not open the same file more than once in any one process, is fully multi-thread compatible without the requirement for critical section handling.

The second level option provides full cisam™ standard compatibility and operates on the standard integer based file handles and associated file descriptor table. This option provides critical section (mutex) handling for protection of the descriptor table and logic to provide appropriate handling for duplicate opens on the same file within the same process. The mutex requirement impacts on the efficiency of the library, but allows the use of the standard interface without losing functionality. There are two exceptions.

The four global variables - isrecnum, isreclen, iserrno and iserrio are present and maintained, but should not be considered reliable. Instead you should use the following function call equivalents:

long *is_recnum( int isfd );
int *is_reclen( int isfd );
int *is_errno( int isfd );
int *is_errio( int isfd );

Note that these functions return pointers rather than values. This allows the application to both enquire and set the value, as in the following examples:

  if( *is_errno( isfd ) == ENOREC ) /* record not found */

  *is_recnum( isfd ) = saved_record_number;

the equivalent core API functions are:

long *isRecnum( int isfd );
int *isReclen( int isfd );
int *isErrno( int isfd );
int *isErrio( int isfd );

The other exception applies to building variable length files. The standard isbuild call requires the use of a global isreclen value, which is not threadsafe, so isvbuild covers this problem by taking the maximum record length as an additional argument:

isvbuild( char *name, int fixlen, int maxlen, IsKdsc *key, int mode );

In the core API, isBuild takes an additional mlen argument.

2 Please Note

When using second level support you must call isThreaded from your root thread before starting any isam threads - this will initialise the master mutex lock.

Under no circumstances, should the application allow more than one thread to operate on the same isam file handle at the same time.

isCleanUp and iscleanup are inherently not threadsafe, and should only ever be called by the root thread after all isam handling threads have terminated.

The transaction processing module is not entirely threadsafe.

Second level threadsafe under os2/warp is only marginally supported. There are a number of limitations imposed by the fact that os2 only provides one critical section lock per thread. At time of writing the library will occasionally deadlock under heavy use. We are researching a solution to this problem but at the same time are hoping that ibm will improve threaded support before it becomes an issue. If you require second level threadsafe operation under os2 please stand up and be counted by contacting the support department.

3 isThreaded

int isThreaded( void )

RETURN

currently isThreaded and isThreadedDone return true always, but this may change in future, so perhaps it is best to check.

NOTES

isThreaded intialises the master mutex lock, and this is essential if you require second level thread safety.

4 Installation

In order to make use of the base level implementation, the only thing you need to do is to compile a library with the ISADMIN feature turned off. This is because the administration functions make use of global tables which would not be safe in a non-mutexed environment. Use of this implementation implies that you will be making base library calls, as detailed in API base reference, and that you do not plan to allow your applications to open the same file more than once.

To build a second level library you will need to turn the ISADMIN feature on, and make a choice from the four options currently given in isconfig.h as to which ISTHREADED flavour your target will use.

If your thread handling library uses a different series of calls or semantics than those covered, you might wish to take a look at head/isthread.h, since the porting procedure is relatively simple. In all cases we will be glad to offer advice in exchange for the opportunity to add more platforms to the list of those supported.