/* ** Shared-memory methods are all pass-thrus. */ static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ devsym_file *p = (devsym_file *)pFile; return sqlite3OsShmLock(p->pReal, ofst, n, flags); }
/* ** Pass-throughs for WAL support. */ static int cfShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, ofst, n, flags); }
static int tvfsShmLock( sqlite3_file *pFile, int ofst, int n, int flags ){ int rc = SQLITE_OK; TestvfsFd *pFd = tvfsGetFd(pFile); Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData); int nLock; char zLock[80]; if( p->isFullshm ){ return sqlite3OsShmLock(pFd->pReal, ofst, n, flags); } if( p->pScript && p->mask&TESTVFS_SHMLOCK_MASK ){ sqlite3_snprintf(sizeof(zLock), zLock, "%d %d", ofst, n); nLock = (int)strlen(zLock); if( flags & SQLITE_SHM_LOCK ){ strcpy(&zLock[nLock], " lock"); }else{ strcpy(&zLock[nLock], " unlock"); } nLock += (int)strlen(&zLock[nLock]); if( flags & SQLITE_SHM_SHARED ){ strcpy(&zLock[nLock], " shared"); }else{ strcpy(&zLock[nLock], " exclusive"); } tvfsExecTcl(p, "xShmLock", Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, Tcl_NewStringObj(zLock, -1), 0 ); tvfsResultCode(p, &rc); } if( rc==SQLITE_OK && p->mask&TESTVFS_SHMLOCK_MASK && tvfsInjectIoerr(p) ){ rc = SQLITE_IOERR; } if( rc==SQLITE_OK ){ int isLock = (flags & SQLITE_SHM_LOCK); int isExcl = (flags & SQLITE_SHM_EXCLUSIVE); u32 mask = (((1<<n)-1) << ofst); if( isLock ){ TestvfsFd *p2; for(p2=pFd->pShm->pFile; p2; p2=p2->pNext){ if( p2==pFd ) continue; if( (p2->excllock&mask) || (isExcl && p2->sharedlock&mask) ){ rc = SQLITE_BUSY; break; } } if( rc==SQLITE_OK ){ if( isExcl ) pFd->excllock |= mask; if( !isExcl ) pFd->sharedlock |= mask; } }else{ if( isExcl ) pFd->excllock &= (~mask); if( !isExcl ) pFd->sharedlock &= (~mask); } } return rc; }