Code staticint winLock(OsFile *id, int locktype){ int rc = SQLITE_OK; /* Return code from subroutines */ int res =1; /* Result of a windows lock call */ int newLocktype; /* Set id->locktype to this value before exiting */ int gotPendingLock =0;/* True if we acquired a PENDING lock this time */ winFile *pFile = (winFile*)id;
/* If there is already a lock of this type or more restrictive on the ** OsFile, do nothing. Don't use the end_lock: exit path, as ** sqlite3OsEnterMutex() hasn't been called yet. */ //当前的锁>=locktype,则返回 if( pFile->locktype>=locktype ){ return SQLITE_OK; }
/* Make sure the locking sequence is correct */ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); assert( locktype!=PENDING_LOCK ); assert( locktype!=RESERVED_LOCK || pFile->locktype==SHARED_LOCK );
/* Lock the PENDING_LOCK byte if we need to acquire a PENDING lock or ** a SHARED lock. If we are acquiring a SHARED lock, the acquisition of ** the PENDING_LOCK byte is temporary. */ newLocktype = pFile->locktype; /*两种情况: (1)如果当前文件处于无锁状态(获取读锁---读事务 **和写事务在最初阶段都要经历的阶段), **(2)处于RESERVED_LOCK,且请求的锁为EXCLUSIVE_LOCK(写事务) **则对执行加PENDING_LOCK */ /////////////////////(1)/////////////////// if( pFile->locktype==NO_LOCK || (locktype==EXCLUSIVE_LOCK && pFile->locktype==RESERVED_LOCK) ){ int cnt =3; //加pending锁 while( cnt-->0&& (res = LockFile(pFile->h, PENDING_BYTE, 0, 1, 0))==0 ){ /* Try 3 times to get the pending lock. The pending lock might be ** held by another reader process who will release it momentarily. */ TRACE2("could not get a PENDING lock. cnt=%d/n", cnt); Sleep(1); } //设置为gotPendingLock为1,使和在后面要释放PENDING锁 gotPendingLock = res; }
/* Acquire a shared lock */ /*获取shared lock **此时,事务应该持有PENDING锁,而PENDING锁作为事务从UNLOCKED到 **SHARED_LOCKED的一个过渡,所以事务由PENDING->SHARED **此时,实际上锁处于两个状态:PENDING和SHARED, **直到后面释放PENDING锁后,才真正处于SHARED状态 */ ////////////////(2)///////////////////////////////////// if( locktype==SHARED_LOCK && res ){ assert( pFile->locktype==NO_LOCK ); res = getReadLock(pFile); if( res ){ newLocktype = SHARED_LOCK; } }
/* Acquire a RESERVED lock */ /*获取RESERVED **此时事务持有SHARED_LOCK,变化过程为SHARED->RESERVED。 **RESERVED锁的作用就是为了提高系统的并发性能 */ ////////////////////////(3)///////////////////////////////// if( locktype==RESERVED_LOCK && res ){ assert( pFile->locktype==SHARED_LOCK ); //加RESERVED锁 res = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0); if( res ){ newLocktype = RESERVED_LOCK; } }
/* Acquire an EXCLUSIVE lock */ /*获取EXCLUSIVE锁 **当一个事务执行该代码时,它应该满足以下条件: **(1)锁的状态为:PENDING (2)是一个写事务 **变化过程:PENDING->EXCLUSIVE */ /////////////////////////(5)/////////////////////////////////////////// if( locktype==EXCLUSIVE_LOCK && res ){ assert( pFile->locktype>=SHARED_LOCK ); res = unlockReadLock(pFile); TRACE2("unreadlock = %d/n", res); res = LockFile(pFile->h, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ newLocktype = EXCLUSIVE_LOCK; }else{ TRACE2("error-code = %d/n", GetLastError()); } }
/* If we are holding a PENDING lock that ought to be released, then ** release it now. */ /*此时事务在第2步中获得PENDING锁,它将申请SHARED_LOCK(第3步,和图形相对照), **而在之前它已经获取了PENDING锁, **所以在这里它需要释放PENDING锁,此时锁的变化为:PENDING->SHARED */ //////////////////////////(6)///////////////////////////////////// if( gotPendingLock && locktype==SHARED_LOCK ){ UnlockFile(pFile->h, PENDING_BYTE, 0, 1, 0); }
/* Update the state of the lock has held in the file descriptor then ** return the appropriate result code. */ if( res ){ rc = SQLITE_OK; }else{ TRACE4("LOCK FAILED %d trying for %d but got %d/n", pFile->h, locktype, newLocktype); rc = SQLITE_BUSY; } //在这里设置文件锁的状态 pFile->locktype = newLocktype; return rc; }