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

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