⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 test_async.c

📁 最新的sqlite3.6.2源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
*/static int asyncLock(sqlite3_file *pFile, int eLock){  int rc = SQLITE_OK;  AsyncFileData *p = ((AsyncFile *)pFile)->pData;  pthread_mutex_lock(&async.lockMutex);  if( p->lock.eLock<eLock ){    AsyncLock *pLock;    AsyncFileLock *pIter;    pLock = (AsyncLock *)sqlite3HashFind(&async.aLock, p->zName, p->nName);    assert(pLock && pLock->pList);    for(pIter=pLock->pList; pIter; pIter=pIter->pNext){      if( pIter!=&p->lock && (        (eLock==SQLITE_LOCK_EXCLUSIVE && pIter->eLock>=SQLITE_LOCK_SHARED) ||        (eLock==SQLITE_LOCK_PENDING && pIter->eLock>=SQLITE_LOCK_RESERVED) ||        (eLock==SQLITE_LOCK_RESERVED && pIter->eLock>=SQLITE_LOCK_RESERVED) ||        (eLock==SQLITE_LOCK_SHARED && pIter->eLock>=SQLITE_LOCK_PENDING)      )){        rc = SQLITE_BUSY;      }    }    if( rc==SQLITE_OK ){      p->lock.eLock = eLock;      p->lock.eAsyncLock = MAX(p->lock.eAsyncLock, eLock);    }    assert(p->lock.eAsyncLock>=p->lock.eLock);    if( rc==SQLITE_OK ){      rc = getFileLock(pLock);    }  }  pthread_mutex_unlock(&async.lockMutex);  ASYNC_TRACE(("LOCK %d (%s) rc=%d\n", eLock, p->zName, rc));  return rc;}static int asyncUnlock(sqlite3_file *pFile, int eLock){  AsyncFileData *p = ((AsyncFile *)pFile)->pData;  AsyncFileLock *pLock = &p->lock;  pthread_mutex_lock(&async.lockMutex);  pLock->eLock = MIN(pLock->eLock, eLock);  pthread_mutex_unlock(&async.lockMutex);  return addNewAsyncWrite(p, ASYNC_UNLOCK, 0, eLock, 0);}/*** This function is called when the pager layer first opens a database file** and is checking for a hot-journal.*/static int asyncCheckReservedLock(sqlite3_file *pFile, int *pResOut){  int ret = 0;  AsyncFileLock *pIter;  AsyncLock *pLock;  AsyncFileData *p = ((AsyncFile *)pFile)->pData;  pthread_mutex_lock(&async.lockMutex);  pLock = (AsyncLock *)sqlite3HashFind(&async.aLock, p->zName, p->nName);  for(pIter=pLock->pList; pIter; pIter=pIter->pNext){    if( pIter->eLock>=SQLITE_LOCK_RESERVED ){      ret = 1;    }  }  pthread_mutex_unlock(&async.lockMutex);  ASYNC_TRACE(("CHECK-LOCK %d (%s)\n", ret, p->zName));  *pResOut = ret;  return SQLITE_OK;}/* ** This is a no-op, as the asynchronous backend does not support locking.*/static int asyncFileControl(sqlite3_file *id, int op, void *pArg){  switch( op ){    case SQLITE_FCNTL_LOCKSTATE: {      pthread_mutex_lock(&async.lockMutex);      *(int*)pArg = ((AsyncFile*)id)->pData->lock.eLock;      pthread_mutex_unlock(&async.lockMutex);      return SQLITE_OK;    }  }  return SQLITE_ERROR;}/* ** Return the device characteristics and sector-size of the device. It** is not tricky to implement these correctly, as this backend might ** not have an open file handle at this point.*/static int asyncSectorSize(sqlite3_file *pFile){  return 512;}static int asyncDeviceCharacteristics(sqlite3_file *pFile){  return 0;}static int unlinkAsyncFile(AsyncFileData *pData){  AsyncLock *pLock;  AsyncFileLock **ppIter;  int rc = SQLITE_OK;  pLock = sqlite3HashFind(&async.aLock, pData->zName, pData->nName);  for(ppIter=&pLock->pList; *ppIter; ppIter=&((*ppIter)->pNext)){    if( (*ppIter)==&pData->lock ){      *ppIter = pData->lock.pNext;      break;    }  }  if( !pLock->pList ){    if( pLock->pFile ){      sqlite3OsClose(pLock->pFile);    }    sqlite3_free(pLock);    sqlite3HashInsert(&async.aLock, pData->zName, pData->nName, 0);    if( !sqliteHashFirst(&async.aLock) ){      sqlite3HashClear(&async.aLock);    }  }else{    rc = getFileLock(pLock);  }  return rc;}/*** Open a file.*/static int asyncOpen(  sqlite3_vfs *pAsyncVfs,  const char *zName,  sqlite3_file *pFile,  int flags,  int *pOutFlags){  static sqlite3_io_methods async_methods = {    1,                               /* iVersion */    asyncClose,                      /* xClose */    asyncRead,                       /* xRead */    asyncWrite,                      /* xWrite */    asyncTruncate,                   /* xTruncate */    asyncSync,                       /* xSync */    asyncFileSize,                   /* xFileSize */    asyncLock,                       /* xLock */    asyncUnlock,                     /* xUnlock */    asyncCheckReservedLock,          /* xCheckReservedLock */    asyncFileControl,                /* xFileControl */    asyncSectorSize,                 /* xSectorSize */    asyncDeviceCharacteristics       /* xDeviceCharacteristics */  };  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  AsyncFile *p = (AsyncFile *)pFile;  int nName = strlen(zName)+1;  int rc = SQLITE_OK;  int nByte;  AsyncFileData *pData;  AsyncLock *pLock = 0;  char *z;  int isExclusive = (flags&SQLITE_OPEN_EXCLUSIVE);  nByte = (    sizeof(AsyncFileData) +        /* AsyncFileData structure */    2 * pVfs->szOsFile +           /* AsyncFileData.pBaseRead and pBaseWrite */    nName                          /* AsyncFileData.zName */  );   z = sqlite3_malloc(nByte);  if( !z ){    return SQLITE_NOMEM;  }  memset(z, 0, nByte);  pData = (AsyncFileData*)z;  z += sizeof(pData[0]);  pData->pBaseRead = (sqlite3_file*)z;  z += pVfs->szOsFile;  pData->pBaseWrite = (sqlite3_file*)z;  z += pVfs->szOsFile;  pData->zName = z;  pData->nName = nName;  pData->close.pFileData = pData;  pData->close.op = ASYNC_CLOSE;  memcpy(pData->zName, zName, nName);  if( !isExclusive ){    rc = sqlite3OsOpen(pVfs, zName, pData->pBaseRead, flags, pOutFlags);    if( rc==SQLITE_OK && ((*pOutFlags)&SQLITE_OPEN_READWRITE) ){      rc = sqlite3OsOpen(pVfs, zName, pData->pBaseWrite, flags, 0);    }  }  pthread_mutex_lock(&async.lockMutex);  if( rc==SQLITE_OK ){    pLock = sqlite3HashFind(&async.aLock, pData->zName, pData->nName);    if( !pLock ){      pLock = sqlite3MallocZero(pVfs->szOsFile + sizeof(AsyncLock));      if( pLock ){        AsyncLock *pDelete;#ifdef ENABLE_FILE_LOCKING        if( flags&SQLITE_OPEN_MAIN_DB ){          pLock->pFile = (sqlite3_file *)&pLock[1];          rc = sqlite3OsOpen(pVfs, zName, pLock->pFile, flags, 0);          if( rc!=SQLITE_OK ){            sqlite3_free(pLock);            pLock = 0;          }        }#endif        pDelete = sqlite3HashInsert(          &async.aLock, pData->zName, pData->nName, (void *)pLock        );        if( pDelete ){          rc = SQLITE_NOMEM;          sqlite3_free(pLock);        }      }else{        rc = SQLITE_NOMEM;      }    }  }  if( rc==SQLITE_OK ){    HashElem *pElem;    p->pMethod = &async_methods;    p->pData = pData;    /* Link AsyncFileData.lock into the linked list of     ** AsyncFileLock structures for this file.    */    pData->lock.pNext = pLock->pList;    pLock->pList = &pData->lock;    pElem = sqlite3HashFindElem(&async.aLock, pData->zName, pData->nName);    pData->zName = (char *)sqliteHashKey(pElem);  }else{    sqlite3OsClose(pData->pBaseRead);    sqlite3OsClose(pData->pBaseWrite);    sqlite3_free(pData);  }  pthread_mutex_unlock(&async.lockMutex);  if( rc==SQLITE_OK ){    incrOpenFileCount();  }  if( rc==SQLITE_OK && isExclusive ){    rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (i64)flags, 0, 0);    if( rc==SQLITE_OK ){      if( pOutFlags ) *pOutFlags = flags;    }else{      pthread_mutex_lock(&async.lockMutex);      unlinkAsyncFile(pData);      pthread_mutex_unlock(&async.lockMutex);      sqlite3_free(pData);    }  }  return rc;}/*** Implementation of sqlite3OsDelete. Add an entry to the end of the ** write-op queue to perform the delete.*/static int asyncDelete(sqlite3_vfs *pAsyncVfs, const char *z, int syncDir){  return addNewAsyncWrite(0, ASYNC_DELETE, syncDir, strlen(z)+1, z);}/*** Implementation of sqlite3OsAccess. This method holds the mutex from** start to finish.*/static int asyncAccess(  sqlite3_vfs *pAsyncVfs,   const char *zName,   int flags,  int *pResOut){  int rc;  int ret;  AsyncWrite *p;  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  assert(flags==SQLITE_ACCESS_READWRITE       || flags==SQLITE_ACCESS_READ       || flags==SQLITE_ACCESS_EXISTS   );  pthread_mutex_lock(&async.queueMutex);  rc = sqlite3OsAccess(pVfs, zName, flags, &ret);  if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){    for(p=async.pQueueFirst; p; p = p->pNext){      if( p->op==ASYNC_DELETE && 0==strcmp(p->zBuf, zName) ){        ret = 0;      }else if( p->op==ASYNC_OPENEXCLUSIVE              && 0==strcmp(p->pFileData->zName, zName)       ){        ret = 1;      }    }  }  ASYNC_TRACE(("ACCESS(%s): %s = %d\n",     flags==SQLITE_ACCESS_READWRITE?"read-write":    flags==SQLITE_ACCESS_READ?"read":"exists"    , zName, ret)  );  pthread_mutex_unlock(&async.queueMutex);  *pResOut = ret;  return rc;}/*** Fill in zPathOut with the full path to the file identified by zPath.*/static int asyncFullPathname(  sqlite3_vfs *pAsyncVfs,   const char *zPath,   int nPathOut,  char *zPathOut){  int rc;  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  rc = sqlite3OsFullPathname(pVfs, zPath, nPathOut, zPathOut);  /* Because of the way intra-process file locking works, this backend  ** needs to return a canonical path. The following block assumes the  ** file-system uses unix style paths.   */  if( rc==SQLITE_OK ){    int iIn;    int iOut = 0;    int nPathOut = strlen(zPathOut);    for(iIn=0; iIn<nPathOut; iIn++){      /* Replace any occurences of "//" with "/" */      if( iIn<=(nPathOut-2) && zPathOut[iIn]=='/' && zPathOut[iIn+1]=='/'      ){        continue;      }      /* Replace any occurences of "/./" with "/" */      if( iIn<=(nPathOut-3)        && zPathOut[iIn]=='/' && zPathOut[iIn+1]=='.' && zPathOut[iIn+2]=='/'      ){        iIn++;        continue;      }      /* Replace any occurences of "<path-component>/../" with "" */      if( iOut>0 && iIn<=(nPathOut-4)        && zPathOut[iIn]=='/' && zPathOut[iIn+1]=='.'        && zPathOut[iIn+2]=='.' && zPathOut[iIn+3]=='/'      ){        iIn += 3;        iOut--;        for( ; iOut>0 && zPathOut[iOut-1]!='/'; iOut--);        continue;      }      zPathOut[iOut++] = zPathOut[iIn];    }    zPathOut[iOut] = '\0';  }  return rc;}static void *asyncDlOpen(sqlite3_vfs *pAsyncVfs, const char *zPath){  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  return pVfs->xDlOpen(pVfs, zPath);}static void asyncDlError(sqlite3_vfs *pAsyncVfs, int nByte, char *zErrMsg){  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  pVfs->xDlError(pVfs, nByte, zErrMsg);}static void *asyncDlSym(  sqlite3_vfs *pAsyncVfs,   void *pHandle,   const char *zSymbol){  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  return pVfs->xDlSym(pVfs, pHandle, zSymbol);}static void asyncDlClose(sqlite3_vfs *pAsyncVfs, void *pHandle){  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  pVfs->xDlClose(pVfs, pHandle);}static int asyncRandomness(sqlite3_vfs *pAsyncVfs, int nByte, char *zBufOut){  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  return pVfs->xRandomness(pVfs, nByte, zBufOut);}static int asyncSleep(sqlite3_vfs *pAsyncVfs, int nMicro){  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  return pVfs->xSleep(pVfs, nMicro);}static int asyncCurrentTime(sqlite3_vfs *pAsyncVfs, double *pTimeOut){  sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData;  return pVfs->xCurrentTime(pVfs, pTimeOut);}static sqlite3_vfs async_vfs = {  1,                    /* iVersion */  sizeof(AsyncFile),    /* szOsFile */  0,                    /* mxPathname */  0,                    /* pNext */  "async",              /* zName */  0,                    /* pAppData */  asyncOpen,            /* xOpen */  asyncDelete,          /* xDelete */  asyncAccess,          /* xAccess */  asyncFullPathname,    /* xFullPathname */  asyncDlOpen,          /* xDlOpen */  asyncDlError,         /* xDlError */  asyncDlSym,           /* xDlSym */  asyncDlClose,         /* xDlClose */  asyncRandomness,      /* xDlError */  asyncSleep,           /* xDlSym */  asyncCurrentTime      /* xDlClose */};/*** Call this routine to enable or disable the** asynchronous IO features implemented in this file. **** This routine is not even remotely threadsafe.  Do not call** this routine while any SQLite database connections are open.*/static void asyncEnable(int enable){  if( enable ){    if( !async_vfs.pAppData ){      static int hashTableInit = 0;      async_vfs.pAppData = (void *)sqlite3_vfs_find(0);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -