/ Check-in [3e9f1635]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix comments and refactor some names associated with shared-memory locking in the Unix VFS. No logical changes.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 3e9f1635271c92dce5324728b4ee1cc1a1856ec3c60b1b512a652c21e010e63e
User & Date: drh 2018-10-02 19:36:40
Context
2018-10-02
19:58
Additional field name changes and commit fixes associated with shared-memory locking in the unix VFS, to improve maintainability. No logic changes. check-in: 9280774a user: drh tags: trunk
19:36
Fix comments and refactor some names associated with shared-memory locking in the Unix VFS. No logical changes. check-in: 3e9f1635 user: drh tags: trunk
2018-10-01
21:41
Add the "PRAGMA table_xinfo" command that works like table_info but also shows hidden columns in virtual tables and adds the "hidden" boolean column. check-in: defa0515 user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

   132    132   
   133    133   /*
   134    134   ** Allowed values of unixFile.fsFlags
   135    135   */
   136    136   #define SQLITE_FSFLAGS_IS_MSDOS     0x1
   137    137   
   138    138   /*
   139         -** If we are to be thread-safe, include the pthreads header and define
   140         -** the SQLITE_UNIX_THREADS macro.
          139  +** If we are to be thread-safe, include the pthreads header.
   141    140   */
   142    141   #if SQLITE_THREADSAFE
   143    142   # include <pthread.h>
   144         -# define SQLITE_UNIX_THREADS 1
   145    143   #endif
   146    144   
   147    145   /*
   148    146   ** Default permissions when creating a new file
   149    147   */
   150    148   #ifndef SQLITE_DEFAULT_FILE_PERMISSIONS
   151    149   # define SQLITE_DEFAULT_FILE_PERMISSIONS 0644
