Sqlite源码解读(七)

2021SC@SDUSC

上次讲了各种字符串相互转换的方法及对应的公共包装器,接下来将讲解SQLITE_OS_WINCE,即sqlite在操作系统WinCE上的代码。

获取手柄上的锁

static void winceMutexAcquire(HANDLE h){

   DWORD dwErr;

   do {

     dwErr = osWaitForSingleObject(h, INFINITE);

   } while (dwErr != WAIT_OBJECT_0 && dwErr != WAIT_ABANDONED);

}

释放锁

#define winceMutexRelease(h) ReleaseMutex(h)

创建用于锁定文件描述符Pfile的互斥和共享内存

static int winceCreateLock(const char *zFilename, winFile *pFile){

  LPWSTR zTok;

  LPWSTR zName;

  DWORD lastErrno;

  BOOL bLogged = FALSE;

  BOOL bInit = TRUE;

  zName = winUtf8ToUnicode(zFilename);

  if( zName==0 ){

   /*内存不足*/

    return SQLITE_IOERR_NOMEM_BKPT;

  }

/*初始化本地锁数据*/

memset(&pFile->local, 0, sizeof(pFile->local));

替换文件名中的反斜杠,并将其小写以派生互斥名称。

zTok = osCharLowerW(zName);

  for (;*zTok;zTok++){

    if (*zTok == '\\') *zTok = '_';

  }

创建或打开命名的互斥体

pFile->hMutex = osCreateMutexW(NULL, FALSE, zName);

  if (!pFile->hMutex){

    pFile->lastErrno = osGetLastError();

    sqlite3_free(zName);

return winLogError(SQLITE_IOERR, pFile->lastErrno, "winceCreateLock1", zFilename);

 }

/*在继续下一步之前获取互斥体*/

winceMutexAcquire(pFile->hMutex);

注:由于命名互斥体、信号量、文件映射等的名称都是区分大小写的,因此可以利用这一点,将互斥名称大写,并将其用作共享的文件映射名称。

osCharUpperW(zName);

  pFile->hShared = osCreateFileMappingW(INVALID_HANDLE_VALUE, NULL,

                                        PAGE_READWRITE, 0, sizeof(winceLock),

                                        zName);

设置一个标志,指示我们是第一个创建内存的,因此它必须为零初始化

lastErrno = osGetLastError();

  if (lastErrno == ERROR_ALREADY_EXISTS){

    bInit = FALSE;

  }

sqlite3_free(zName);

如果我们成功地创建了共享内存句柄,则映射它。

if( pFile->hShared ){

    pFile->shared = (winceLock*)osMapViewOfFile(pFile->hShared,

             FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, sizeof(winceLock));

/* 如果映射失败,则关闭共享内存句柄并清除它*/

    if( !pFile->shared ){

      pFile->lastErrno = osGetLastError();

      winLogError(SQLITE_IOERR, pFile->lastErrno,

                  "winceCreateLock2", zFilename);

      bLogged = TRUE;

      osCloseHandle(pFile->hShared);

      pFile->hShared = NULL;

    }

  }

/*如果无法创建共享内存,则关闭互斥锁并失败*/

if( pFile->hShared==NULL ){

    if( !bLogged ){

      pFile->lastErrno = lastErrno;

      winLogError(SQLITE_IOERR, pFile->lastErrno,

                  "winceCreateLock3", zFilename);

      bLogged = TRUE;

    }

    winceMutexRelease(pFile->hMutex);

    osCloseHandle(pFile->hMutex);

    pFile->hMutex = NULL;

    return SQLITE_IOERR;

  }

初始化共享内存(如果我们需要的话)

if( bInit ){

    memset(pFile->shared, 0, sizeof(winceLock));

  }

  winceMutexRelease(pFile->hMutex);

  return SQLITE_OK;

}

销毁winFile中处理WinCE锁的部分

static void winceDestroyLock(winFile *pFile){

  if (pFile->hMutex){

    /* 获取互斥体 */

    winceMutexAcquire(pFile->hMutex);

    /* 以下块可能应该在调试模式下断言,但它们将被清除,以防任何锁仍然处于打开状态*/

    if (pFile->local.nReaders){

      pFile->shared->nReaders --;

    }

    if (pFile->local.bReserved){

      pFile->shared->bReserved = FALSE;

    }

    if (pFile->local.bPending){

      pFile->shared->bPending = FALSE;

    }

    if (pFile->local.bExclusive){

      pFile->shared->bExclusive = FALSE;

    }

    /* 取消引用并关闭共享内存句柄的副本。 */

    osUnmapViewOfFile(pFile->shared);

    osCloseHandle(pFile->hShared);

    /* 完成互斥 */

    winceMutexRelease(pFile->hMutex);

    osCloseHandle(pFile->hMutex);

    pFile->hMutex = NULL;

  }

}

