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

  1. /*
  2.  *    CTCLIB.C module for Microsoft C Compilers
  3.  *
  4.  *    This sample is setup for the MS-DOS 3.1/2/3 Operating Systems
  5.  *    and the MICROSOFT (Version 3 / 4 / 5) 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.  *    (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 <sys\types.h>        /* **************************** */
  51. #include <share.h>        /* ----          FROM         ---- */
  52. #include <sys\locking.h>    /* ----     MICROSOFT      ---- */
  53. #include <sys\stat.h>        /* **************************** */
  54.  
  55. #define    INFINITY    3000    /* loop termination count waiting for lock */
  56. #define LEFT_SHIFT    24    /* controls dummy lock capacity */
  57.                 /* 25 => 62  files: 32M fixed records or */
  58.                 /*            32MB var len file    */
  59.                 /* 24 => 126 files: 16M fixed records or */
  60.                 /*            16MB var len file    */
  61.                 /* 23 => 254 files:  8M fixed records or */
  62.                 /*             8MB var len file    */
  63.                 /* 22 => 510 files:  4M fixed records or */
  64.                 /*             4MB var len file    */
  65.  
  66. COUNT ctseek(),uerr();
  67.  
  68. RNDFILE mbopen(ctnum,opmode)
  69. PFAST CTFILE  *ctnum;
  70. COUNT             opmode;    /* EXCLUSIVE or SHARED */
  71. {
  72.     RNDFILE retval;
  73.     int     acflag,shflag;
  74.  
  75.     COUNT vtclose();
  76.  
  77.     ctnum->sekpos = DRNZERO;
  78.     acflag          = BUPDATE;
  79. #ifdef FPUTFGET
  80.     if (opmode & SHARED)
  81.         shflag = SH_DENYNO;
  82.     else if (opmode & READFIL) {
  83.         shflag = SH_DENYWR;
  84.         acflag = (O_BINARY | O_RDONLY);
  85.     } else
  86.         shflag = SH_DENYRW;
  87. #else
  88.     shflag = 0;
  89. #endif
  90.  
  91.     if (!(opmode & PERMANENT) && ct_numvfil >= MAXVFIL)
  92.         vtclose();
  93.  
  94.     if ((retval = sopen(ctnum->flname,acflag,shflag)) < 0)
  95.         if (vtclose() == YES)
  96.             retval = sopen(ctnum->flname,acflag,shflag);
  97.  
  98.     if (!(opmode & PERMANENT) && retval >= 0)
  99.         ct_numvfil++;
  100.  
  101.     return(retval);
  102. }
  103.  
  104. /* ------------------------------------------------------------ */
  105.  
  106. RNDFILE mbcrat(ctnum)
  107. PFAST CTFILE  *ctnum;
  108. {
  109.     RNDFILE retval;
  110.  
  111.     COUNT vtclose();
  112.  
  113.     ctnum->sekpos = DRNZERO;
  114.     if (!(ctnum->flmode & PERMANENT) && ct_numvfil >= MAXVFIL)
  115.         vtclose();
  116.  
  117.     if ((retval = open(ctnum->flname,
  118.         BCREATE,(S_IREAD | S_IWRITE))) < 0)
  119.         if (vtclose() == YES)
  120.             retval = open(ctnum->flname,
  121.                 BCREATE,
  122.                 (S_IREAD | S_IWRITE));
  123.  
  124.     if (!(ctnum->flmode & PERMANENT) && retval >= 0)
  125.         ct_numvfil++;
  126.  
  127.     return(retval);
  128. }
  129.  
  130. /* ------------------------------------------------------------ */
  131.  
  132. COUNT mbsave( ctnum)
  133. PFAST CTFILE *ctnum;
  134. {
  135.     COUNT   mbclos();
  136.     RNDFILE mbopen();
  137.  
  138.     if (mbclos(ctnum,ctnum->flmode))
  139.         return(uerr(FSAV_ERR));
  140.     else if ((ctnum->fd = mbopen(ctnum,ctnum->flmode)) < 0)
  141.         return(uerr(FSAV_ERR));
  142.     else
  143.         return(NO_ERROR);
  144. }
  145.  
  146. VOID flushdos(datno)
  147. COUNT         datno;
  148. {
  149.     bdos(13,0,0);
  150. }
  151.  
  152. #ifndef CTSERVER
  153.  
  154. /* --------------------------------------------------------------------
  155.    LOCK index node
  156.  */
  157.  
  158. COUNT LOCK(node,knum)    /* node == 0  => header */
  159. LONG       node;
  160. PFAST KEYFILE  *knum;
  161. {
  162.  
  163. /*
  164.  * c-tree node locking protocol is guaranteed to be deadlock free. Therefore,
  165.  * if a lock is unsucessful, this routine forces a short delay and then 
  166.  * attempts the lock again.  The INFINITY parameter allows one to avoid
  167.  * an infinite loop if there is a bug in the lock routines.  Theoretically,
  168.  * the while loop should never run indefinitely.
  169.  */
  170.  
  171.  
  172. #ifdef FPUTFGET
  173.  
  174.     COUNT dummy,tries;
  175.  
  176.     tries = 0;
  177.     knum -= knum->kmem;
  178.     if (!(knum->flmode & NONEXCLUSIVE))
  179.         return(NO_ERROR);
  180.  
  181. /*
  182.  * Notice how a lock region is converted to a phantom region of the dummy
  183.  * file and the lock is applied to file zero (whose control structure is
  184.  * pointed to by the global variable ct_key).
  185.  */
  186.     if (knum->clstyp != VAT_CLOSE)
  187.         node /= knum->recsiz;
  188.     node |= ((LONG) knum->filnum << LEFT_SHIFT);
  189.     if (ctseek(ct_key,node))
  190.         return(uerr(SEEK_ERR));
  191.     while (locking(ct_key->fd,LK_NBLCK,1L))
  192.         if (tries++ > INFINITY)
  193.             return(uerr(LNOD_ERR));
  194.         else
  195.             /* delay and try again */
  196.             for (dummy = 0; dummy++ < INFINITY; )
  197.                 ;
  198.     return(NO_ERROR);
  199. #else
  200.     return(NO_ERROR);
  201. #endif
  202.  
  203. }
  204.  
  205. /* --------------------------------------------------------------------
  206.    UNLOCK index file node
  207. */
  208.  
  209. COUNT UNLOCK(node,knum)
  210. LONG         node;
  211. PFAST KEYFILE    *knum;
  212. {
  213.  
  214. #ifdef FPUTFGET
  215.     knum -= knum->kmem;
  216.     if (!(knum->flmode & NONEXCLUSIVE))
  217.         return(NO_ERROR);
  218.  
  219.     if (knum->clstyp != VAT_CLOSE)
  220.         node /= knum->recsiz;
  221.     node |= ((LONG) knum->filnum << LEFT_SHIFT);
  222.     if (ctseek(ct_key,node))
  223.         return(uerr(SEEK_ERR));
  224.     else if (locking(ct_key->fd,LK_UNLCK,1L))
  225.         return(uerr(UNOD_ERR));
  226.     else
  227.         return(NO_ERROR);
  228. #else
  229.     return(NO_ERROR);
  230. #endif
  231.  
  232. }
  233.  
  234.  
  235. /* --------------------------------------------------------------------
  236.    LOCK data record
  237.  */
  238.  
  239. COUNT DLOCK(recbyt,dnum)        /* recbyt == 0  => header record */
  240. POINTER        recbyt;
  241. PFAST DATFILE      *dnum;
  242. {
  243.  
  244. /*
  245.  * the data record locks are NOT guaranteed to be deadlock free.  Therefore,
  246.  * except for the header record which is only locked by internal c-tree 
  247.  * maintenance requests, the data record lock routine returns instead of
  248.  * looping when a lock is denied because of a competing lock.  The application
  249.  * program must deal with the appropriate action if a lock is denied to a
  250.  * data record.
  251.  */
  252.  
  253. #ifdef FPUTFGET
  254.     COUNT dummy,tries,test;
  255.     LONG  actbyt;
  256.  
  257.     if (!(dnum->flmode & NONEXCLUSIVE))
  258.         return(NO_ERROR);
  259.  
  260.     actbyt  = recbyt;
  261.     tries   = 0;
  262.     if (dnum->clstyp != VAT_CLOSE)
  263.         recbyt /= dnum->reclen;
  264.     recbyt |= ((LONG) dnum->filnum << LEFT_SHIFT);
  265.     if (ctseek(ct_key,recbyt))
  266.         return(uerr(SEEK_ERR));
  267.     while ((test = locking(ct_key->fd,LK_NBLCK,1L)) &&
  268.         actbyt == DRNZERO) /* i.e., the header record is locked */ 
  269.         if (tries++ > INFINITY)
  270.             return(uerr(DLOK_ERR));
  271.         else
  272.             /* delay and try again */
  273.             for (dummy = 0; dummy++ < INFINITY; )
  274.                 ;
  275.  
  276.     if (!test)            /* lock request is successful!  */
  277.         return(NO_ERROR);
  278.     else 
  279.         return(uerr(DLOK_ERR));
  280. #else
  281.     return(NO_ERROR);
  282. #endif
  283.  
  284. }
  285.  
  286. COUNT RLOCK(recbyt,dnum)
  287. POINTER        recbyt;
  288. PFAST DATFILE      *dnum;
  289. {
  290.     return(NO_ERROR); /* read locks not supported */
  291. }
  292.  
  293. /* --------------------------------------------------------------------
  294.    UNLOCK data record
  295. */
  296.  
  297. COUNT UDLOCK(recbyt,dnum)
  298. POINTER         recbyt;
  299. PFAST DATFILE       *dnum;
  300. {
  301.  
  302. #ifdef FPUTFGET
  303.     if (!(dnum->flmode & NONEXCLUSIVE))
  304.         return(NO_ERROR);
  305.  
  306.     if (dnum->clstyp != VAT_CLOSE)
  307.         recbyt /= dnum->reclen;
  308.     recbyt |= ((LONG) dnum->filnum << LEFT_SHIFT);
  309.     if (ctseek(ct_key,recbyt))
  310.         return(uerr(SEEK_ERR));
  311.     if (locking(ct_key->fd,LK_UNLCK,1L))
  312.         return(uerr(UDLK_ERR));
  313.     else
  314.         return(NO_ERROR);
  315.  
  316. #else
  317.     return(NO_ERROR);
  318. #endif
  319.  
  320. }
  321.  
  322. #endif
  323.  
  324. /* end of ctclib.msc */
  325.