home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / MISC / SQDEV200.ZIP / SRC / SQ_LOCK.C < prev    next >
C/C++ Source or Header  |  1994-05-23  |  6KB  |  213 lines

  1. /***************************************************************************
  2.  *                                                                         *
  3.  *  Squish Developers Kit Source, Version 2.00                             *
  4.  *  Copyright 1989-1994 by SCI Communications.  All rights reserved.       *
  5.  *                                                                         *
  6.  *  USE OF THIS FILE IS SUBJECT TO THE RESTRICTIONS CONTAINED IN THE       *
  7.  *  SQUISH DEVELOPERS KIT LICENSING AGREEMENT IN SQDEV.PRN.  IF YOU DO NOT *
  8.  *  FIND THE TEXT OF THIS AGREEMENT IN THE AFOREMENTIONED FILE, OR IF YOU  *
  9.  *  DO NOT HAVE THIS FILE, YOU SHOULD IMMEDIATELY CONTACT THE AUTHOR AT    *
  10.  *  ONE OF THE ADDRESSES LISTED BELOW.  IN NO EVENT SHOULD YOU PROCEED TO  *
  11.  *  USE THIS FILE WITHOUT HAVING ACCEPTED THE TERMS OF THE SQUISH          *
  12.  *  DEVELOPERS KIT LICENSING AGREEMENT, OR SUCH OTHER AGREEMENT AS YOU ARE *
  13.  *  ABLE TO REACH WITH THE AUTHOR.                                         *
  14.  *                                                                         *
  15.  *  You can contact the author at one of the address listed below:         *
  16.  *                                                                         *
  17.  *  Scott Dudley       FidoNet     1:249/106                               *
  18.  *  777 Downing St.    Internet    sjd@f106.n249.z1.fidonet.org            *
  19.  *  Kingston, Ont.     CompuServe  >INTERNET:sjd@f106.n249.z1.fidonet.org  *
  20.  *  Canada  K7M 5N3    BBS         1-613-634-3058, V.32bis                 *
  21.  *                                                                         *
  22.  ***************************************************************************/
  23.  
  24. #pragma off(unreferenced)
  25. static char rcs_id[]="$Id: SQ_LOCK.C 1.3 1994/04/01 11:54:45 sjd Exp sjd $";
  26. #pragma on(unreferenced)
  27.  
  28. #define MSGAPI_HANDLERS
  29. #define MSGAPI_NO_OLD_TYPES
  30.  
  31. #include <io.h>
  32. #include <fcntl.h>
  33. #include <sys/types.h>
  34. #include <sys/stat.h>
  35. #include "prog.h"
  36. #include "msgapi.h"
  37. #include "api_sq.h"
  38. #include "apidebug.h"
  39.  
  40.  
  41. /* Lock the first byte of the Squish file header.  Do this up to            *
  42.  * SQUISH_LOCK_RETRY number of times, in case someone else is using         *
  43.  * the message base.                                                        */
  44.  
  45. static unsigned near _SquishLockBase(HAREA ha)
  46. {
  47.   int iMaxTry=SQUISH_LOCK_RETRY;
  48.  
  49.   /* Only need to lock the area the first time */
  50.  
  51.   if (Sqd->fLocked++ != 0)
  52.     return TRUE;
  53.  
  54.   /* The first step is to obtain a lock on the Squish file header.  Another *
  55.    * process may be attempting to do the same thing, so we retry a couple   *
  56.    * of times just in case.                                                 */
  57.  
  58.   while (iMaxTry-- && mi.haveshare)
  59.   {
  60.     if (lock(Sqd->sfd, 0L, 1L)==0)
  61.       break;
  62.  
  63.     /* Wait for one second */
  64.  
  65.     tdelay(1000);
  66.   }
  67.  
  68.   /* If we could not get exclusive access to the base, report an error */
  69.  
  70.   if (!iMaxTry)
  71.   {
  72.     msgapierr=MERR_SHARE;
  73.     Sqd->fHaveExclusive=0;
  74.     return FALSE;
  75.   }
  76.  
  77.   return TRUE;
  78. }
  79.  
  80.  
  81. /* Unlock the first byte of the Squish file */
  82.  
  83. static unsigned near _SquishUnlockBase(HAREA ha)
  84. {
  85.   /* If we have it locked more than once, only unlock on the last call */
  86.  
  87.   if (--Sqd->fLocked)
  88.     return TRUE;
  89.  
  90.   /* Unlock the first byte of the file */
  91.  
  92.   if (mi.haveshare)
  93.     (void)unlock(Sqd->sfd, 0L, 1L);
  94.  
  95.   return TRUE;
  96. }
  97.  
  98.  
  99.  
  100. /* Obtain exclusive access to this message area.  We need to do this to     *
  101.  * synchronize access to critical fields in the Squish file header.         */
  102.  
  103. unsigned _SquishExclusiveBegin(HAREA ha)
  104. {
  105.   SQBASE sqb;
  106.  
  107.   /* We can't open the header for exclusive access more than once */
  108.  
  109.   if (Sqd->fHaveExclusive)
  110.   {
  111.     msgapierr=MERR_SHARE;
  112.     return FALSE;
  113.   }
  114.  
  115.  
  116.   /* Lock the header */
  117.  
  118.   if (!_SquishLockBase(ha))
  119.     return FALSE;
  120.  
  121.  
  122.   /* Obtain an up-to-date copy of the file header */
  123.  
  124.   if (!_SquishReadBaseHeader(ha, &sqb) ||
  125.       !_SquishCopyBaseToData(ha, &sqb))
  126.   {
  127.     (void)_SquishUnlockBase(ha);
  128.     return FALSE;
  129.   }
  130.  
  131.   Sqd->fHaveExclusive=TRUE;
  132.   return TRUE;
  133. }
  134.  
  135.  
  136. /* Finish exclusive access to the area header.  Sync the base header        *
  137.  * with what we have in memory, then unlock the file.                       */
  138.  
  139. unsigned _SquishExclusiveEnd(HAREA ha)
  140. {
  141.   SQBASE sqb;
  142.   unsigned rc;
  143.  
  144.   if (!Sqd->fHaveExclusive)
  145.   {
  146.     msgapierr=MERR_NOLOCK;
  147.     return FALSE;
  148.   }
  149.  
  150.   /* Copy the in-memory struct to sqb, then write to disk */
  151.  
  152.   rc=_SquishCopyDataToBase(ha, &sqb) &&
  153.      _SquishWriteBaseHeader(ha, &sqb);
  154.  
  155.   /* Relinquish access to the base */
  156.  
  157.   if (!_SquishUnlockBase(ha))
  158.     rc=FALSE;
  159.  
  160.   Sqd->fHaveExclusive=FALSE;
  161.  
  162.   return rc;
  163. }
  164.  
  165.  
  166. /* Lock this message area for exclusive access */
  167.  
  168. sword MAPIENTRY SquishLock(HAREA ha)
  169. {
  170.   /* Only need to lock once */
  171.  
  172.   if (Sqd->fLockFunc++ != 0)
  173.     return 0;
  174.  
  175.   /* Lock the header */
  176.  
  177.   if (!_SquishLockBase(ha))
  178.     return -1;
  179.  
  180.  
  181.   /* Read the index into memory */
  182.  
  183.   if (!_SquishBeginBuffer(Sqd->hix))
  184.   {
  185.     (void)_SquishUnlockBase(ha);
  186.     return -1;
  187.   }
  188.  
  189.   return 0;
  190. }
  191.  
  192.  
  193. /* Unlock an area that was opened for exclusive access */
  194.  
  195. sword MAPIENTRY SquishUnlock(HAREA ha)
  196. {
  197.   if (Sqd->fLockFunc==0)
  198.   {
  199.     msgapierr=MERR_NOLOCK;
  200.     return -1;
  201.   }
  202.  
  203.   if (--Sqd->fLockFunc != 0)
  204.     return 0;
  205.  
  206.   (void)_SquishEndBuffer(Sqd->hix);
  207.   (void)_SquishUnlockBase(ha);
  208.  
  209.   return 0;
  210. }
  211.  
  212.  
  213.