Product Documentation

FairCom ISAM for C

Previous Topic

Next Topic


Set operation modes for special performance-related functionality and test operational states for critical events.

Short Name



Low-Level function


LONG SetOperationState( LONG status_word, VRLEN operation_code )


SetOperationState() allows an application to set or return a 4-byte status word. The bits of the status word change default operation modes. status_word options options are listed in the following table and detailed below:

Operations Mode



Enable automatic, low level, blocking read locks on each record access that does not already have a lock.


Lock next fetch only.


Automatic unlock on add.


Automatic unlock on rewrite.




Blocking lock on next fetch only.


Enable blocking write lock mode during record add call then restore original lock mode.


Toggle function monitor. (Server)


Toggle lock monitor. (Server)


Toggle memory track monitor. (Server)


Don’t continue if mirror or primary fails. (Server)


A primary or mirror has been shutdown.


Memory swapping active.


Automatic ISAM transactions.


Keep locks involved in automatic transactions on record adds and updates after commit.


Changes GetSerialNbr() operation.


Defer file closes or deletes during transactions.


Change all CT_STRING fields having a non-zero field length in the fixed length portion of the record buffer to CT_FSTRING fields. (Client)


Set sysiocod on disk reads and writes.

operation_code options are:

Operation State



Turn a status bit off.


Set the entire status word.


Turn a status bit on.


Return the entire status word.

OPS_READLOCK - The set operations function, SETOPS(), enables automatic, low level, blocking read locks on each record access that does not already have a lock. The locks are released automatically as soon as the record is read. Blocking locks permit a c-tree application to be coded the same whether or not the automatic locks have been requested. But this means a read will block until the read lock is available. The locking code is in the REDREC(), iRDVREC() and REDVREC() routines.


will turn on or off the read lock state.

If ctBEHAV_READLOCK is not enabled, the SETOPS() call will not return an error, and no automatic locking will take place. The state variable returned by SETOPS() will not have the OPS_READLOCK bit set.

OPS_UNLOCK_ADD - If on, causes automatic record unlocks on calls to AddRecord() or AddVRecord(). A loop of the form:

