]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Untested implementation of the shared-memory dead-man-switch.
authordrh <drh@noemail.net>
Thu, 29 Apr 2010 16:40:51 +0000 (16:40 +0000)
committerdrh <drh@noemail.net>
Thu, 29 Apr 2010 16:40:51 +0000 (16:40 +0000)
FossilOrigin-Name: 706611283ea2575c2942543391026b36061cfc1c

manifest
manifest.uuid
src/os_unix.c

index 81762c0b4c0d4f51d14739e423de8ea773f5d0d2..ee0cee40d9e4772325dddd8742ea29a732598348 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Progress\stowards\sa\sVFS\sthat\swill\ssupport\sWAL.\s\sLocking\scode\sis\sin\splace\nbut\sis\suntested.\s\sStill\sno\ssupport\sfor\sthe\sDMS.
-D 2010-04-29T15:17:48
+C Untested\simplementation\sof\sthe\sshared-memory\sdead-man-switch.
+D 2010-04-29T16:40:51
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in d83a0ffef3dcbfb08b410a6c6dd6c009ec9167fb
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -153,7 +153,7 @@ F src/os.c 8bc63cf91e9802e2b807198e54e50227fa889306
 F src/os.h 534b082c3cb349ad05fa6fa0b06087e022af282c
 F src/os_common.h 0d6ee583b6ee3185eb9d951f890c6dd03021a08d
 F src/os_os2.c 8ad77a418630d7dee91d1bb04f79c2096301d3a0
-F src/os_unix.c 340c503705cdb447753a55771911a92aa41d27c8
+F src/os_unix.c f0e002e74108c8a3f70c63dd91419ab6bcafd095
 F src/os_win.c a8fc01d8483be472e495793c01064fd87e56a5c1
 F src/pager.c b4a41030860229e80295fa1f37addab24d21799c
 F src/pager.h cee4487ab4f0911dd9f22a40e3cd55afdb7ef444
@@ -811,14 +811,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 3cc55a7568daa3796483f632e33478969e381cf5
-R 1f2ad602233779dda1e35a2877201d1f
+P 1bde41cf081570ad257f927b641e752dff4ed014
+R a7ee89d9d5eb7d4f4fd9d69824beab31
 U drh
-Z 5bb08c68390b552fdeb1ef93301ae98c
+Z 15bd57757c5a0ce16c3065e9d45dae67
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFL2aMhoxKgR168RlERAntLAKCNwNXdF9LrZZqkEN8f3gsvrSxoXACaA2Ku
-SvIawhrGV2wraxrir5MNan8=
-=Vfpz
+iD4DBQFL2baVoxKgR168RlERArO2AJ9g8Vnb6XlVDltcg68idEyJzFPcYwCYh7Xs
+0Mdctk0jP1xbHiTJhHLX+A==
+=minX
 -----END PGP SIGNATURE-----
