home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c004 / 2.ddi / LC / CTCLIB.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-04-18  |  7.6 KB  |  317 lines

  1. /*
  2.  *    Lattice C CTCLIB.C module
  3.  *
  4.  *    This sample is setup for the MS-DOS 3.1/2/3 Operating System
  5.  *    and the Lattice Version 3 C Compiler. (It will also run in
  6.  *    DOS 2 and DOS 3.0 environments.)
  7.  *
  8.  *    Due to the highly restrictive nature of the DOS 3.1 locking protocols
  9.  *    (i.e., you cannot READ a region of a file locked by another process),
  10.  *    we have provided a work-around which requires a dummy file as file
  11.  *    number zero. In particular, the zeroth data file of each ISAM parameter
  12.  *    file should be a dummy file, have a record length of 128 bytes, 
  13.  *     and file mode parameters indicating a SHARED, PERMANENT, FIXED length 
  14.  *    file. Then, instead of actually locking the files in use, c-tree will
  15.  *    place ct_locks on corresponding regions of the dummy file.
  16.  *
  17.  *    Due to the use of a dummy lock file, it is not necessary for the
  18.  *    lock routines to increment and decrement the lokcnt member which
  19.  *    is used for checking virtual files.
  20.  *
  21.  *    This program is the CONFIDENTIAL and PROPRIETARY property 
  22.  *    of FairCom(R) Corporation. Any unauthorized use, reproduction or
  23.  *    transfer of this program is strictly prohibited.
  24.  *
  25.  *      Copyright (c) 1985, 1986, 1987, 1988, 1989 FairCom
  26.  *    (Subject to limited distribution and
  27.  *     restricted disclosure only.)
  28.  *    *** ALL RIGHTS RESERVED ***
  29.  *
  30.  *    4006 West Broadway
  31.  *    Columbia, MO 65203
  32.  *
  33.  *
  34.  *    c-tree(R)    Version 4.3
  35.  *            Release C
  36.  *            February 7, 1989 17:30
  37.  *
  38.  */
  39.  
  40. #include "ctstdr.h"        /* standard i/o header         */
  41. #undef   EXTERN
  42. #define  EXTERN /* */
  43. #include "ctoptn.h"        /* c-tree configuration options */
  44. #include "cterrc.h"        /* c-tree error codes        */
  45. #include "ctstrc.h"        /* c-tree data structures    */
  46. #include "ctgvar.h"        /* c-tree global variables    */
  47.  
  48. #include <unlstd.h>        /* ----    FROM LATTICE    ---- */
  49.  
  50. #define    INFINITY    3000    /* loop termination count waiting for lock */
  51. #define LEFT_SHIFT    24    /* controls dummy lock capacity */
  52.                 /* 25 => 62  files: 32M fixed records or */
  53.                 /*            32MB var len file    */
  54.                 /* 24 => 126 files: 16M fixed records or */
  55.                 /*            16MB var len file    */
  56.                 /* 23 => 254 files:  8M fixed records or */
  57.                 /*             8MB var len file    */
  58.                 /* 22 => 510 files:  4M fixed records or */
  59.                 /*             4MB var len file    */
  60.  
  61. COUNT ctseek(),uerr();
  62.    
  63. RNDFILE mbopen(ctnum,opmode)
  64. PFAST CTFILE *ctnum;
  65. COUNT opmode;    /* EXCLUSIVE or SHARED */
  66. {
  67.     RNDFILE retval;
  68.     int     acflag,shflag;
  69.  
  70.     COUNT vtclose();
  71.  
  72.     ctnum->sekpos = 0L;
  73.     acflag          = BUPDATE;
  74. #ifdef FPUTFGET
  75.     if (opmode & SHARED)
  76.         shflag = O_SDN;
  77.     else if (opmode & READFIL) {
  78.         shflag = O_SDW;
  79.         acflag = (O_RAW | O_RDONLY);
  80.     } else
  81.         shflag = O_SDRW;
  82. #else
  83.     shflag = 0;
  84. #endif
  85.  
  86.     if (!(opmode & PERMANENT) && ct_numvfil >= MAXVFIL)
  87.         vtclose();
  88.  
  89.     if ((retval = open(ctnum->flname,acflag | shflag)) < 0)
  90.         if (vtclose() == YES)
  91.             retval = open(ctnum->flname,acflag | shflag);
  92.  
  93.     if (!(opmode & PERMANENT) && retval >= 0)
  94.         ct_numvfil++;
  95.  
  96.     return(retval);
  97. }
  98.  
  99. /* ------------------------------------------------------------ */
  100.  
  101. RNDFILE mbcrat(ctnum)
  102. PFAST CTFILE *ctnum;
  103. {
  104.     RNDFILE retval;
  105.  
  106.     COUNT vtclose();
  107.  
  108.     ctnum->sekpos = 0;
  109.     if (!(ctnum->flmode & PERMANENT) && ct_numvfil >= MAXVFIL)
  110.         vtclose();
  111.  
  112.     if ((retval = creat(ctnum->flname,BCREATE)) < 0)
  113.         if (vtclose() == YES)
  114.             retval = creat(ctnum->flname,BCREATE);
  115.  
  116.     if (!(ctnum->flmode & PERMANENT) && retval >= 0)
  117.         ct_numvfil++;
  118.  
  119.     return(retval);
  120. }
  121.  
  122. /* ------------------------------------------------------------ */
  123.  
  124. COUNT mbsave(ctnum)
  125. PFAST CTFILE *ctnum;
  126. {
  127.     COUNT   mbclos();
  128.     RNDFILE mbopen();
  129.  
  130.     if (mbclos(ctnum,ctnum->flmode))
  131.         return(uerr(FSAV_ERR));
  132.     else if ((ctnum->fd = mbopen(ctnum,ctnum->flmode)) < 0)
  133.         return(uerr(FSAV_ERR));
  134.     else
  135.         return(NO_ERROR);
  136. }
  137.  
  138. VOID flushdos(datno)
  139. COUNT         datno;
  140. {
  141.     bdos(13,0);
  142. }
  143.  
  144. #ifndef CTSERVER
  145.  
  146. /* --------------------------------------------------------------------
  147.    LOCK index node
  148.  */
  149.  
  150. COUNT LOCK(node,knum)    /* node == 0  => header */
  151. LONG    node;
  152. PFAST KEYFILE *knum;
  153. {
  154.  
  155. /*
  156.  * c-tree node locking protocol is guaranteed to be deadlock free. Therefore,
  157.  * if a lock is unsucessful, this routine forces a short delay and then 
  158.  * attempts the lock again.  The INFINITY parameter allows one to avoid
  159.  * an infinite loop if there is a bug in the lock routines.  Theoretically,
  160.  * the while loop should never run indefinitely.
  161.  */
  162.  
  163.  
  164. #ifdef FPUTFGET
  165.  
  166.     COUNT dummy,tries;
  167.  
  168.     tries = 0;
  169.     knum -= knum->kmem;
  170.     if (!(knum->flmode & NONEXCLUSIVE))
  171.         return(NO_ERROR);
  172.  
  173. /*
  174.  * Notice how a lock region is converted to a phantom region of the dummy
  175.  * file and the lock is applied to file zero (whose control structure is
  176.  * pointed to by the global variable ct_key).
  177.  */
  178.     if (knum->clstyp != VAT_CLOSE)
  179.         node /= knum->recsiz;
  180.     node |= ((LONG) knum->filnum << LEFT_SHIFT);
  181.     if (ctseek(ct_key,node))
  182.         return(uerr(SEEK_ERR));
  183.     while (lockf(ct_key->fd,F_TLOCK,1L))
  184.         if (tries++ > INFINITY)
  185.             return(uerr(LNOD_ERR));
  186.         else
  187.             /* delay and try again */
  188.             for (dummy = 0; dummy++ < INFINITY; )
  189.                 ;
  190.     return(NO_ERROR);
  191. #else
  192.     return(NO_ERROR);
  193. #endif
  194.  
  195. }
  196.  
  197. /* --------------------------------------------------------------------
  198.    UNLOCK index file node
  199. */
  200.  
  201. COUNT UNLOCK(node,knum)
  202. LONG    node;
  203. PFAST KEYFILE *knum;
  204. {
  205.  
  206. #ifdef FPUTFGET
  207.     knum -= knum->kmem;
  208.     if (!(knum->flmode & NONEXCLUSIVE))
  209.         return(NO_ERROR);
  210.  
  211.     if (knum->clstyp != VAT_CLOSE)
  212.         node /= knum->recsiz;
  213.     node |= ((LONG) knum->filnum << LEFT_SHIFT);
  214.     if (ctseek(ct_key,node))
  215.         return(uerr(SEEK_ERR));
  216.     else if (lockf(ct_key->fd,F_ULOCK,1L))
  217.         return(uerr(UNOD_ERR));
  218.     else
  219.         return(NO_ERROR);
  220. #else
  221.     return(NO_ERROR);
  222. #endif
  223.  
  224. }
  225.  
  226.  
  227. /* --------------------------------------------------------------------
  228.    LOCK data record
  229.  */
  230.  
  231. COUNT DLOCK(recbyt,dnum)        /* recbyt == 0  => header record */
  232. POINTER        recbyt;
  233. PFAST DATFILE  *dnum;
  234. {
  235.  
  236. /*
  237.  * the data record locks are NOT guaranteed to be deadlock free.  Therefore,
  238.  * except for the header record which is only locked by internal c-tree 
  239.  * maintenance requests, the data record lock routine returns instead of
  240.  * looping when a lock is denied because of a competing lock.  The application
  241.  * program must deal with the appropriate action if a lock is denied to a
  242.  * data record.
  243.  */
  244.  
  245. #ifdef FPUTFGET
  246.     COUNT dummy,tries,test;
  247.     LONG  actbyt;
  248.  
  249.     if (!(dnum->flmode & NONEXCLUSIVE))
  250.         return(NO_ERROR);
  251.  
  252.     actbyt  = recbyt;
  253.     tries   = 0;
  254.     if (dnum->clstyp != VAT_CLOSE)
  255.         recbyt /= dnum->reclen;
  256.     recbyt |= ((LONG) dnum->filnum << LEFT_SHIFT);
  257.     if (ctseek(ct_key,recbyt))
  258.         return(uerr(SEEK_ERR));
  259.     while ((test = lockf(ct_key->fd,F_TLOCK,1L)) &&
  260.         actbyt == DRNZERO) /* i.e., the header record is locked */ 
  261.         if (tries++ > INFINITY)
  262.             return(uerr(DLOK_ERR));
  263.         else
  264.             /* delay and try again */
  265.             for (dummy = 0; dummy++ < INFINITY; )
  266.                 ;
  267.  
  268.     if (!test)            /* lock request is successful!  */
  269.         return(NO_ERROR);
  270.     else 
  271.         return(uerr(DLOK_ERR));
  272. #else
  273.     return(NO_ERROR);
  274. #endif
  275.  
  276. }
  277.  
  278. COUNT RLOCK(recbyt,dnum)
  279. POINTER        recbyt;
  280. PFAST DATFILE  *dnum;
  281. {
  282.     return(NO_ERROR);
  283. }
  284.  
  285. /* --------------------------------------------------------------------
  286.    UNLOCK data record
  287. */
  288.  
  289. COUNT UDLOCK(recbyt,dnum)
  290. POINTER        recbyt;
  291. PFAST DATFILE  *dnum;
  292. {
  293.  
  294. #ifdef FPUTFGET
  295.     if (!(dnum->flmode & NONEXCLUSIVE))
  296.         return(NO_ERROR);
  297.  
  298.     if (dnum->clstyp != VAT_CLOSE)
  299.         recbyt /= dnum->reclen;
  300.     recbyt |= ((LONG) dnum->filnum << LEFT_SHIFT);
  301.     if (ctseek(ct_key,recbyt))
  302.         return(uerr(SEEK_ERR));
  303.     if (lockf(ct_key->fd,F_ULOCK,1L))
  304.         return(uerr(UDLK_ERR));
  305.     else
  306.         return(NO_ERROR);
  307.  
  308. #else
  309.     return(NO_ERROR);
  310. #endif
  311.  
  312. }
  313.  
  314. #endif
  315.  
  316. /* end of ctclib.lc3 */
  317.