LCOV - code coverage report
Current view: directory - storage/src - TelemetryVFS.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 203 162 79.8 %
Date: 2012-06-02 Functions: 35 23 65.7 %

       1                 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
       2                 :  * vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
       3                 :  * ***** BEGIN LICENSE BLOCK *****
       4                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       5                 :  *
       6                 :  * The contents of this file are subject to the Mozilla Public License Version
       7                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       8                 :  * the License. You may obtain a copy of the License at
       9                 :  * http://www.mozilla.org/MPL/
      10                 :  *
      11                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      12                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      13                 :  * for the specific language governing rights and limitations under the
      14                 :  * License.
      15                 :  *
      16                 :  * The Original Code is Oracle Corporation code.
      17                 :  *
      18                 :  * The Initial Developer of the Original Code is
      19                 :  *  Oracle Corporation
      20                 :  * Portions created by the Initial Developer are Copyright (C) 2011
      21                 :  * the Initial Developer. All Rights Reserved.
      22                 :  *
      23                 :  * Contributor(s):
      24                 :  *   Taras Glek <tglek@mozilla.com>
      25                 :  *
      26                 :  * Alternatively, the contents of this file may be used under the terms of
      27                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      28                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      29                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      30                 :  * of those above. If you wish to allow use of your version of this file only
      31                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      32                 :  * use your version of this file under the terms of the MPL, indicate your
      33                 :  * decision by deleting the provisions above and replace them with the notice
      34                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      35                 :  * the provisions above, a recipient may use your version of this file under
      36                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      37                 :  *
      38                 :  * ***** END LICENSE BLOCK ***** */
      39                 : 
      40                 : #include <string.h>
      41                 : #include "mozilla/Telemetry.h"
      42                 : #include "sqlite3.h"
      43                 : #include "nsThreadUtils.h"
      44                 : #include "mozilla/Util.h"
      45                 : 
      46                 : namespace {
      47                 : 
      48                 : using namespace mozilla;
      49                 : 
      50                 : struct Histograms {
      51                 :   const char *name;
      52                 :   const Telemetry::ID readB;
      53                 :   const Telemetry::ID writeB;
      54                 :   const Telemetry::ID readMS;
      55                 :   const Telemetry::ID writeMS;
      56                 :   const Telemetry::ID syncMS;
      57                 : };
      58                 : 
      59                 : #define SQLITE_TELEMETRY(FILENAME, HGRAM) \
      60                 :   { FILENAME, \
      61                 :     Telemetry::MOZ_SQLITE_ ## HGRAM ## _READ_B, \
      62                 :     Telemetry::MOZ_SQLITE_ ## HGRAM ## _WRITE_B, \
      63                 :     Telemetry::MOZ_SQLITE_ ## HGRAM ## _READ_MS, \
      64                 :     Telemetry::MOZ_SQLITE_ ## HGRAM ## _WRITE_MS, \
      65                 :     Telemetry::MOZ_SQLITE_ ## HGRAM ## _SYNC_MS \
      66                 :   }
      67                 : 
      68                 : Histograms gHistograms[] = {
      69                 :   SQLITE_TELEMETRY("places.sqlite", PLACES),
      70                 :   SQLITE_TELEMETRY("urlclassifier3.sqlite", URLCLASSIFIER),
      71                 :   SQLITE_TELEMETRY("cookies.sqlite", COOKIES),
      72                 :   SQLITE_TELEMETRY("webappsstore.sqlite", WEBAPPS),
      73                 :   SQLITE_TELEMETRY(NULL, OTHER)
      74                 : };
      75                 : #undef SQLITE_TELEMETRY
      76                 : 
      77                 : /** RAII class for measuring how long io takes on/off main thread
      78                 :  */
      79                 : class IOThreadAutoTimer {
      80                 : public:
      81                 :   /** 
      82                 :    * IOThreadAutoTimer measures time spent in IO. Additionally it
      83                 :    * automatically determines whether IO is happening on the main
      84                 :    * thread and picks an appropriate histogram.
      85                 :    *
      86                 :    * @param id takes a telemetry histogram id. The id+1 must be an
      87                 :    * equivalent histogram for the main thread. Eg, MOZ_SQLITE_OPEN_MS 
      88                 :    * is followed by MOZ_SQLITE_OPEN_MAIN_THREAD_MS.
      89                 :    */
      90          509052 :   IOThreadAutoTimer(Telemetry::ID id)
      91                 :     : start(TimeStamp::Now()),
      92          509052 :       id(id)
      93                 :   {
      94          509052 :   }
      95                 : 
      96          509052 :   ~IOThreadAutoTimer() {
      97          509052 :     PRUint32 mainThread = NS_IsMainThread() ? 1 : 0;
      98                 :     Telemetry::AccumulateTimeDelta(static_cast<Telemetry::ID>(id + mainThread),
      99          509052 :                                    start);
     100          509052 :   }
     101                 : 
     102                 : private:
     103                 :   const TimeStamp start;
     104                 :   const Telemetry::ID id;
     105                 : };
     106                 : 
     107                 : struct telemetry_file {
     108                 :   sqlite3_file base;        // Base class.  Must be first
     109                 :   Histograms *histograms;   // histograms pertaining to this file
     110                 :   sqlite3_file pReal[1];    // This contains the vfs that actually does work
     111                 : };
     112                 : 
     113                 : /*
     114                 : ** Close a telemetry_file.
     115                 : */
     116                 : int
     117           11040 : xClose(sqlite3_file *pFile)
     118                 : {
     119           11040 :   telemetry_file *p = (telemetry_file *)pFile;
     120                 :   int rc;
     121           11040 :   rc = p->pReal->pMethods->xClose(p->pReal);
     122           11040 :   if( rc==SQLITE_OK ){
     123           11040 :     delete p->base.pMethods;
     124           11040 :     p->base.pMethods = NULL;
     125                 :   }
     126           11040 :   return rc;
     127                 : }
     128                 : 
     129                 : /*
     130                 : ** Read data from a telemetry_file.
     131                 : */
     132                 : int
     133           78549 : xRead(sqlite3_file *pFile, void *zBuf, int iAmt, sqlite_int64 iOfst)
     134                 : {
     135           78549 :   telemetry_file *p = (telemetry_file *)pFile;
     136          157098 :   IOThreadAutoTimer ioTimer(p->histograms->readMS);
     137                 :   int rc;
     138           78549 :   rc = p->pReal->pMethods->xRead(p->pReal, zBuf, iAmt, iOfst);
     139                 :   // sqlite likes to read from empty files, this is normal, ignore it.
     140           78549 :   if (rc != SQLITE_IOERR_SHORT_READ)
     141           71909 :     Telemetry::Accumulate(p->histograms->readB, rc == SQLITE_OK ? iAmt : 0);
     142           78549 :   return rc;
     143                 : }
     144                 : 
     145                 : /*
     146                 : ** Write data to a telemetry_file.
     147                 : */
     148                 : int
     149          384007 : xWrite(sqlite3_file *pFile, const void *zBuf, int iAmt, sqlite_int64 iOfst)
     150                 : {
     151          384007 :   telemetry_file *p = (telemetry_file *)pFile;
     152          768014 :   IOThreadAutoTimer ioTimer(p->histograms->writeMS);
     153                 :   int rc;
     154          384007 :   rc = p->pReal->pMethods->xWrite(p->pReal, zBuf, iAmt, iOfst);
     155          384007 :   Telemetry::Accumulate(p->histograms->writeB, rc == SQLITE_OK ? iAmt : 0);
     156          384007 :   return rc;
     157                 : }
     158                 : 
     159                 : /*
     160                 : ** Truncate a telemetry_file.
     161                 : */
     162                 : int
     163            7695 : xTruncate(sqlite3_file *pFile, sqlite_int64 size)
     164                 : {
     165           15390 :   IOThreadAutoTimer ioTimer(Telemetry::MOZ_SQLITE_TRUNCATE_MS);
     166            7695 :   telemetry_file *p = (telemetry_file *)pFile;
     167                 :   int rc;
     168           15390 :   Telemetry::AutoTimer<Telemetry::MOZ_SQLITE_TRUNCATE_MS> timer;
     169            7695 :   rc = p->pReal->pMethods->xTruncate(p->pReal, size);
     170            7695 :   return rc;
     171                 : }
     172                 : 
     173                 : /*
     174                 : ** Sync a telemetry_file.
     175                 : */
     176                 : int
     177           27757 : xSync(sqlite3_file *pFile, int flags)
     178                 : {
     179           27757 :   telemetry_file *p = (telemetry_file *)pFile;
     180           55514 :   IOThreadAutoTimer ioTimer(p->histograms->syncMS);
     181           27757 :   return p->pReal->pMethods->xSync(p->pReal, flags);
     182                 : }
     183                 : 
     184                 : /*
     185                 : ** Return the current file-size of a telemetry_file.
     186                 : */
     187                 : int
     188           55651 : xFileSize(sqlite3_file *pFile, sqlite_int64 *pSize)
     189                 : {
     190           55651 :   telemetry_file *p = (telemetry_file *)pFile;
     191                 :   int rc;
     192           55651 :   rc = p->pReal->pMethods->xFileSize(p->pReal, pSize);
     193           55651 :   return rc;
     194                 : }
     195                 : 
     196                 : /*
     197                 : ** Lock a telemetry_file.
     198                 : */
     199                 : int
     200           31534 : xLock(sqlite3_file *pFile, int eLock)
     201                 : {
     202           31534 :   telemetry_file *p = (telemetry_file *)pFile;
     203                 :   int rc;
     204           31534 :   rc = p->pReal->pMethods->xLock(p->pReal, eLock);
     205           31534 :   return rc;
     206                 : }
     207                 : 
     208                 : /*
     209                 : ** Unlock a telemetry_file.
     210                 : */
     211                 : int
     212           25243 : xUnlock(sqlite3_file *pFile, int eLock)
     213                 : {
     214           25243 :   telemetry_file *p = (telemetry_file *)pFile;
     215                 :   int rc;
     216           25243 :   rc = p->pReal->pMethods->xUnlock(p->pReal, eLock);
     217           25243 :   return rc;
     218                 : }
     219                 : 
     220                 : /*
     221                 : ** Check if another file-handle holds a RESERVED lock on a telemetry_file.
     222                 : */
     223                 : int
     224               0 : xCheckReservedLock(sqlite3_file *pFile, int *pResOut)
     225                 : {
     226               0 :   telemetry_file *p = (telemetry_file *)pFile;
     227               0 :   int rc = p->pReal->pMethods->xCheckReservedLock(p->pReal, pResOut);
     228               0 :   return rc;
     229                 : }
     230                 : 
     231                 : /*
     232                 : ** File control method. For custom operations on a telemetry_file.
     233                 : */
     234                 : int
     235            6080 : xFileControl(sqlite3_file *pFile, int op, void *pArg)
     236                 : {
     237            6080 :   telemetry_file *p = (telemetry_file *)pFile;
     238            6080 :   int rc = p->pReal->pMethods->xFileControl(p->pReal, op, pArg);
     239            6080 :   return rc;
     240                 : }
     241                 : 
     242                 : /*
     243                 : ** Return the sector-size in bytes for a telemetry_file.
     244                 : */
     245                 : int
     246               0 : xSectorSize(sqlite3_file *pFile)
     247                 : {
     248               0 :   telemetry_file *p = (telemetry_file *)pFile;
     249                 :   int rc;
     250               0 :   rc = p->pReal->pMethods->xSectorSize(p->pReal);
     251               0 :   return rc;
     252                 : }
     253                 : 
     254                 : /*
     255                 : ** Return the device characteristic flags supported by a telemetry_file.
     256                 : */
     257                 : int
     258           37131 : xDeviceCharacteristics(sqlite3_file *pFile)
     259                 : {
     260           37131 :   telemetry_file *p = (telemetry_file *)pFile;
     261                 :   int rc;
     262           37131 :   rc = p->pReal->pMethods->xDeviceCharacteristics(p->pReal);
     263           37131 :   return rc;
     264                 : }
     265                 : 
     266                 : /*
     267                 : ** Shared-memory operations.
     268                 : */
     269                 : int
     270          237317 : xShmLock(sqlite3_file *pFile, int ofst, int n, int flags)
     271                 : {
     272          237317 :   telemetry_file *p = (telemetry_file *)pFile;
     273          237317 :   return p->pReal->pMethods->xShmLock(p->pReal, ofst, n, flags);
     274                 : }
     275                 : 
     276                 : int
     277             779 : xShmMap(sqlite3_file *pFile, int iRegion, int szRegion, int isWrite, void volatile **pp)
     278                 : {
     279             779 :   telemetry_file *p = (telemetry_file *)pFile;
     280                 :   int rc;
     281             779 :   rc = p->pReal->pMethods->xShmMap(p->pReal, iRegion, szRegion, isWrite, pp);
     282             779 :   return rc;
     283                 : }
     284                 : 
     285                 : void
     286          121778 : xShmBarrier(sqlite3_file *pFile){
     287          121778 :   telemetry_file *p = (telemetry_file *)pFile;
     288          121778 :   p->pReal->pMethods->xShmBarrier(p->pReal);
     289          121778 : }
     290                 : 
     291                 : int
     292             426 : xShmUnmap(sqlite3_file *pFile, int delFlag){
     293             426 :   telemetry_file *p = (telemetry_file *)pFile;
     294                 :   int rc;
     295             426 :   rc = p->pReal->pMethods->xShmUnmap(p->pReal, delFlag);
     296             426 :   return rc;
     297                 : }
     298                 :  
     299                 : int
     300           11044 : xOpen(sqlite3_vfs* vfs, const char *zName, sqlite3_file* pFile,
     301                 :           int flags, int *pOutFlags)
     302                 : {
     303           22088 :   IOThreadAutoTimer ioTimer(Telemetry::MOZ_SQLITE_OPEN_MS);
     304           22088 :   Telemetry::AutoTimer<Telemetry::MOZ_SQLITE_OPEN_MS> timer;
     305           11044 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     306                 :   int rc;
     307           11044 :   telemetry_file *p = (telemetry_file *)pFile;
     308           11044 :   Histograms *h = NULL;
     309                 :   // check if the filename is one we are probing for
     310           46702 :   for(size_t i = 0;i < sizeof(gHistograms)/sizeof(gHistograms[0]);i++) {
     311           46702 :     h = &gHistograms[i];
     312                 :     // last probe is the fallback probe
     313           46702 :     if (!h->name)
     314            7970 :       break;
     315           38732 :     if (!zName)
     316            1644 :       continue;
     317           37088 :     const char *match = strstr(zName, h->name);
     318           37088 :     if (!match)
     319           34010 :       continue;
     320            3078 :     char c = match[strlen(h->name)];
     321                 :     // include -wal/-journal too
     322            3078 :     if (!c || c == '-')
     323            3074 :       break;
     324                 :   }
     325           11044 :   p->histograms = h;
     326           11044 :   rc = orig_vfs->xOpen(orig_vfs, zName, p->pReal, flags, pOutFlags);
     327           11044 :   if( rc != SQLITE_OK )
     328               4 :     return rc;
     329           11040 :   if( p->pReal->pMethods ){
     330           11040 :     sqlite3_io_methods *pNew = new sqlite3_io_methods;
     331           11040 :     const sqlite3_io_methods *pSub = p->pReal->pMethods;
     332           11040 :     memset(pNew, 0, sizeof(*pNew));
     333           11040 :     pNew->iVersion = pSub->iVersion;
     334           11040 :     pNew->xClose = xClose;
     335           11040 :     pNew->xRead = xRead;
     336           11040 :     pNew->xWrite = xWrite;
     337           11040 :     pNew->xTruncate = xTruncate;
     338           11040 :     pNew->xSync = xSync;
     339           11040 :     pNew->xFileSize = xFileSize;
     340           11040 :     pNew->xLock = xLock;
     341           11040 :     pNew->xUnlock = xUnlock;
     342           11040 :     pNew->xCheckReservedLock = xCheckReservedLock;
     343           11040 :     pNew->xFileControl = xFileControl;
     344           11040 :     pNew->xSectorSize = xSectorSize;
     345           11040 :     pNew->xDeviceCharacteristics = xDeviceCharacteristics;
     346           11040 :     if( pNew->iVersion>=2 ){
     347            3052 :       pNew->xShmMap = pSub->xShmMap ? xShmMap : 0;
     348            3052 :       pNew->xShmLock = pSub->xShmLock ? xShmLock : 0;
     349            3052 :       pNew->xShmBarrier = pSub->xShmBarrier ? xShmBarrier : 0;
     350            3052 :       pNew->xShmUnmap = pSub->xShmUnmap ? xShmUnmap : 0;
     351                 :     }
     352           11040 :     pFile->pMethods = pNew;
     353                 :   }
     354           11040 :   return rc;
     355                 : }
     356                 : 
     357                 : int
     358           10941 : xDelete(sqlite3_vfs* vfs, const char *zName, int syncDir)
     359                 : {
     360           10941 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     361           10941 :   return orig_vfs->xDelete(orig_vfs, zName, syncDir);
     362                 : }
     363                 : 
     364                 : int
     365           28865 : xAccess(sqlite3_vfs *vfs, const char *zName, int flags, int *pResOut)
     366                 : {
     367           28865 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     368           28865 :   return orig_vfs->xAccess(orig_vfs, zName, flags, pResOut);
     369                 : }
     370                 : 
     371                 : int
     372            4512 : xFullPathname(sqlite3_vfs *vfs, const char *zName, int nOut, char *zOut)
     373                 : {
     374            4512 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     375            4512 :   return orig_vfs->xFullPathname(orig_vfs, zName, nOut, zOut);
     376                 : }
     377                 : 
     378                 : void*
     379               0 : xDlOpen(sqlite3_vfs *vfs, const char *zFilename)
     380                 : {
     381               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     382               0 :   return orig_vfs->xDlOpen(orig_vfs, zFilename);
     383                 : }
     384                 : 
     385                 : void
     386               0 : xDlError(sqlite3_vfs *vfs, int nByte, char *zErrMsg)
     387                 : {
     388               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     389               0 :   orig_vfs->xDlError(orig_vfs, nByte, zErrMsg);
     390               0 : }
     391                 : 
     392                 : void 
     393               0 : (*xDlSym(sqlite3_vfs *vfs, void *pHdle, const char *zSym))(void){
     394               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     395               0 :   return orig_vfs->xDlSym(orig_vfs, pHdle, zSym);
     396                 : }
     397                 : 
     398                 : void
     399               0 : xDlClose(sqlite3_vfs *vfs, void *pHandle)
     400                 : {
     401               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     402               0 :   orig_vfs->xDlClose(orig_vfs, pHandle);
     403               0 : }
     404                 : 
     405                 : int
     406             689 : xRandomness(sqlite3_vfs *vfs, int nByte, char *zOut)
     407                 : {
     408             689 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     409             689 :   return orig_vfs->xRandomness(orig_vfs, nByte, zOut);
     410                 : }
     411                 : 
     412                 : int
     413               0 : xSleep(sqlite3_vfs *vfs, int microseconds)
     414                 : {
     415               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     416               0 :   return orig_vfs->xSleep(orig_vfs, microseconds);
     417                 : }
     418                 : 
     419                 : int
     420               0 : xCurrentTime(sqlite3_vfs *vfs, double *prNow)
     421                 : {
     422               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     423               0 :   return orig_vfs->xCurrentTime(orig_vfs, prNow);
     424                 : }
     425                 : 
     426                 : int
     427               0 : xGetLastError(sqlite3_vfs *vfs, int nBuf, char *zBuf)
     428                 : {
     429               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     430               0 :   return orig_vfs->xGetLastError(orig_vfs, nBuf, zBuf);
     431                 : }
     432                 : 
     433                 : int
     434           10655 : xCurrentTimeInt64(sqlite3_vfs *vfs, sqlite3_int64 *piNow)
     435                 : {
     436           10655 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     437           10655 :   return orig_vfs->xCurrentTimeInt64(orig_vfs, piNow);
     438                 : }
     439                 : 
     440                 : static
     441                 : int
     442               0 : xSetSystemCall(sqlite3_vfs *vfs, const char *zName, sqlite3_syscall_ptr pFunc)
     443                 : {
     444               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     445               0 :   return orig_vfs->xSetSystemCall(orig_vfs, zName, pFunc);
     446                 : }
     447                 : 
     448                 : static
     449                 : sqlite3_syscall_ptr
     450               0 : xGetSystemCall(sqlite3_vfs *vfs, const char *zName)
     451                 : {
     452               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     453               0 :   return orig_vfs->xGetSystemCall(orig_vfs, zName);
     454                 : }
     455                 : 
     456                 : static
     457                 : const char *
     458               0 : xNextSystemCall(sqlite3_vfs *vfs, const char *zName)
     459                 : {
     460               0 :   sqlite3_vfs *orig_vfs = static_cast<sqlite3_vfs*>(vfs->pAppData);
     461               0 :   return orig_vfs->xNextSystemCall(orig_vfs, zName);
     462                 : }
     463                 : 
     464                 : }
     465                 : 
     466                 : namespace mozilla {
     467                 : namespace storage {
     468                 : 
     469             803 : sqlite3_vfs* ConstructTelemetryVFS()
     470                 : {
     471                 : #if defined(XP_WIN)
     472                 : #define EXPECTED_VFS "win32"
     473                 : #else
     474                 : #define EXPECTED_VFS "unix"
     475                 : #endif
     476                 : 
     477             803 :   sqlite3_vfs *vfs = sqlite3_vfs_find(NULL);
     478             803 :   const bool expected_vfs = vfs->zName && !strcmp(vfs->zName, EXPECTED_VFS);
     479             803 :   if (!expected_vfs) {
     480               0 :     return NULL;
     481                 :   }
     482                 : 
     483             803 :   sqlite3_vfs *tvfs = new ::sqlite3_vfs;
     484             803 :   memset(tvfs, 0, sizeof(::sqlite3_vfs));
     485             803 :   tvfs->iVersion = 3;
     486                 :   // If the SQLite VFS version is updated, this shim must be updated as well.
     487             803 :   MOZ_ASSERT(vfs->iVersion == tvfs->iVersion);
     488             803 :   tvfs->szOsFile = sizeof(telemetry_file) - sizeof(sqlite3_file) + vfs->szOsFile;
     489             803 :   tvfs->mxPathname = vfs->mxPathname;
     490             803 :   tvfs->zName = "telemetry-vfs";
     491             803 :   tvfs->pAppData = vfs;
     492             803 :   tvfs->xOpen = xOpen;
     493             803 :   tvfs->xDelete = xDelete;
     494             803 :   tvfs->xAccess = xAccess;
     495             803 :   tvfs->xFullPathname = xFullPathname;
     496             803 :   tvfs->xDlOpen = xDlOpen;
     497             803 :   tvfs->xDlError = xDlError;
     498             803 :   tvfs->xDlSym = xDlSym;
     499             803 :   tvfs->xDlClose = xDlClose;
     500             803 :   tvfs->xRandomness = xRandomness;
     501             803 :   tvfs->xSleep = xSleep;
     502             803 :   tvfs->xCurrentTime = xCurrentTime;
     503             803 :   tvfs->xGetLastError = xGetLastError;
     504                 :   // Added in version 2.
     505             803 :   tvfs->xCurrentTimeInt64 = xCurrentTimeInt64;
     506                 :   // Added in version 3.
     507             803 :   tvfs->xSetSystemCall = xSetSystemCall;
     508             803 :   tvfs->xGetSystemCall = xGetSystemCall;
     509             803 :   tvfs->xNextSystemCall = xNextSystemCall;
     510                 : 
     511             803 :   return tvfs;
     512                 : }
     513                 : 
     514                 : }
     515                 : }

Generated by: LCOV version 1.7