The WebDatabase implementation in the renderer users a custom vfs to broker file open and other requests. This modifies the built-in vfs implementation to let that code share much of the implementation details. diff --git src/os_unix.c src/os_unix.c index ef04a72..e5e1509 100644 --- src/os_unix.c +++ src/os_unix.c @@ -3496,9 +3496,16 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); */ /* +** Initializes a unixFile structure with zeros. +*/ +void initUnixFile(sqlite3_file* file) { + memset(file, 0, sizeof(unixFile)); +} + +/* ** Initialize the contents of the unixFile structure pointed to by pId. */ -static int fillInUnixFile( +int fillInUnixFile( sqlite3_vfs *pVfs, /* Pointer to vfs object */ int h, /* Open file descriptor of file being opened */ int dirfd, /* Directory file descriptor */ @@ -3812,6 +3819,73 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ } /* +** Initializes a unixFile structure with zeros. +*/ +void chromium_sqlite3_initialize_unix_sqlite3_file(sqlite3_file* file) { + memset(file, 0, sizeof(unixFile)); +} + +int chromium_sqlite3_fill_in_unix_sqlite3_file(sqlite3_vfs* vfs, + int fd, + int dirfd, + sqlite3_file* file, + const char* fileName, + int noLock, + int isDelete) { + return fillInUnixFile(vfs, fd, dirfd, file, fileName, noLock, isDelete, 0); +} + +/* +** Search for an unused file descriptor that was opened on the database file. +** If a suitable file descriptor if found, then it is stored in *fd; otherwise, +** *fd is not modified. +** +** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot +** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned. +*/ +int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file, + const char* fileName, + int flags, + int* fd) { + unixFile* unixSQLite3File = (unixFile*)file; + int fileType = flags & 0xFFFFFF00; + if (fileType == SQLITE_OPEN_MAIN_DB) { + UnixUnusedFd *unusedFd = findReusableFd(fileName, flags); + if (unusedFd) { + *fd = unusedFd->fd; + } else { + unusedFd = sqlite3_malloc(sizeof(*unusedFd)); + if (!unusedFd) { + return SQLITE_NOMEM; + } + } + unixSQLite3File->pUnused = unusedFd; + } + return SQLITE_OK; +} + +/* +** Marks 'fd' as the unused file descriptor for 'pFile'. +*/ +void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file, + int fd, + int flags) { + unixFile* unixSQLite3File = (unixFile*)file; + if (unixSQLite3File->pUnused) { + unixSQLite3File->pUnused->fd = fd; + unixSQLite3File->pUnused->flags = flags; + } +} + +/* +** Destroys pFile's field that keeps track of the unused file descriptor. +*/ +void chromium_sqlite3_destroy_reusable_file_handle(sqlite3_file* file) { + unixFile* unixSQLite3File = (unixFile*)file; + sqlite3_free(unixSQLite3File->pUnused); +} + +/* ** Open the file zPath. ** ** Previously, the SQLite OS layer used three functions in place of this @@ -3893,20 +3967,13 @@ static int unixOpen( || eType==SQLITE_OPEN_TRANSIENT_DB ); - memset(p, 0, sizeof(unixFile)); + chromium_sqlite3_initialize_unix_sqlite3_file(pFile); if( eType==SQLITE_OPEN_MAIN_DB ){ - UnixUnusedFd *pUnused; - pUnused = findReusableFd(zName, flags); - if( pUnused ){ - fd = pUnused->fd; - }else{ - pUnused = sqlite3_malloc(sizeof(*pUnused)); - if( !pUnused ){ - return SQLITE_NOMEM; - } + rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd); + if( rc!=SQLITE_OK ){ + return rc; } - p->pUnused = pUnused; }else if( !zName ){ /* If zName is NULL, the upper layer is requesting a temp file. */ assert(isDelete && !isOpenDirectory); @@ -3949,10 +4016,7 @@ static int unixOpen( *pOutFlags = flags; } - if( p->pUnused ){ - p->pUnused->fd = fd; - p->pUnused->flags = flags; - } + chromium_sqlite3_update_reusable_file_handle(pFile, fd, flags); if( isDelete ){ #if OS_VXWORKS @@ -4028,7 +4092,7 @@ static int unixOpen( rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); open_finished: if( rc!=SQLITE_OK ){ - sqlite3_free(p->pUnused); + chromium_sqlite3_destroy_reusable_file_handle(pFile); } return rc; } diff --git src/os_win.c src/os_win.c index bc03a4b..06539d7 100644 --- src/os_win.c +++ src/os_win.c @@ -1890,4 +1890,11 @@ int sqlite3_os_end(void){ return SQLITE_OK; } +void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle) { + winFile* winSQLite3File = (winFile*)file; + memset(file, 0, sizeof(*file)); + winSQLite3File->pMethod = &winIoMethod; + winSQLite3File->h = handle; +} + #endif /* SQLITE_OS_WIN */