index 000aaadb5f749d9c7fca01a2874c3daf99f9e0b0..ca7b008f921097b9cb13050da738b7d1e180e65d 100644 (file)
@@ -1 +1 @@
-1bde41cf081570ad257f927b641e752dff4ed014
\ No newline at end of file
+706611283ea2575c2942543391026b36061cfc1c
\ No newline at end of file
index 634f5ee21859b366faaedceed6c90e87af952512..248309664d851453d32c5774e336840fdcd53234 100644 (file)
@@ -4698,7 +4698,7 @@ static const char *unixShmLockString(u8 mask){
 ** Locks block if the UNIX_SHM_MUTEX bit is set and are non-blocking
 ** otherwise.
 */
-static int unixShmSystemLocks(
+static int unixShmSystemLock(
   unixShmFile *pFile,   /* Apply locks to this open shared-memory segment */
   int lockType,         /* F_UNLCK, F_RDLCK, or F_WRLCK */
   u8 lockMask           /* Which bytes to lock or unlock */
@@ -4709,6 +4709,9 @@ static int unixShmSystemLocks(
   int rc;               /* Result code form fcntl() */
   u8 mask;              /* Mask of bits in lockMask */
 
+  /* Access to the unixShmFile object is serialized by the caller */
+  assert( sqlite3_mutex_held(pFile->mutex) );
+
   /* Initialize the locking parameters */
   memset(&f, 0, sizeof(f));
   f.l_type = lockType;
@@ -4787,6 +4790,9 @@ static int unixShmUnlock(
   unixShm *pX; /* For looping over all sibling connections */
   u8 allMask;  /* Union of locks held by connections other than "p" */
 
+  /* Access to the unixShmFile object is serialized by the caller */
+  assert( sqlite3_mutex_held(pFile->mutex) );
+
   /* We never try to unlock locks that we do not hold */
   assert( ((p->exclMask|p->sharedMask) & unlockMask)==unlockMask );
 
@@ -4799,7 +4805,7 @@ static int unixShmUnlock(
 
   /* Unlock the system-level locks */
   if( (unlockMask & allMask)!=unlockMask ){
-    rc = unixShmSystemLocks(pFile, F_UNLCK, unlockMask & ~allMask);
+    rc = unixShmSystemLock(pFile, F_UNLCK, unlockMask & ~allMask);
   }else{
     rc = SQLITE_OK;
   }
@@ -4824,6 +4830,9 @@ static int unixShmSharedLock(
   unixShm *pX;   /* For looping over all sibling connections */
   u8 allShared;  /* Union of locks held by connections other than "p" */
 
+  /* Access to the unixShmFile object is serialized by the caller */
+  assert( sqlite3_mutex_held(pFile->mutex) );
+
   /* Find out which shared locks are already held by sibling connections.
   ** If any sibling already holds an exclusive lock, go ahead and return
   ** SQLITE_BUSY.
@@ -4836,7 +4845,7 @@ static int unixShmSharedLock(
 
   /* Get shared locks at the system level, if necessary */
   if( (~allShared) & readMask ){
-    rc = unixShmSystemLocks(pFile, F_RDLCK, readMask);
+    rc = unixShmSystemLock(pFile, F_RDLCK, readMask);
   }else{
     rc = SQLITE_OK;
   }
@@ -4860,6 +4869,9 @@ static int unixShmExclusiveLock(
   int rc;        /* Result code */
   unixShm *pX;   /* For looping over all sibling connections */
 
+  /* Access to the unixShmFile object is serialized by the caller */
+  assert( sqlite3_mutex_held(pFile->mutex) );
+
   /* Make sure no sibling connections hold locks that will block this
   ** lock.  If any do, return SQLITE_BUSY right away.
   */
@@ -4872,7 +4884,7 @@ static int unixShmExclusiveLock(
   /* Get the exclusive locks at the system level.  Then if successful
   ** also mark the local connection as being locked.
   */
-  rc = unixShmSystemLocks(pFile, F_WRLCK, writeMask);
+  rc = unixShmSystemLock(pFile, F_WRLCK, writeMask);
   if( rc==SQLITE_OK ){
     p->sharedMask &= ~writeMask;
     p->exclMask |= writeMask;
@@ -4917,16 +4929,20 @@ static int unixShmOpen(
   const char *zName,    /* Name of file to mmap */
   sqlite3_shm **pShm    /* Write the unixShm object created here */
 ){
-  struct unixShm *p = 0;
-  struct unixShmFile *pFile = 0;
-  int rc;
-  struct unixFileId fid;
-  struct stat sStat;
+  struct unixShm *p = 0;             /* The connection to be opened */
+  struct unixShmFile *pFile = 0;     /* The underlying mmapped file */
+  int rc;                            /* Result code */
+  struct unixFileId fid;             /* Unix file identifier */
+  struct stat sStat;                 /* Result from stat() an fstat() */
 
+  /* Allocate space for the new sqlite3_shm object */
   p = sqlite3_malloc( sizeof(*p) );
   if( p==0 ) return SQLITE_NOMEM;
   memset(p, 0, sizeof(*p));
 
+  /* Look to see if there is an existing unixShmFile that can be used.
+  ** If no matching unixShmFile currently exists, create a new one.
+  */
   unixEnterMutex();
   rc = stat(zName, &sStat);
   if( rc==0 ){
@@ -4982,16 +4998,27 @@ static int unixShmOpen(
     pFile->fid.ino = sStat.st_ino;
     pFile->size = (int)sStat.st_size;
     pFile->size = (pFile->size/SQLITE_UNIX_SHM_INCR)*SQLITE_UNIX_SHM_INCR;
-    if( pFile->size==0 ){
-      pFile->size = SQLITE_UNIX_SHM_INCR;
-      rc = ftruncate(pFile->h, pFile->size);
-      if( rc ){
-        rc = SQLITE_FULL;
+
+    /* Check to see if another process is holding the dead-man switch.
+    ** If not, truncate the file to zero length. 
+    */
+    if( unixShmSystemLock(pFile, F_WRLCK, UNIX_SHM_MUTEX) ){
+      rc = SQLITE_IOERR_LOCK;
+      goto shm_open_err;
+    }
+    if( unixShmSystemLock(pFile, F_WRLCK, UNIX_SHM_DMS)==SQLITE_OK ){
+      if( ftruncate(pFile->h, 0) ){
+        rc = SQLITE_IOERR;
         goto shm_open_err;
       }
+      pFile->size = 0;
     }
+    rc = unixShmSystemLock(pFile, F_RDLCK, UNIX_SHM_DMS);
+    if( rc ) goto shm_open_err;
+    unixShmSystemLock(pFile, F_UNLCK, UNIX_SHM_MUTEX);
   }
 
+  /* Make the new connection a child of the unixShmFile */
   p->pFile = pFile;
   p->pNext = pFile->pFirst;
 #ifdef SQLITE_DEBUG
@@ -5003,6 +5030,7 @@ static int unixShmOpen(
   unixLeaveMutex();
   return SQLITE_OK;
 
+  /* Jump here on any error */
 shm_open_err:
   unixShmPurge();
   sqlite3_free(p);