home *** CD-ROM | disk | FTP | other *** search
/ Frostbyte's 1980s DOS Shareware Collection / floppyshareware.zip / floppyshareware / DOOG / CBASE09.ZIP / BTREE.ZIP / BTLOCK.C < prev    next >
Text File  |  1989-08-31  |  4KB  |  187 lines

  1. /*    Copyright (c) 1989 Citadel    */
  2. /*       All Rights Reserved        */
  3.  
  4. /* #ident    "btlock.c    1.1 - 89/07/03" */
  5.  
  6. #include <blkio.h>
  7. #include <errno.h>
  8. #include "btree_.h"
  9.  
  10. /*man---------------------------------------------------------------------------
  11. NAME
  12.      btlock - btree lock
  13.  
  14. SYNOPSIS
  15.      #include <btree.h>
  16.  
  17.      int btlock(btp, l_type)
  18.      btree_t *btp;
  19.      int l_type;
  20.  
  21. DESCRIPTION
  22.      The btlock function controls the lock status of a btree.  The btp
  23.      argument is an open btree.  l_type indicates the target status of
  24.      the lock on the btree.
  25.  
  26.      The lock types available are:
  27.  
  28.           BT_RDLCK - lock btree for reading
  29.           BT_WRLCK - lock btree for reading and writing
  30.           BT_RDLKW - lock btree for reading (wait)
  31.           BT_WRLKW - lock btree for reading and writing (wait)
  32.           BT_UNLCK - unlock btree
  33.  
  34.      For the lock types which wait, btlock will not return until the
  35.      lock is available.  For the lock types which do not wait, if the
  36.      lock is unavailable because of a lock held by another process  a
  37.      value of -1 is returned and errno set to EAGAIN.
  38.  
  39.      btlock will fail if one or more of the following is true:
  40.  
  41.      [EAGAIN]       l_type is BT_RDLCK and btp is already
  42.                     write locked by another process, or l_type
  43.                     is BT_WRLCK and btp is already read
  44.                     or write locked by another process.
  45.      [EINVAL]       btp is is not a valid btree pointer.
  46.      [EINVAL]       l_type is not one of the valid lock types.
  47.      [BTECORRUPT]   btp is corrupt.
  48.      [BTENOPEN]     btp is not open.
  49.      [BTENOPEN]     l_type is BT_RDLCK or BT_RDLKW and btp
  50.                     is not opened for reading or l_type is BT_WRLCK
  51.                     or BT_WRLKW and btp is not open for writing.
  52.  
  53. SEE ALSO
  54.      btgetlck.
  55.  
  56. DIAGNOSTICS
  57.      Upon successful completion, a value of 0 is returned.  Otherwise, a
  58.      value of -1 is returned, and errno set to indicate the error.
  59.  
  60. ------------------------------------------------------------------------------*/
  61. int btlock(btp, l_type)
  62. btree_t * btp;
  63. int       l_type;
  64. {
  65.     int    rs    = 0;
  66.     int    bl_type    = 0;
  67.  
  68.     errno = 0;
  69.  
  70.     /* validate arguments */
  71.     if (!bt_valid(btp)) {
  72.         errno = EINVAL;
  73.         return -1;
  74.     }
  75.  
  76.     /* check if btree not open */
  77.     if (!(btp->flags & BTOPEN)) {
  78.         errno = BTENOPEN;
  79.         return -1;
  80.     }
  81.  
  82.     /* check if file is open */
  83.     switch (l_type) {
  84.     case BT_RDLCK:
  85.         if (!(btp->flags & BTREAD)) {
  86.             errno = BTENOPEN;
  87.             return -1;
  88.         }
  89.         bl_type = B_RDLCK;
  90.         break;
  91.     case BT_RDLKW:
  92.         if (!(btp->flags & BTREAD)) {
  93.             errno = BTENOPEN;
  94.             return -1;
  95.         }
  96.         bl_type = B_RDLKW;
  97.         break;
  98.     case BT_WRLCK:
  99.         if (!(btp->flags & BTWRITE)) {
  100.             errno = BTENOPEN;
  101.             return -1;
  102.         }
  103.         bl_type = B_WRLCK;
  104.         break;
  105.     case BT_WRLKW:
  106.         if (!(btp->flags & BTWRITE)) {
  107.             errno = BTENOPEN;
  108.             return -1;
  109.         }
  110.         bl_type = B_WRLKW;
  111.         break;
  112.     case BT_UNLCK:
  113.         /* flush buffers */
  114.         rs = bflush(btp->bp);
  115.         if (rs == -1) {
  116.             BTEPRINT;
  117.             return -1;
  118.         }
  119.         bl_type = B_UNLCK;
  120.         break;
  121.     default:
  122.         errno = EINVAL;
  123.         return -1;
  124.         break;
  125.     }
  126.  
  127.     /* lock btree file */
  128.     rs = lockb(btp->bp, bl_type, (bpos_t)0, (size_t)0);
  129.     if (rs == -1) {
  130.         if (errno != EAGAIN) BTEPRINT;
  131.         return -1;
  132.     }
  133.  
  134.     /* set status bits in btree control structure */
  135.     switch (l_type) {
  136.     case BT_UNLCK:
  137.         if (btgetlck(btp) == BT_WRLCK) {    /* update header */
  138.             rs = bputh(btp->bp, (void *)&btp->bthdr);
  139.             if (rs == -1) {
  140.                 BTEPRINT;
  141.                 return -1;
  142.             }
  143.         }
  144.         btp->flags &= ~BTLOCKS;
  145.         break;    /* case BT_UNLCK: */
  146.     case BT_RDLCK:
  147.     case BT_RDLKW:
  148.         if (btgetlck(btp) == BT_UNLCK) {
  149.             rs = bgeth(btp->bp, (void *)&btp->bthdr);
  150.             if (rs == -1) {
  151.                 BTEPRINT;
  152.                 return -1;
  153.             }
  154.             if (btp->bthdr.flags & BTHMOD) {
  155.                 errno = BTECORRUPT;
  156.                 return -1;
  157.             }
  158.         }
  159.         btp->flags |= BTRDLCK;
  160.         btp->flags &= ~BTWRLCK;
  161.         break;    /* case BT_RDLCK: */
  162.     case BT_WRLCK:
  163.     case BT_WRLKW:
  164.         if (btgetlck(btp) == BT_UNLCK) {
  165.             rs = bgeth(btp->bp, (void *)&btp->bthdr);
  166.             if (rs == -1) {
  167.                 BTEPRINT;
  168.                 return -1;
  169.             }
  170.             if (btp->bthdr.flags & BTHMOD) {
  171.                 errno = BTECORRUPT;
  172.                 return -1;
  173.             }
  174.         }
  175.         btp->flags |= (BTRDLCK | BTWRLCK);
  176.         break;    /* case BT_WRLCK: */
  177.     default:
  178.         BTEPRINT;
  179.         errno = BTEPANIC;
  180.         return -1;
  181.         break;    /* default: */
  182.     }
  183.  
  184.     errno = 0;
  185.     return 0;
  186. }
  187.