BlockingISAMRead

c-tree ISAM function to support a blocking record read.

Short Name

BLKIREC()

Type

ISAM function

Declaration

COUNT BlockingISAMRead(FILNO filno,NINT opcode,LONG timeoutsec,
    pTEXT blockcond,pVOID target,pVOID recptr,pVRLEN plen)

Description

In V12 the file number typedef was formally changed from COUNT, a two-byte value to FILNO, a four-byte value. Refer to this link for compatibility details. Four Byte File Numbering

A blocking record read permits an application to attempt to read a record, and if no existing record satisfy the read request, BlockingISAMRead() blocks until such a record exists or the times out period expires.

BlockingISAMRead() supports blocking ISAM reads on fixed or variable-length records subject to an optional blocking condition that may be a logical expression or a function callback, just as in a set filter call (SETFLTR()).

  • filno is a file number of an open c-tree data or index file.
  • opcode specifies one of the following ISAM read operations:
ISAM Read Operation Explanation
ctBLKIREC_FIRST Read first record in physical or key order
ctBLKIREC_NEXT Read next record in physical or key order
ctBLKIREC_PREV Read previous record in physical or key order
ctBLKIREC_LAST Read last record in physical or key order
ctBLKIREC_GT Read record with key value greater than target key
ctBLKIREC_GTE Read record with key value greater than or equal to target key
ctBLKIREC_EQL Read record with key value equal to target key
ctBLKIREC_LTE Read record with key value less than or equal to target key
ctBLKIREC_LT Read record with key value less than target key
  • timeoutsec specifies the number of seconds the blocking read will wait before returning if no record satisfies the optional blockcond argument or no record is found. Set timeoutsec to zero to return immediately.
  • blockcond is an optional conditional expression which may be a logical expression of the same form as used for conditional index support or a function callback as in a SetDataFilter() call. Set blockcond to an empty string ("") to specify no condition.
  • target should be non-NULL only if filno specifies an index and the opcode requires a target value (for example, ctBLKIREC_GT).
  • The record is read into the buffer pointed to by recptr.
  • plen should be NULL for a fixed-length read, and should point to the length of the output buffer (recptr) for a variable-length read. *plen is updated to the actual record length upon successful return.

The function operates by performing the requested ISAM operation (FIRST(), NEXT(), etc.). If the requested ISAM operation successful, BlockingISAMRead() then sees if the optional blocking condition is satisfied. If no record was found or if the record does not satisfy the blocking condition, and timeoutsec is non-zero, then the read blocks (sleeps) for timeoutsec. The sleep is interrupted if the target file is updated, and this process repeats until a record is found that satisfies the condition, or the block times out. A time out condition is indicated by returning NTIM_ERR (156). BlockingISAMRead() requires server notification support to operate correctly.

Return

Value Symbolic Constant Explanation
0 NO_ERROR No error occurred.
156 NTIM_ERR Timeout error

See FairCom DB Error Codes for a complete listing of valid FairCom DB error values.

Example

struct {
    TEXT    job_name[256];
        .....
    LONG    start_time;
            .....
} JOBMAN;
TEXT    blockcond[128];
ChangeISAMContext
/*
** setting the first character to zero means no
** blocking condition
*/
blockcond[0] = '\0';

start:
    rc = BLKIREC( keyno, ctBLKIREC_FIRST, WAITTIME, blockcond,  NULL, &JOBMAN, NULL);
    if (rc == NTIM_ERR) {
        /* time out occurred. check whether to continue
         ** job management processing
         */
        if **continue** {
            blockcond[0]= '\0';
            goto start;
        } else
            goto end;
    } else if (rc) {
        /* unexpected error */
        handle possible error conditions
         [examin BLKIREC source for possible error cases]
    } else {
        /* found job record. check job start time */
        if **JOBMAN.start_time <= current_time** {
            launch job
            update record (so no longer at front of file)
            blockcond[0] = '\0';
            goto start;
        } else {
            /*
             ** job not ready to run yet. create a
             ** blocking condition so that if a job with
             ** an earlier time is added to the job file
             ** the BLKIREC will return
             */
            ctrt_sprintf(blockcond, "start_time < %ld",JOBMAN.start_time);
            goto start;
        }
    }
end:

See also

To double performance, see ChangeISAMContext.