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

  1. /*
  2.  *    Turbo C CTCLIB.C module
  3.  *
  4.  *    This sample is setup for the MS-DOS 3.1/2/3 Operating System
  5.  *    and the BORLAND INTERNATIONAL TURBO C Compiler. 
  6.  *      (It will also run in  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.  *    (MS-DOS is a trademark of Microsoft)
  22.  *
  23.  *    This program is the CONFIDENTIAL and PROPRIETARY property 
  24.  *    of FairCom(R) Corporation. Any unauthorized use, reproduction or
  25.  *    transfer of this program is strictly prohibited.
  26.  *
  27.  *      Copyright (c) 1985, 1986, 1987, 1988, 1989 FairCom
  28.  *    (Subject to limited distribution and
  29.  *     restricted disclosure only.)
  30.  *    *** ALL RIGHTS RESERVED ***
  31.  *
  32.  *    4006 West Broadway
  33.  *    Columbia, MO 65203
  34.  *
  35.  *
  36.  *    c-tree(R)    Version 4.3
  37.  *            Release C
  38.  *            February 7, 1989 17:30
  39.  *
  40.  */
  41.  
  42. #include "ctstdr.h"        /* standard i/o header         */
  43. #undef   EXTERN
  44. #define  EXTERN /* */
  45. #include "ctoptn.h"        /* c-tree configuration options */
  46. #include "cterrc.h"        /* c-tree error codes        */
  47. #include "ctstrc.h"        /* c-tree data structures    */
  48. #include "ctgvar.h"        /* c-tree global variables    */
  49.  
  50. #include <share.h>          /* From Borland            */
  51. #include <stat.h>          /* From Borland            */
  52.  
  53. #define    INFINITY    3000    /* loop termination count waiting for lock */
  54. #define LEFT_SHIFT    24    /* controls dummy lock capacity */
  55.                 /* 25 => 62  files: 32M fixed records or */
  56.                 /*            32MB var len file    */
  57.                 /* 24 => 126 files: 16M fixed records or */
  58.                 /*            16MB var len file    */
  59.                 /* 23 => 254 files:  8M fixed records or */
  60.                 /*             8MB var len file    */
  61.                 /* 22 => 510 files:  4M fixed records or */
  62.                 /*             4MB var len file    */
  63.  
  64. COUNT ctseek(),uerr();
  65.    
  66. RNDFILE mbopen(ctnum,opmode)
  67. PFAST CTFILE *ctnum;
  68. COUNT opmode;    /* EXCLUSIVE or SHARED */
  69. {
  70.     RNDFILE retval;
  71.     int     acflag,shflag;
  72.  
  73.     COUNT vtclose();
  74.  
  75.     ctnum->sekpos = 0L;
  76.     acflag          = BUPDATE;
  77. #ifdef FPUTFGET
  78.     if (opmode & SHARED)
  79.         shflag = SH_DENYNO;
  80.     else if (opmode & READFIL) {
  81.         shflag = SH_DENYWR;
  82.         acflag = (O_BINARY | O_RDONLY);
  83.     } else
  84.         shflag = SH_DENYRW;
  85. #else
  86.     shflag = 0;
  87. #endif
  88.  
  89.     if (!(opmode & PERMANENT) && ct_numvfil >= MAXVFIL)
  90.         vtclose();
  91.  
  92.     if ((retval = _open(ctnum->flname,(acflag | shflag))) < 0)
  93.         if (vtclose() == YES)
  94.             retval = _open(ctnum->flname,(acflag | shflag));
  95.  
  96.     if (!(opmode & PERMANENT) && retval >= 0)
  97.         ct_numvfil++;
  98.  
  99.     return(retval);
  100. }
  101.  
  102. /* ------------------------------------------------------------ */
  103.  
  104. RNDFILE mbcrat(ctnum)
  105. PFAST CTFILE *ctnum;
  106. {
  107.     RNDFILE retval;
  108.  
  109.     COUNT vtclose();
  110.  
  111.     ctnum->sekpos = 0L;
  112.     if (!(ctnum->flmode & PERMANENT) && ct_numvfil >= MAXVFIL)
  113.         vtclose();
  114.  
  115.     if ((retval = open(ctnum->flname,
  116.         BCREATE,(S_IREAD | S_IWRITE))) < 0)
  117.         if (vtclose() == YES)
  118.             retval = open(ctnum->flname,
  119.                 BCREATE,
  120.                 (S_IREAD | S_IWRITE));
  121.  
  122.     if (!(ctnum->flmode & PERMANENT) && retval >= 0)
  123.         ct_numvfil++;
  124.  
  125.     return(retval);
  126. }
  127.  
  128. /* ------------------------------------------------------------ */
  129.  
  130. COUNT mbsave(ctnum)
  131. PFAST CTFILE *ctnum;
  132. {
  133.     COUNT   mbclos();
  134.     RNDFILE mbopen();
  135.  
  136.     if (mbclos(ctnum,ctnum->flmode))
  137.         return(uerr(FSAV_ERR));
  138.     else if ((ctnum->fd = mbopen(ctnum,ctnum->flmode)) < 0)
  139.         return(uerr(FSAV_ERR));
  140.     else
  141.         return(NO_ERROR);
  142. }
  143.  
  144. VOID flushdos(datno)
  145. COUNT         datno;
  146. {
  147.     bdos(13,0,0);
  148. }
  149.  
  150. #ifndef CTSERVER
  151.  
  152. /* --------------------------------------------------------------------
  153.    LOCK index node
  154.  */
  155.  
  156. COUNT LOCK(node,knum)    /* node == 0  => header */
  157. LONG    node;
  158. PFAST KEYFILE *knum;
  159. {
  160.  
  161. /*
  162.  * c-tree node locking protocol is guaranteed to be deadlock free. Therefore,
  163.  * if a lock is unsucessful, this routine forces a short delay and then 
  164.  * attempts the lock again.  The INFINITY parameter allows one to avoid
  165.  * an infinite loop if there is a bug in the lock routines.  Theoretically,
  166.  * the while loop should never run indefinitely.
  167.  */
  168.  
  169.  
  170. #ifdef FPUTFGET
  171.  
  172.     COUNT dummy,tries;
  173.  
  174.     tries = 0;
  175.     knum -= knum->kmem;
  176.     if (!(knum->flmode & NONEXCLUSIVE))
  177.         return(NO_ERROR);
  178.  
  179. /*
  180.  * Notice how a lock region is converted to a phantom region of the dummy
  181.  * file and the lock is applied to file zero (whose control structure is
  182.  * pointed to by the global variable ct_key).
  183.  */
  184.     if (knum->clstyp != VAT_CLOSE)
  185.         node /= knum->recsiz;
  186.     node |= ((LONG) knum->filnum << LEFT_SHIFT);
  187.     while (lock(ct_key->fd,node,1L))
  188.         if (tries++ > INFINITY)
  189.             return(uerr(LNOD_ERR));
  190.         else
  191.             /* delay and try again */
  192.             for (dummy = 0; dummy++ < INFINITY; )
  193.                 ;
  194.     return(NO_ERROR);
  195. #else
  196.     return(NO_ERROR);
  197. #endif
  198.  
  199. }
  200.  
  201. /* --------------------------------------------------------------------
  202.    UNLOCK index file node
  203. */
  204.  
  205. COUNT UNLOCK(node,knum)
  206. LONG    node;
  207. PFAST KEYFILE *knum;
  208. {
  209.  
  210. #ifdef FPUTFGET
  211.     knum -= knum->kmem;
  212.     if (!(knum->flmode & NONEXCLUSIVE))
  213.         return(NO_ERROR);
  214.  
  215.     if (knum->clstyp != VAT_CLOSE)
  216.         node /= knum->recsiz;
  217.     node |= ((LONG) knum->filnum << LEFT_SHIFT);
  218.     if (unlock(ct_key->fd,node,1L))
  219.         return(uerr(UNOD_ERR));
  220.     else
  221.         return(NO_ERROR);
  222. #else
  223.     return(NO_ERROR);
  224. #endif
  225.  
  226. }
  227.  
  228.  
  229. /* --------------------------------------------------------------------
  230.    LOCK data record
  231.  */
  232.  
  233. COUNT DLOCK(recbyt,dnum)        /* recbyt == 0  => header record */
  234. POINTER        recbyt;
  235. PFAST DATFILE  *dnum;
  236. {
  237.  
  238. /*
  239.  * the data record ct_locks are NOT guaranteed to be deadlock free.  Therefore,
  240.  * except for the header record which is only locked by internal c-tree 
  241.  * maintenance requests, the data record lock routine returns instead of
  242.  * looping when a lock is denied because of a competing lock.  The application
  243.  * program must deal with the appropriate action if a lock is denied to a
  244.  * data record.
  245.  */
  246.  
  247. #ifdef FPUTFGET
  248.     COUNT dummy,tries,test;
  249.     LONG  actbyt;
  250.  
  251.     if (!(dnum->flmode & NONEXCLUSIVE))
  252.         return(NO_ERROR);
  253.  
  254.     actbyt  = recbyt;
  255.     tries   = 0;
  256.     if (dnum->clstyp != VAT_CLOSE)
  257.         recbyt /= dnum->reclen;
  258.     recbyt |= ((LONG) dnum->filnum << LEFT_SHIFT);
  259.     while ((test = lock(ct_key->fd,recbyt,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 (unlock(ct_key->fd,recbyt,1L))
  302.         return(uerr(UDLK_ERR));
  303.     else
  304.         return(NO_ERROR);
  305.  
  306. #else
  307.     return(NO_ERROR);
  308. #endif
  309.  
  310. }
  311.  
  312. #endif
  313.  
  314. /* end of ctclib.tc */
  315.