/ Check-in [58381352]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Simplifications to the locking logic in the unix-dotfile VFS.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 583813525888c7e106f3e8cb46c1a507006daee6
User & Date: drh 2015-11-30 00:05:39
Context
2015-11-30
12:01
Add the "colUsed" field to the sqlite3_index_info structure passed to virtual table xBestIndex methods. To indicate the subset of the virtual table columns that may be required by the current scan. check-in: 47f10b7e user: dan tags: trunk
00:05
Simplifications to the locking logic in the unix-dotfile VFS. check-in: 58381352 user: drh tags: trunk
2015-11-29
21:46
Fix the sqldiff utility program so that it works for schemas that have tables with zero-length column names. check-in: 64263ccb user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

  1346   1346     int rc = SQLITE_OK;
  1347   1347     int reserved = 0;
  1348   1348     unixFile *pFile = (unixFile*)id;
  1349   1349   
  1350   1350     SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
  1351   1351   
  1352   1352     assert( pFile );
         1353  +  assert( pFile->eFileLock<=SHARED_LOCK );
  1353   1354     unixEnterMutex(); /* Because pFile->pInode is shared across threads */
  1354   1355   
  1355   1356     /* Check if a thread in this process holds such a lock */
  1356   1357     if( pFile->pInode->eFileLock>SHARED_LOCK ){
  1357   1358       reserved = 1;
  1358   1359     }
  1359   1360   
................................................................................
  1756   1757           lock.l_type = F_UNLCK;
  1757   1758           lock.l_whence = SEEK_SET;
  1758   1759           lock.l_start = SHARED_FIRST;
  1759   1760           lock.l_len = divSize;
  1760   1761           if( unixFileLock(pFile, &lock)==(-1) ){
  1761   1762             tErrno = errno;
  1762   1763             rc = SQLITE_IOERR_UNLOCK;
  1763         -          if( IS_LOCK_ERROR(rc) ){
  1764         -            storeLastErrno(pFile, tErrno);
  1765         -          }
         1764  +          storeLastErrno(pFile, tErrno);
  1766   1765             goto end_unlock;
  1767   1766           }
  1768   1767           lock.l_type = F_RDLCK;
  1769   1768           lock.l_whence = SEEK_SET;
  1770   1769           lock.l_start = SHARED_FIRST;
  1771   1770           lock.l_len = divSize;
  1772   1771           if( unixFileLock(pFile, &lock)==(-1) ){
................................................................................
  1780   1779           lock.l_type = F_UNLCK;
  1781   1780           lock.l_whence = SEEK_SET;
  1782   1781           lock.l_start = SHARED_FIRST+divSize;
  1783   1782           lock.l_len = SHARED_SIZE-divSize;
  1784   1783           if( unixFileLock(pFile, &lock)==(-1) ){
  1785   1784             tErrno = errno;
  1786   1785             rc = SQLITE_IOERR_UNLOCK;
  1787         -          if( IS_LOCK_ERROR(rc) ){
  1788         -            storeLastErrno(pFile, tErrno);
  1789         -          }
         1786  +          storeLastErrno(pFile, tErrno);
  1790   1787             goto end_unlock;
  1791   1788           }
  1792   1789         }else
  1793   1790   #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
  1794   1791         {
  1795   1792           lock.l_type = F_RDLCK;
  1796   1793           lock.l_whence = SEEK_SET;
................................................................................
  2033   2030     int rc = SQLITE_OK;
  2034   2031     int reserved = 0;
  2035   2032     unixFile *pFile = (unixFile*)id;
  2036   2033   
  2037   2034     SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
  2038   2035     
  2039   2036     assert( pFile );
  2040         -
  2041         -  /* Check if a thread in this process holds such a lock */
  2042         -  if( pFile->eFileLock>SHARED_LOCK ){
  2043         -    /* Either this connection or some other connection in the same process
  2044         -    ** holds a lock on the file.  No need to check further. */
  2045         -    reserved = 1;
  2046         -  }else{
  2047         -    /* The lock is held if and only if the lockfile exists */
  2048         -    const char *zLockFile = (const char*)pFile->lockingContext;
  2049         -    reserved = osAccess(zLockFile, 0)==0;
  2050         -  }
         2037  +  reserved = osAccess((const char*)pFile->lockingContext, 0)==0;
  2051   2038     OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved));
  2052   2039     *pResOut = reserved;
  2053   2040     return rc;
  2054   2041   }
  2055   2042   
  2056   2043   /*
  2057   2044   ** Lock the file with the lock specified by parameter eFileLock - one
................................................................................
  2105   2092     if( rc<0 ){
  2106   2093       /* failed to open/create the lock directory */
  2107   2094       int tErrno = errno;
  2108   2095       if( EEXIST == tErrno ){
  2109   2096         rc = SQLITE_BUSY;
  2110   2097       } else {
  2111   2098         rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK);
  2112         -      if( IS_LOCK_ERROR(rc) ){
         2099  +      if( rc!=SQLITE_BUSY ){
  2113   2100           storeLastErrno(pFile, tErrno);
  2114   2101         }
  2115   2102       }
  2116   2103       return rc;
  2117   2104     } 
  2118   2105     
  2119   2106     /* got it, set the type and return ok */