................................................................................
  1115   1113     /* WAS:  ino_t ino;   */
  1116   1114     u64 ino;                   /* Inode number */
  1117   1115   #endif
  1118   1116   };
  1119   1117   
  1120   1118   /*
  1121   1119   ** An instance of the following structure is allocated for each open
  1122         -** inode.  Or, on LinuxThreads, there is one of these structures for
  1123         -** each inode opened by each thread.
         1120  +** inode.
  1124   1121   **
  1125   1122   ** A single inode can have multiple file descriptors, so each unixFile
  1126   1123   ** structure contains a pointer to an instance of this object and this
  1127   1124   ** object keeps a count of the number of unixFile pointing to it.
  1128   1125   **
  1129   1126   ** Mutex rules:
  1130   1127   **
................................................................................
  1162   1159     sem_t *pSem;                    /* Named POSIX semaphore */
  1163   1160     char aSemName[MAX_PATHNAME+2];  /* Name of that semaphore */
  1164   1161   #endif
  1165   1162   };
  1166   1163   
  1167   1164   /*
  1168   1165   ** A lists of all unixInodeInfo objects.
         1166  +**
         1167  +** Must hold unixBigLock in order to read or write this variable.
  1169   1168   */
  1170   1169   static unixInodeInfo *inodeList = 0;  /* All unixInodeInfo objects */
  1171   1170   
  1172   1171   #ifdef SQLITE_DEBUG
  1173   1172   /*
  1174         -** True if the inode mutex is held, or not.  Used only within assert()
  1175         -** to help verify correct mutex usage.
         1173  +** True if the inode mutex (on the unixFile.pFileMutex field) is held, or not.
         1174  +** This routine is used only within assert() to help verify correct mutex
         1175  +** usage.
  1176   1176   */
  1177   1177   int unixFileMutexHeld(unixFile *pFile){
  1178   1178     assert( pFile->pInode );
  1179   1179     return sqlite3_mutex_held(pFile->pInode->pLockMutex);
  1180   1180   }
  1181   1181   int unixFileMutexNotheld(unixFile *pFile){
  1182   1182     assert( pFile->pInode );
................................................................................
  1296   1296     }
  1297   1297     pInode->pUnused = 0;
  1298   1298   }
  1299   1299   
  1300   1300   /*
  1301   1301   ** Release a unixInodeInfo structure previously allocated by findInodeInfo().
  1302   1302   **
  1303         -** The mutex entered using the unixEnterMutex() function must be held
  1304         -** when this function is called.
         1303  +** The global mutex must be held when this routine is called, but the mutex
         1304  +** on the inode being deleted must NOT be held.
  1305   1305   */
  1306   1306   static void releaseInodeInfo(unixFile *pFile){
  1307   1307     unixInodeInfo *pInode = pFile->pInode;
  1308   1308     assert( unixMutexHeld() );
  1309   1309     assert( unixFileMutexNotheld(pFile) );
  1310   1310     if( ALWAYS(pInode) ){
  1311   1311       pInode->nRef--;
................................................................................
  1332   1332   }
  1333   1333   
  1334   1334   /*
  1335   1335   ** Given a file descriptor, locate the unixInodeInfo object that
  1336   1336   ** describes that file descriptor.  Create a new one if necessary.  The
  1337   1337   ** return value might be uninitialized if an error occurs.
  1338   1338   **
  1339         -** The mutex entered using the unixEnterMutex() function must be held
  1340         -** when this function is called.
         1339  +** The global mutex must held when calling this routine.
  1341   1340   **
  1342   1341   ** Return an appropriate error code.
  1343   1342   */
  1344   1343   static int findInodeInfo(
  1345   1344     unixFile *pFile,               /* Unix file with file desc used in the key */
  1346   1345     unixInodeInfo **ppInode        /* Return the unixInodeInfo object here */
  1347   1346   ){
................................................................................
  1394   1393     memset(&fileId, 0, sizeof(fileId));
  1395   1394     fileId.dev = statbuf.st_dev;
  1396   1395   #if OS_VXWORKS
  1397   1396     fileId.pId = pFile->pId;
  1398   1397   #else
  1399   1398     fileId.ino = (u64)statbuf.st_ino;
  1400   1399   #endif
         1400  +  assert( unixMutexHeld() );
  1401   1401     pInode = inodeList;
  1402   1402     while( pInode && memcmp(&fileId, &pInode->fileId, sizeof(fileId)) ){
  1403   1403       pInode = pInode->pNext;
  1404   1404     }
  1405   1405     if( pInode==0 ){
  1406   1406       pInode = sqlite3_malloc64( sizeof(*pInode) );
  1407   1407       if( pInode==0 ){
................................................................................
  1413   1413         pInode->pLockMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  1414   1414         if( pInode->pLockMutex==0 ){
  1415   1415           sqlite3_free(pInode);
  1416   1416           return SQLITE_NOMEM_BKPT;
  1417   1417         }
  1418   1418       }
  1419   1419       pInode->nRef = 1;
         1420  +    assert( unixMutexHeld() );
  1420   1421       pInode->pNext = inodeList;
  1421   1422       pInode->pPrev = 0;
  1422   1423       if( inodeList ) inodeList->pPrev = pInode;
  1423   1424       inodeList = pInode;
  1424   1425     }else{
  1425   1426       pInode->nRef++;
  1426   1427     }
................................................................................
  4219   4220   **
  4220   4221   ** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and
  4221   4222   ** unixMutexHeld() is true when reading or writing any other field
  4222   4223   ** in this structure.
  4223   4224   */
  4224   4225   struct unixShmNode {
  4225   4226     unixInodeInfo *pInode;     /* unixInodeInfo that owns this SHM node */
  4226         -  sqlite3_mutex *mutex;      /* Mutex to access this object */
         4227  +  sqlite3_mutex *pShmMutex;  /* Mutex to access this object */
  4227   4228     char *zFilename;           /* Name of the mmapped file */
  4228   4229     int h;                     /* Open file descriptor */
  4229   4230     int szRegion;              /* Size of shared-memory regions */
  4230   4231     u16 nRegion;               /* Size of array apRegion */
  4231   4232     u8 isReadonly;             /* True if read-only */
  4232   4233     u8 isUnlocked;             /* True if no DMS lock held */
  4233   4234     char **apRegion;           /* Array of mapped shared-memory regions */
................................................................................
  4243   4244   /*
  4244   4245   ** Structure used internally by this VFS to record the state of an
  4245   4246   ** open shared memory connection.
  4246   4247   **
  4247   4248   ** The following fields are initialized when this object is created and
  4248   4249   ** are read-only thereafter:
  4249   4250   **
  4250         -**    unixShm.pFile
         4251  +**    unixShm.pShmNode
  4251   4252   **    unixShm.id
  4252   4253   **
  4253         -** All other fields are read/write.  The unixShm.pFile->mutex must be held
  4254         -** while accessing any read/write fields.
         4254  +** All other fields are read/write.  The unixShm.pShmNode->pShmMutex must
         4255  +** be held while accessing any read/write fields.
  4255   4256   */
  4256   4257   struct unixShm {
  4257   4258     unixShmNode *pShmNode;     /* The underlying unixShmNode object */
  4258   4259     unixShm *pNext;            /* Next unixShm with the same unixShmNode */
  4259         -  u8 hasMutex;               /* True if holding the unixShmNode mutex */
         4260  +  u8 hasMutex;               /* True if holding the unixShmNode->pShmMutex */
  4260   4261     u8 id;                     /* Id of this connection within its unixShmNode */
  4261   4262     u16 sharedMask;            /* Mask of shared locks held */
  4262   4263     u16 exclMask;              /* Mask of exclusive locks held */
  4263   4264   };
  4264   4265   
  4265   4266   /*
  4266   4267   ** Constants used for locking
................................................................................
  4282   4283   ){
  4283   4284     unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
  4284   4285     struct flock f;        /* The posix advisory locking structure */
  4285   4286     int rc = SQLITE_OK;    /* Result code form fcntl() */
  4286   4287   
  4287   4288     /* Access to the unixShmNode object is serialized by the caller */
  4288   4289     pShmNode = pFile->pInode->pShmNode;
  4289         -  assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->mutex) );
         4290  +  assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
  4290   4291   
  4291   4292     /* Shared locks never span more than one byte */
  4292   4293     assert( n==1 || lockType!=F_RDLCK );
  4293   4294   
  4294   4295     /* Locks are within range */
  4295   4296     assert( n>=1 && n<=SQLITE_SHM_NLOCK );
  4296   4297   
................................................................................
  4368   4369   static void unixShmPurge(unixFile *pFd){
  4369   4370     unixShmNode *p = pFd->pInode->pShmNode;
  4370   4371     assert( unixMutexHeld() );
  4371   4372     if( p && ALWAYS(p->nRef==0) ){
  4372   4373       int nShmPerMap = unixShmRegionPerMap();
  4373   4374       int i;
  4374   4375       assert( p->pInode==pFd->pInode );
  4375         -    sqlite3_mutex_free(p->mutex);
         4376  +    sqlite3_mutex_free(p->pShmMutex);
  4376   4377       for(i=0; i<p->nRegion; i+=nShmPerMap){
  4377   4378         if( p->h>=0 ){
  4378   4379           osMunmap(p->apRegion[i], p->szRegion);
  4379   4380         }else{
  4380   4381           sqlite3_free(p->apRegion[i]);
  4381   4382         }
  4382   4383       }
................................................................................
  4539   4540       sqlite3_snprintf(nShmFilename, zShm, "%s-shm", zBasePath);
  4540   4541       sqlite3FileSuffix3(pDbFd->zPath, zShm);
  4541   4542   #endif
  4542   4543       pShmNode->h = -1;
  4543   4544       pDbFd->pInode->pShmNode = pShmNode;
  4544   4545       pShmNode->pInode = pDbFd->pInode;
  4545   4546       if( sqlite3GlobalConfig.bCoreMutex ){
  4546         -      pShmNode->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
  4547         -      if( pShmNode->mutex==0 ){
         4547  +      pShmNode->pShmMutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
         4548  +      if( pShmNode->pShmMutex==0 ){
  4548   4549           rc = SQLITE_NOMEM_BKPT;
  4549   4550           goto shm_open_err;
  4550   4551         }
  4551   4552       }
  4552   4553   
  4553   4554       if( pInode->bProcessLock==0 ){
  4554   4555         if( 0==sqlite3_uri_boolean(pDbFd->zPath, "readonly_shm", 0) ){
................................................................................
  4583   4584     pDbFd->pShm = p;
  4584   4585     unixLeaveMutex();
  4585   4586   
  4586   4587     /* The reference count on pShmNode has already been incremented under
  4587   4588     ** the cover of the unixEnterMutex() mutex and the pointer from the
  4588   4589     ** new (struct unixShm) object to the pShmNode has been set. All that is
  4589   4590     ** left to do is to link the new object into the linked list starting
  4590         -  ** at pShmNode->pFirst. This must be done while holding the pShmNode->mutex 
  4591         -  ** mutex.
         4591  +  ** at pShmNode->pFirst. This must be done while holding the
         4592  +  ** pShmNode->pShmMutex.
  4592   4593     */
  4593         -  sqlite3_mutex_enter(pShmNode->mutex);
         4594  +  sqlite3_mutex_enter(pShmNode->pShmMutex);
  4594   4595     p->pNext = pShmNode->pFirst;
  4595   4596     pShmNode->pFirst = p;
  4596         -  sqlite3_mutex_leave(pShmNode->mutex);
         4597  +  sqlite3_mutex_leave(pShmNode->pShmMutex);
  4597   4598     return rc;
  4598   4599   
  4599   4600     /* Jump here on any error */
  4600   4601   shm_open_err:
  4601   4602     unixShmPurge(pDbFd);       /* This call frees pShmNode if required */
  4602   4603     sqlite3_free(p);
  4603   4604     unixLeaveMutex();
................................................................................
  4641   4642     if( pDbFd->pShm==0 ){
  4642   4643       rc = unixOpenSharedMemory(pDbFd);
  4643   4644       if( rc!=SQLITE_OK ) return rc;
  4644   4645     }
  4645   4646   
  4646   4647     p = pDbFd->pShm;
  4647   4648     pShmNode = p->pShmNode;
  4648         -  sqlite3_mutex_enter(pShmNode->mutex);
         4649  +  sqlite3_mutex_enter(pShmNode->pShmMutex);
  4649   4650     if( pShmNode->isUnlocked ){
  4650   4651       rc = unixLockSharedMemory(pDbFd, pShmNode);
  4651   4652       if( rc!=SQLITE_OK ) goto shmpage_out;
  4652   4653       pShmNode->isUnlocked = 0;
  4653   4654     }
  4654   4655     assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 );
  4655   4656     assert( pShmNode->pInode==pDbFd->pInode );
................................................................................
  4750   4751   shmpage_out:
  4751   4752     if( pShmNode->nRegion>iRegion ){
  4752   4753       *pp = pShmNode->apRegion[iRegion];
  4753   4754     }else{
  4754   4755       *pp = 0;
  4755   4756     }
  4756   4757     if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
  4757         -  sqlite3_mutex_leave(pShmNode->mutex);
         4758  +  sqlite3_mutex_leave(pShmNode->pShmMutex);
  4758   4759     return rc;
  4759   4760   }
  4760   4761   
  4761   4762   /*
  4762   4763   ** Change the lock state for a shared-memory segment.
  4763   4764   **
  4764   4765   ** Note that the relationship between SHAREd and EXCLUSIVE locks is a little
................................................................................
  4789   4790          || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) );
  4790   4791     assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 );
  4791   4792     assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 );
  4792   4793     assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 );
  4793   4794   
  4794   4795     mask = (1<<(ofst+n)) - (1<<ofst);
  4795   4796     assert( n>1 || mask==(1<<ofst) );
  4796         -  sqlite3_mutex_enter(pShmNode->mutex);
         4797  +  sqlite3_mutex_enter(pShmNode->pShmMutex);
  4797   4798     if( flags & SQLITE_SHM_UNLOCK ){
  4798   4799       u16 allMask = 0; /* Mask of locks held by siblings */
  4799   4800   
  4800   4801       /* See if any siblings hold this same lock */
  4801   4802       for(pX=pShmNode->pFirst; pX; pX=pX->pNext){
  4802   4803         if( pX==p ) continue;
  4803   4804         assert( (pX->exclMask & (p->exclMask|p->sharedMask))==0 );
................................................................................
  4862   4863         rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
  4863   4864         if( rc==SQLITE_OK ){
  4864   4865           assert( (p->sharedMask & mask)==0 );
  4865   4866           p->exclMask |= mask;
  4866   4867         }
  4867   4868       }
  4868   4869     }
  4869         -  sqlite3_mutex_leave(pShmNode->mutex);
         4870  +  sqlite3_mutex_leave(pShmNode->pShmMutex);
  4870   4871     OSTRACE(("SHM-LOCK shmid-%d, pid-%d got %03x,%03x\n",
  4871   4872              p->id, osGetpid(0), p->sharedMask, p->exclMask));
  4872   4873     return rc;
  4873   4874   }
  4874   4875   
  4875   4876   /*
  4876   4877   ** Implement a memory barrier or memory fence on shared memory.  
................................................................................
  4912   4913     pShmNode = p->pShmNode;
  4913   4914   
  4914   4915     assert( pShmNode==pDbFd->pInode->pShmNode );
  4915   4916     assert( pShmNode->pInode==pDbFd->pInode );
  4916   4917   
  4917   4918     /* Remove connection p from the set of connections associated
  4918   4919     ** with pShmNode */
  4919         -  sqlite3_mutex_enter(pShmNode->mutex);
         4920  +  sqlite3_mutex_enter(pShmNode->pShmMutex);
  4920   4921     for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){}
  4921   4922     *pp = p->pNext;
  4922   4923   
  4923   4924     /* Free the connection p */
  4924   4925     sqlite3_free(p);
  4925   4926     pDbFd->pShm = 0;
  4926         -  sqlite3_mutex_leave(pShmNode->mutex);
         4927  +  sqlite3_mutex_leave(pShmNode->pShmMutex);
  4927   4928   
  4928   4929     /* If pShmNode->nRef has reached 0, then close the underlying
  4929   4930     ** shared-memory file, too */
  4930   4931     assert( unixFileMutexNotheld(pDbFd) );
  4931   4932     unixEnterMutex();
  4932   4933     assert( pShmNode->nRef>0 );
  4933   4934     pShmNode->nRef--;