Index: src/os_unix.c ================================================================== --- src/os_unix.c +++ src/os_unix.c @@ -712,10 +712,13 @@ } #ifdef SQLITE_DEBUG static int unixMutexHeld(void) { return sqlite3_mutex_held(unixBigLock); } +static int unixMutexNotheld(void) { + return sqlite3_mutex_notheld(unixBigLock); +} #endif #ifdef SQLITE_HAVE_OS_TRACE /* @@ -1247,11 +1250,11 @@ } /* ** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. */ -static void closePendingFds(unixFile *pFile){ +static void closePendingFdsUnsafe(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; UnixUnusedFd *pNext; for(p=pInode->pUnused; p; p=pNext){ pNext = p->pNext; @@ -1259,10 +1262,16 @@ sqlite3_free(p); nUnusedFd--; } pInode->pUnused = 0; } + +static void closePendingFds(unixFile *pFile){ + unixEnterMutex(); + closePendingFdsUnsafe(pFile); + unixLeaveMutex(); +} /* ** Release a unixInodeInfo structure previously allocated by findInodeInfo(). ** ** The mutex entered using the unixEnterMutex() function must be held @@ -1273,11 +1282,11 @@ assert( unixMutexHeld() ); if( ALWAYS(pInode) ){ pInode->nRef--; if( pInode->nRef==0 ){ assert( pInode->pShmNode==0 ); - closePendingFds(pFile); + closePendingFdsUnsafe(pFile); if( pInode->pPrev ){ assert( pInode->pPrev->pNext==pInode ); pInode->pPrev->pNext = pInode->pNext; }else{ assert( inodeList==pInode ); @@ -1456,10 +1465,11 @@ SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); assert( pFile ); assert( pFile->eFileLock<=SHARED_LOCK ); + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; @@ -1668,10 +1678,11 @@ assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); /* This mutex is needed because pFile->pInode is shared across threads */ pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ @@ -1860,10 +1871,11 @@ assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); @@ -2791,10 +2803,11 @@ context = (afpLockingContext *) pFile->lockingContext; if( context->reserved ){ *pResOut = 1; return SQLITE_OK; } + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pFile->pInode->pLockMutex); /* Check if a thread in this process holds such a lock */ if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; } @@ -2879,10 +2892,11 @@ assert( eFileLock!=RESERVED_LOCK || pFile->eFileLock==SHARED_LOCK ); /* This mutex is needed because pFile->pInode is shared across threads */ pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ @@ -3048,10 +3062,11 @@ assert( eFileLock<=SHARED_LOCK ); if( pFile->eFileLock<=eFileLock ){ return SQLITE_OK; } pInode = pFile->pInode; + assert( unixMutexNotheld() ); sqlite3_mutex_enter(pInode->pLockMutex); assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); SimulateIOErrorBenign(1);