while (. . .) {


AddRecord(. . .);



could be replaced with:


while(. . .) {

AddRecord(. . .);


OPS_UNLOCK_RWT - Causes automatic record unlock on calls to ReWriteRecord() or ReWriteVRecord(). Similar to the OPS_UNLOCK_ADD, this mode eliminates the need to call LockISAM(ctFREE). If the rewrite fails, the record remains locked.

OPS_LOCKON_GET - Unlike the previous two modes, this status word mode must be set before each use. However, the OPS_STATE_ON call for OPS_LOCKON_GET is not sent to the c-tree Server, so repeated calls do not cause network overhead. OPS_LOCKON_GET should not be OR-ed with any other status_word constants.

OPS_LOCKON_GET and OPS_UNLOCK_RWT can significantly reduce the number of calls needed to lock, read, update and unlock a record. A loop of the form:

while(. . .) {


GetRecord(. . .);

ReWriteRecord(. . .);



which requires four calls to the c-tree Server for each loop, can be replaced with:


while(. . .) {


GetRecord(. . .);

ReWriteRecord(. . .);


where only two calls go to the c-tree Server for each loop.

Note: The OPS_LOCKON_GET state is cleared on the subsequent read operation, whether or not the read operation succeeds. Thus, there is no need to call OPS_STATE_OFF for this mode. In fact, doing so results in additional network calls to the server defeating any benefits gained. If the read operation fails, the lock is freed automatically on return from the read operation. Use OPS_LOCKON_GET prior to any low level or ISAM level retrieval function, such as FirstRecord() or ReadData().

OPS_LOCKON_BLK - Behaves as OPS_LOCKON_GET except the lock request is a blocking lock. If the lock is denied, the client is placed in a wait list for the lock, which is granted on a FIFO (First In First Out) basis. The application does not see the lock denial, does not have to issue retries, and waits forever for the lock. However, while waiting in the wait list, if the requesting client would cause a deadlock, the retrieval operation fails with DEAD_ERR (86). Support for this option is only guaranteed by the c-tree Server. Many non-server, multi-user systems do not support blocking locks, and OPS_LOCKON_BLK functions as a non-blocking lock.

SetOperationState(OPS_LOCKON_BLK,OPS_STATE_ON); /* enable */

SetOperationState(OPS_LOCKON_BLK,OPS_STATE_OFF); /* disable */

OPS_FUNCTION_MON - Toggles the c-tree Server function monitor.

OPS_MIRROR_NOSWITCH - Changes how errors related to mirrored files are handled. The default protocol is to try to continue operation with either the primary or the mirror file if the other fails. If the primary fails, all I/O continues on the mirror. If the mirror fails, all I/O continues on the primary. When operation continues with the remaining good file, either primary or mirror, the c-tree Plus function returns successfully. However, this situation causes an event to be reported via SystemMonitor(), and the OPS_MIRROR_TRM bit is set in the status_word.

Calling SetOperationState(OPS_MIRROR_NOSWITCH, OPS_STATE_ON), changes the application protocol. If either the primary or the mirror fails, the entire operation fails and returns an appropriate error code. Use SystemMonitor() to monitor for primary/mirror errors under either protocol.

OPS_AUTOISAM_TRN - Implements automatic transaction begins, commits, or aborts for the six ISAM update routines: AddRecord(), DeleteRecord(), ReWriteRecord(), AddVRecord(), DeleteVRecord(), ReWriteVRecord(). Automatic transactions reduce the network traffic for single ISAM updates. These automatic transactions can be used for both Server and single user implementations. The calls:



turn on and off, respectively, automatic transaction begins, commits or aborts for the six ISAM update routines listed above. When turned on, automatic transactions start a transaction at the beginning of each of these six ISAM update routines if, and only if, no transaction is already active. Upon successful conclusion of these ISAM updates, the transaction is committed. If an error occurs, the transaction is aborted. Of course, these automatic commits or aborts are only invoked if an automatic transaction was started at the beginning of the ISAM update routine.

Assuming SetOperationState(OPS_AUTOISAM_TRN,OPS_STATE_ON) has been called and that an update on a transaction processed file is to be performed without an explicit call to Begin, then the system behavior is as follows:

  1. An automatic transaction will not free locks acquired outside the automatic transaction, unless the lock is on an item updated or locked in the transaction. This is similar to ctKEEP_OUT behavior as explained in the Begin function description.
  2. An aborted automatic transaction, which occurs when the update returns an error, always releases locks acquired in the transaction.
  3. If the LockISAM() state is ctENABLE or ctENABLE_BLK, or these states have been restored via LockISAM(ctRESTORE), or ctRESTORE_BLK, respectively, an automatic transaction will not free any locks on commit, similar to Commit(ctKEEP) or Abort(ctKEEP_OUT).

If OPS_UNLOCK_UPD is on, both commits and aborts on automatic transactions behave according to ctKEEP_OUT, regardless of the LockISAM() state.

OPS_TRACK_MON - Causes the net count of memory allocation requests to be output upon each calling of SetOperationState().



Turning on the tracking via SetOperationState() uses a default threshold value of 250. Each such call to SetOperationState(), in addition to each time the threshold value is encountered, increasing or decreasing, produces a debug line of output to STDOUT, typically the c-tree Server console screen, detailing the current net allocation count. Override the threshold value by placing the keyword MEMORY_TRACK in the c-tree Server configuration file. This feature is intended for dynamically tracking the c-tree Server memory consumption.

OPS_LOCK_MON - Enables the lock monitor whether or not the configuration file contains LOCK_MONITOR. If there is no configuration entry, the threshold value is set to 100. SetOperationState(OPS_LOCK_MON,OPS_STATE_OFF) turns off the lock monitor. When SetOperationState() is called to turn the monitor on or off, and each time the threshold value is encountered, increasing or decreasing, a message specifying the current number of excess locks is sent to the c-tree Server console. The net lock count is always maintained. Therefore, if a monitor is subsequently turned on by SetOperationState(), the current lock count will be correct. There is almost no overhead to maintain this value: only a simple increment or decrement on each lock or unlock. This function is useful for assuring proper locking operation.

OPS_MIRROR_TRM - When the mirror error handling protocol is not changed via OPS_MIRROR_NOSWITCH, if a primary or mirror fails, causing the c-tree Server to go on using only one file, the OPS_MIRROR_TRM bit is set in status_word. It can be tested as follows:

if (SetOperationState((LONG)0,OPS_STATE_RET) & OPS_MIRROR_TRM)

printf("System continuing with a primary or mirror failure.");

OPS_SERIAL_UPD - When turned on causes GetSerialNbr() to return a unique serial number. This mode allows manual serialization of the data by the application. GetSerialNbr() normally returns the current value of the file’s serial number.

Note: FairCom does not recommend this option. Corrupt files may contain an improper last-used-value in the header after a rebuild operation. When serial numbers are included in records via the serial number key segment mode, rebuild determines the highest used serial number and resets the value in the header.

For transaction controlled files, a transaction must be active to call GetSerialNbr() when OPS_SERIAL_UPD has been turned on.

OPS_DEFER_CLOSE - Defers a file closes or deletes requested during transactions. By default, a file close or delete request during a transaction returns CPND_ERR (588). Turning on the defer option allows the function to return NO_ERROR (0) and continue, while the actual close or delete is deferred until the end of the transaction.

OPS_CONV_STRING - For a data record containing CT_STRING field data in the fixed length portion of the record buffer, if the CT_STRING data is padded with null (0x0) bytes, and if a c-tree client reads the data from a c-tree Server whose system’s byte order differs from the client system’s byte ordering, the values of fields that follow the CT_STRING fields may be incorrectly reversed.

In heterogeneous environments, the c-tree client code reverses binary fields in the record buffer when reading data records. A CT_STRING field is considered to end when the first null byte is encountered. If an application pads a CT_STRING field with multiple null bytes, the c-tree client’s scanning logic stops scanning the field at the first null byte and considers the next field to begin with the second null byte. The client logic will then reverse the wrong bytes in the data record buffer.Enables the client logic to scan a c-tree data file’s field definitions when the client code reads the DODA from the data file. When enabled, the client logic will change all CT_STRING fields having a non-zero field length in the fixed length portion of the record buffer to CT_STRING fields.

OPS_DISK_IO - Uses sysiocod to indicate if the previous function call to the Server generated any read and/or write activity for data and/or index files. sysiocod is only set if the previous call did not itself cause a sysiocod return value.

A sysiocod between -1015 and -1000 indicates that the feature is on, and no other sysiocod value occurred. There are sixteen possible return values, defined as:


Symbolic Constant




Index read from disk.



Data read from disk.



Index write to disk.



Data write to disk.

A return of -1000 means no data or index disk activity, though there still may have been activity in transaction logs and other Server files. A return of -1015 means there were read AND writes on both data and index files.

This statement prints a message as shown:

if (sysiocod <= -ctDISKIObase && (((-sysiocod) - ctDISKIObase)& ctDISKIO_DATW))

printf(“One or more data file writes to disk\n”);


printf(“No data file write to disk\n”);

OPS_AUTOISAM_TRN - Permits individual ISAM updates to be performed within an automatically initiated transaction. The purpose of this option is to avoid the network overhead of the TRANBEG and TRANEND calls. (If a transaction has already been initiated by the application, then no automatic transaction is attempted.)

Prior to the introduction of this option, the automatic commit would free any lock involved in the transaction unless LKISAM(ENABLE) or LKISAM(ENABLE_BLK) was already in effect and OPS_UNLOCK_ADD or OPS_UNLOCK_RWT were not in effect. If an application desired to hold the lock after the automatic commit, LKISAM(ENABLE) would have to be called first; but this caused the same network overhead as the TRANBEG.

The SETOPS option, OPS_KEEPLOK_TRN, causes the locks involved in automatic transactions for adds and rewrites to be kept after the automatic commit. Delete operations still have the locks freed.

OPS_LOCLON_ADD_BLK When a table lock is in effect, a record add call by a connection that is not holding the table lock fails with error DLOK_ERR and sysiocod of DLKT_COD if that connection has not enabled the ISAM blocking write lock mode. Calling LKISAM(ctENABLE_BLK) before adding the record avoids the error, but it requires an additional call to the server, plus another call after the record add call in order to restore the original lock mode. The c-tree client library and c-tree Server now support a new SETOPS() mode that can be used to enable the blocking write lock mode during the record add call and then restore the original lock mode, all in a single call to the server.

To use this feature, call SETOPS(OPS_LOCKON_ADD_BLK, OPS_STATE_ON) before calling the record add function [ADDREC() or ADDVREC()]. The SETOPS() call sets a bit on the client side and returns to the caller without making a call to the server. This bit is passed to the server on the next record add call. The server and client library turn off this mode when the record add call completes, so it applies only to the first record add call that is made after turning on this option. For this reason, it's recommended to enable this mode right before the call to add the record to which you want this mode to apply.

The record read functions that check and turn off the OPS_LOCKON_GET and OPS_LOCKON_BLK modes ignore this new mode. And the record add functions that check and turn off the OPS_LOCKON_ADD_BLK mode ignore the OPS_LOCKON_GET and OPS_LOCKON_BLK modes.


SetOperationState() returns the present state of the operation status word. On return, uerr_cod is set to one of the following


Symbolic Constant




Successful operation.



Bad operation_code parameter or status_word contains illegal bit fields.

See c-tree Error Codes for a complete listing of valid c-tree error values.

See also

GetSerialNbr(), AddRecord(), AddVRecord(), DeleteRecord(), DeleteVRecord(), ReWriteRecord(), ReWriteVRecord(), LockISAM(), FirstRecord(), ReadData(), SystemMonitor(), Abort(), Commit(), Begin()