Scott Graham | d19529d | 2014-11-03 15:04:31 -0800 | [diff] [blame] | 1 | The WebDatabase implementation in the renderer users a custom vfs to |
| 2 | broker file open and other requests. This modifies the built-in vfs |
| 3 | implementation to let that code share much of the implementation |
| 4 | details. |
| 5 | |
| 6 | diff --git src/os_unix.c src/os_unix.c |
| 7 | index ef04a72..e5e1509 100644 |
| 8 | --- src/os_unix.c |
| 9 | +++ src/os_unix.c |
| 10 | @@ -3496,9 +3496,16 @@ typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); |
| 11 | */ |
| 12 | |
| 13 | /* |
| 14 | +** Initializes a unixFile structure with zeros. |
| 15 | +*/ |
| 16 | +void initUnixFile(sqlite3_file* file) { |
| 17 | + memset(file, 0, sizeof(unixFile)); |
| 18 | +} |
| 19 | + |
| 20 | +/* |
| 21 | ** Initialize the contents of the unixFile structure pointed to by pId. |
| 22 | */ |
| 23 | -static int fillInUnixFile( |
| 24 | +int fillInUnixFile( |
| 25 | sqlite3_vfs *pVfs, /* Pointer to vfs object */ |
| 26 | int h, /* Open file descriptor of file being opened */ |
| 27 | int dirfd, /* Directory file descriptor */ |
| 28 | @@ -3812,6 +3819,73 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ |
| 29 | } |
| 30 | |
| 31 | /* |
| 32 | +** Initializes a unixFile structure with zeros. |
| 33 | +*/ |
| 34 | +void chromium_sqlite3_initialize_unix_sqlite3_file(sqlite3_file* file) { |
| 35 | + memset(file, 0, sizeof(unixFile)); |
| 36 | +} |
| 37 | + |
| 38 | +int chromium_sqlite3_fill_in_unix_sqlite3_file(sqlite3_vfs* vfs, |
| 39 | + int fd, |
| 40 | + int dirfd, |
| 41 | + sqlite3_file* file, |
| 42 | + const char* fileName, |
| 43 | + int noLock, |
| 44 | + int isDelete) { |
| 45 | + return fillInUnixFile(vfs, fd, dirfd, file, fileName, noLock, isDelete, 0); |
| 46 | +} |
| 47 | + |
| 48 | +/* |
| 49 | +** Search for an unused file descriptor that was opened on the database file. |
| 50 | +** If a suitable file descriptor if found, then it is stored in *fd; otherwise, |
| 51 | +** *fd is not modified. |
| 52 | +** |
| 53 | +** If a reusable file descriptor is not found, and a new UnixUnusedFd cannot |
| 54 | +** be allocated, SQLITE_NOMEM is returned. Otherwise, SQLITE_OK is returned. |
| 55 | +*/ |
| 56 | +int chromium_sqlite3_get_reusable_file_handle(sqlite3_file* file, |
| 57 | + const char* fileName, |
| 58 | + int flags, |
| 59 | + int* fd) { |
| 60 | + unixFile* unixSQLite3File = (unixFile*)file; |
| 61 | + int fileType = flags & 0xFFFFFF00; |
| 62 | + if (fileType == SQLITE_OPEN_MAIN_DB) { |
| 63 | + UnixUnusedFd *unusedFd = findReusableFd(fileName, flags); |
| 64 | + if (unusedFd) { |
| 65 | + *fd = unusedFd->fd; |
| 66 | + } else { |
| 67 | + unusedFd = sqlite3_malloc(sizeof(*unusedFd)); |
| 68 | + if (!unusedFd) { |
| 69 | + return SQLITE_NOMEM; |
| 70 | + } |
| 71 | + } |
| 72 | + unixSQLite3File->pUnused = unusedFd; |
| 73 | + } |
| 74 | + return SQLITE_OK; |
| 75 | +} |
| 76 | + |
| 77 | +/* |
| 78 | +** Marks 'fd' as the unused file descriptor for 'pFile'. |
| 79 | +*/ |
| 80 | +void chromium_sqlite3_update_reusable_file_handle(sqlite3_file* file, |
| 81 | + int fd, |
| 82 | + int flags) { |
| 83 | + unixFile* unixSQLite3File = (unixFile*)file; |
| 84 | + if (unixSQLite3File->pUnused) { |
| 85 | + unixSQLite3File->pUnused->fd = fd; |
| 86 | + unixSQLite3File->pUnused->flags = flags; |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +/* |
| 91 | +** Destroys pFile's field that keeps track of the unused file descriptor. |
| 92 | +*/ |
| 93 | +void chromium_sqlite3_destroy_reusable_file_handle(sqlite3_file* file) { |
| 94 | + unixFile* unixSQLite3File = (unixFile*)file; |
| 95 | + sqlite3_free(unixSQLite3File->pUnused); |
| 96 | +} |
| 97 | + |
| 98 | +/* |
| 99 | ** Open the file zPath. |
| 100 | ** |
| 101 | ** Previously, the SQLite OS layer used three functions in place of this |
| 102 | @@ -3893,20 +3967,13 @@ static int unixOpen( |
| 103 | || eType==SQLITE_OPEN_TRANSIENT_DB |
| 104 | ); |
| 105 | |
| 106 | - memset(p, 0, sizeof(unixFile)); |
| 107 | + chromium_sqlite3_initialize_unix_sqlite3_file(pFile); |
| 108 | |
| 109 | if( eType==SQLITE_OPEN_MAIN_DB ){ |
| 110 | - UnixUnusedFd *pUnused; |
| 111 | - pUnused = findReusableFd(zName, flags); |
| 112 | - if( pUnused ){ |
| 113 | - fd = pUnused->fd; |
| 114 | - }else{ |
| 115 | - pUnused = sqlite3_malloc(sizeof(*pUnused)); |
| 116 | - if( !pUnused ){ |
| 117 | - return SQLITE_NOMEM; |
| 118 | - } |
| 119 | + rc = chromium_sqlite3_get_reusable_file_handle(pFile, zName, flags, &fd); |
| 120 | + if( rc!=SQLITE_OK ){ |
| 121 | + return rc; |
| 122 | } |
| 123 | - p->pUnused = pUnused; |
| 124 | }else if( !zName ){ |
| 125 | /* If zName is NULL, the upper layer is requesting a temp file. */ |
| 126 | assert(isDelete && !isOpenDirectory); |
| 127 | @@ -3949,10 +4016,7 @@ static int unixOpen( |
| 128 | *pOutFlags = flags; |
| 129 | } |
| 130 | |
| 131 | - if( p->pUnused ){ |
| 132 | - p->pUnused->fd = fd; |
| 133 | - p->pUnused->flags = flags; |
| 134 | - } |
| 135 | + chromium_sqlite3_update_reusable_file_handle(pFile, fd, flags); |
| 136 | |
| 137 | if( isDelete ){ |
| 138 | #if OS_VXWORKS |
| 139 | @@ -4028,7 +4092,7 @@ static int unixOpen( |
| 140 | rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); |
| 141 | open_finished: |
| 142 | if( rc!=SQLITE_OK ){ |
| 143 | - sqlite3_free(p->pUnused); |
| 144 | + chromium_sqlite3_destroy_reusable_file_handle(pFile); |
| 145 | } |
| 146 | return rc; |
| 147 | } |
| 148 | diff --git src/os_win.c src/os_win.c |
| 149 | index bc03a4b..06539d7 100644 |
| 150 | --- src/os_win.c |
| 151 | +++ src/os_win.c |
| 152 | @@ -1890,4 +1890,11 @@ int sqlite3_os_end(void){ |
| 153 | return SQLITE_OK; |
| 154 | } |
| 155 | |
| 156 | +void chromium_sqlite3_initialize_win_sqlite3_file(sqlite3_file* file, HANDLE handle) { |
| 157 | + winFile* winSQLite3File = (winFile*)file; |
| 158 | + memset(file, 0, sizeof(*file)); |
| 159 | + winSQLite3File->pMethod = &winIoMethod; |
| 160 | + winSQLite3File->h = handle; |
| 161 | +} |
| 162 | + |
| 163 | #endif /* SQLITE_OS_WIN */ |