WindowsforCE中LockFile() API的一种实现

static BOOL winceLockFile(

  LPHANDLE phFile,

  DWORD dwFileOffsetLow,

  DWORD dwFileOffsetHigh,

  DWORD nNumberOfBytesToLockLow,

  DWORD nNumberOfBytesToLockHigh

){

  winFile *pFile = HANDLE_TO_WINFILE(phFile);

  BOOL bReturn = FALSE;

  UNUSED_PARAMETER(dwFileOffsetHigh);

  UNUSED_PARAMETER(nNumberOfBytesToLockHigh);

  if (!pFile->hMutex) return TRUE;

  winceMutexAcquire(pFile->hMutex);

/*独占锁*/

if (dwFileOffsetLow == (DWORD)SHARED_FIRST

       && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){

    if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){

       pFile->shared->bExclusive = TRUE;

       pFile->local.bExclusive = TRUE;

       bReturn = TRUE;

    }

  }

/*只读锁*/

else if (dwFileOffsetLow == (DWORD)SHARED_FIRST &&

           nNumberOfBytesToLockLow == 1){

    if (pFile->shared->bExclusive == 0){

      pFile->local.nReaders ++;

      if (pFile->local.nReaders == 1){

        pFile->shared->nReaders ++;

      }

      bReturn = TRUE;

    }

  }

/*挂起锁*/

else if (dwFileOffsetLow == (DWORD)PENDING_BYTE

           && nNumberOfBytesToLockLow == 1){

    /* 如果还未获取挂起锁,则获取它 */

    if (pFile->shared->bPending == 0) {

      pFile->shared->bPending = TRUE;

      pFile->local.bPending = TRUE;

      bReturn = TRUE;

    }

  }

/*保留锁*/

else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE

           && nNumberOfBytesToLockLow == 1){

    if (pFile->shared->bReserved == 0) {

      pFile->shared->bReserved = TRUE;

      pFile->local.bReserved = TRUE;

      bReturn = TRUE;

    }

  }

  winceMutexRelease(pFile->hMutex);

  return bReturn;

}

对应地,以下是WindowsforCE中UnlockFile() API的一种实现

static BOOL winceUnlockFile(

  LPHANDLE phFile,

  DWORD dwFileOffsetLow,

  DWORD dwFileOffsetHigh,

  DWORD nNumberOfBytesToUnlockLow,

  DWORD nNumberOfBytesToUnlockHigh

){

  winFile *pFile = HANDLE_TO_WINFILE(phFile);

  BOOL bReturn = FALSE;

  UNUSED_PARAMETER(dwFileOffsetHigh);

  UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh);

  if (!pFile->hMutex) return TRUE;

  winceMutexAcquire(pFile->hMutex);

/*释放一个读卡器锁或者是独占锁*/

if (dwFileOffsetLow == (DWORD)SHARED_FIRST){

    /* Did we have an exclusive lock? */

    if (pFile->local.bExclusive){

      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);

      pFile->local.bExclusive = FALSE;

      pFile->shared->bExclusive = FALSE;

      bReturn = TRUE;

    }

/*我们有一个读卡器锁吗*/

if (pFile->local.bExclusive){

      assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE);

      pFile->local.bExclusive = FALSE;

      pFile->shared->bExclusive = FALSE;

      bReturn = TRUE;

    }

/*释放挂起锁*/

else if (dwFileOffsetLow == (DWORD)PENDING_BYTE

           && nNumberOfBytesToUnlockLow == 1){

    if (pFile->local.bPending){

      pFile->local.bPending = FALSE;

      pFile->shared->bPending = FALSE;

      bReturn = TRUE;

    }

  }

 /*释放保留锁*/

else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE

           && nNumberOfBytesToUnlockLow == 1){

    if (pFile->local.bReserved) {

      pFile->local.bReserved = FALSE;

      pFile->shared->bReserved = FALSE;

      bReturn = TRUE;

    }

  }

winceMutexRelease(pFile->hMutex);

  return bReturn;

}

以上即是WinCE的特殊代码,SQLITE_OS_WINCE部分结束。

猜你喜欢

转载自blog.csdn.net/qq_53825872/article/details/121334027