................................................................................
  2152   2139       pFile->eFileLock = SHARED_LOCK;
  2153   2140       return SQLITE_OK;
  2154   2141     }
  2155   2142     
  2156   2143     /* To fully unlock the database, delete the lock file */
  2157   2144     assert( eFileLock==NO_LOCK );
  2158   2145     rc = osRmdir(zLockFile);
  2159         -  if( rc<0 && errno==ENOTDIR ) rc = osUnlink(zLockFile);
  2160   2146     if( rc<0 ){
  2161   2147       int tErrno = errno;
  2162         -    rc = 0;
  2163         -    if( ENOENT != tErrno ){
         2148  +    if( tErrno==ENOENT ){
         2149  +      rc = SQLITE_OK;
         2150  +    }else{
  2164   2151         rc = SQLITE_IOERR_UNLOCK;
  2165         -    }
  2166         -    if( IS_LOCK_ERROR(rc) ){
  2167   2152         storeLastErrno(pFile, tErrno);
  2168   2153       }
  2169   2154       return rc; 
  2170   2155     }
  2171   2156     pFile->eFileLock = NO_LOCK;
  2172   2157     return SQLITE_OK;
  2173   2158   }
  2174   2159   
  2175   2160   /*
  2176   2161   ** Close a file.  Make sure the lock has been released before closing.
  2177   2162   */
  2178   2163   static int dotlockClose(sqlite3_file *id) {
  2179         -  int rc = SQLITE_OK;
  2180         -  if( id ){
  2181         -    unixFile *pFile = (unixFile*)id;
  2182         -    dotlockUnlock(id, NO_LOCK);
  2183         -    sqlite3_free(pFile->lockingContext);
  2184         -    rc = closeUnixFile(id);
  2185         -  }
  2186         -  return rc;
         2164  +  unixFile *pFile = (unixFile*)id;
         2165  +  assert( id!=0 );
         2166  +  dotlockUnlock(id, NO_LOCK);
         2167  +  sqlite3_free(pFile->lockingContext);
         2168  +  return closeUnixFile(id);
  2187   2169   }
  2188   2170   /****************** End of the dot-file lock implementation *******************
  2189   2171   ******************************************************************************/
  2190   2172   
  2191   2173   /******************************************************************************
  2192   2174   ************************** Begin flock Locking ********************************
  2193   2175   **
................................................................................
  2245   2227       if( !lrc ){
  2246   2228         /* got the lock, unlock it */
  2247   2229         lrc = robust_flock(pFile->h, LOCK_UN);
  2248   2230         if ( lrc ) {
  2249   2231           int tErrno = errno;
  2250   2232           /* unlock failed with an error */
  2251   2233           lrc = SQLITE_IOERR_UNLOCK; 
  2252         -        if( IS_LOCK_ERROR(lrc) ){
  2253         -          storeLastErrno(pFile, tErrno);
  2254         -          rc = lrc;
  2255         -        }
         2234  +        storeLastErrno(pFile, tErrno);
         2235  +        rc = lrc;
  2256   2236         }
  2257   2237       } else {
  2258   2238         int tErrno = errno;
  2259   2239         reserved = 1;
  2260   2240         /* someone else might have it reserved */
  2261   2241         lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); 
  2262   2242         if( IS_LOCK_ERROR(lrc) ){
................................................................................
  2381   2361     }
  2382   2362   }
  2383   2363   
  2384   2364   /*
  2385   2365   ** Close a file.
  2386   2366   */
  2387   2367   static int flockClose(sqlite3_file *id) {
  2388         -  int rc = SQLITE_OK;
  2389         -  if( id ){
  2390         -    flockUnlock(id, NO_LOCK);
  2391         -    rc = closeUnixFile(id);
  2392         -  }
  2393         -  return rc;
         2368  +  assert( id!=0 );
         2369  +  flockUnlock(id, NO_LOCK);
         2370  +  return closeUnixFile(id);
  2394   2371   }
  2395   2372   
  2396   2373   #endif /* SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORK */
  2397   2374   
  2398   2375   /******************* End of the flock lock implementation *********************
  2399   2376   ******************************************************************************/
  2400   2377   
................................................................................
  3011   2988   }
  3012   2989   
  3013   2990   /*
  3014   2991   ** Close a file & cleanup AFP specific locking context 
  3015   2992   */
  3016   2993   static int afpClose(sqlite3_file *id) {
  3017   2994     int rc = SQLITE_OK;
  3018         -  if( id ){
  3019         -    unixFile *pFile = (unixFile*)id;
  3020         -    afpUnlock(id, NO_LOCK);
  3021         -    unixEnterMutex();
  3022         -    if( pFile->pInode && pFile->pInode->nLock ){
  3023         -      /* If there are outstanding locks, do not actually close the file just
  3024         -      ** yet because that would clear those locks.  Instead, add the file
  3025         -      ** descriptor to pInode->aPending.  It will be automatically closed when
  3026         -      ** the last lock is cleared.
  3027         -      */
  3028         -      setPendingFd(pFile);
  3029         -    }
  3030         -    releaseInodeInfo(pFile);
  3031         -    sqlite3_free(pFile->lockingContext);
  3032         -    rc = closeUnixFile(id);
  3033         -    unixLeaveMutex();
         2995  +  unixFile *pFile = (unixFile*)id;
         2996  +  assert( id!=0 );
         2997  +  afpUnlock(id, NO_LOCK);
         2998  +  unixEnterMutex();
         2999  +  if( pFile->pInode && pFile->pInode->nLock ){
         3000  +    /* If there are outstanding locks, do not actually close the file just
         3001  +    ** yet because that would clear those locks.  Instead, add the file
         3002  +    ** descriptor to pInode->aPending.  It will be automatically closed when
         3003  +    ** the last lock is cleared.
         3004  +    */
         3005  +    setPendingFd(pFile);
  3034   3006     }
         3007  +  releaseInodeInfo(pFile);
         3008  +  sqlite3_free(pFile->lockingContext);
         3009  +  rc = closeUnixFile(id);
         3010  +  unixLeaveMutex();
  3035   3011     return rc;
  3036   3012   }
  3037   3013   
  3038   3014   #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */
  3039   3015   /*
  3040   3016   ** The code above is the AFP lock implementation.  The code is specific
  3041   3017   ** to MacOSX and does not work on other unix platforms.  No alternative
................................................................................
  7370   7346     return rc;
  7371   7347   }
  7372   7348   
  7373   7349   /*
  7374   7350   ** Close a file that uses proxy locks.
  7375   7351   */
  7376   7352   static int proxyClose(sqlite3_file *id) {
  7377         -  if( id ){
         7353  +  if( ALWAYS(id) ){
  7378   7354       unixFile *pFile = (unixFile*)id;
  7379   7355       proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext;
  7380   7356       unixFile *lockProxy = pCtx->lockProxy;
  7381   7357       unixFile *conchFile = pCtx->conchFile;
  7382   7358       int rc = SQLITE_OK;
  7383   7359       
  7384   7360       if( lockProxy ){