1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-07-29 08:01:23 +03:00

Add experimental support to pause/unpause an SAHPool OPFS VFS, as discussed in [forum:fe8cdb8431c32455|forum post fe8cdb8431c32455], the intent being enable a page to relinquish, perhaps temporarily, the VFS such that the VFS's storage can be accessed by another page/tab.

FossilOrigin-Name: 1d2683fe9e4be01c3137e750900f54d287e7d96185e66924d24b50f4647e7ef1
This commit is contained in:
stephan
2025-01-29 11:08:11 +00:00
parent 36279c256b
commit 8883deb30e
4 changed files with 89 additions and 11 deletions

View File

@ -832,12 +832,18 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
Removes this object's sqlite3_vfs registration and shuts down
this object, releasing all handles, mappings, and whatnot,
including deleting its data directory. There is currently no
way to "revive" the object and reaquire its resources.
way to "revive" the object and reaquire its
resources. Similarly, there is no recovery strategy if removal
of any given SAH fails, so such errors are ignored by this
function.
This function is intended primarily for testing.
Resolves to true if it did its job, false if the
VFS has already been shut down.
@see pauseVfs()
@see unpauseVfs()
*/
async removeVfs(){
if(!this.#cVfs.pointer || !this.#dhOpaque) return false;
@ -860,6 +866,65 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
}
/**
"Pauses" this VFS by unregistering it from SQLite and
relinquishing all open SAHs, leaving the associated files
intact. If this object is already paused, this is a
no-op. Returns this object.
This function throws if any database handles are active, as the
alternative would be to invoke Undefined Behavior by closing
that file handle out from under the database. Similarly,
automatically closing any database handles opened by this VFS
would invoke Undefined Behavior in downstream code which is
holding those pointers.
@see isPaused()
@see unpauseVfs()
*/
pauseVfs(){
if(this.#mapS3FileToOFile_.size>0){
toss("Cannot pause a VFS which has an opened database.")
}
if(this.#mapSAHToName.size>0){
capi.sqlite3_vfs_unregister(this.vfsName);
this.releaseAccessHandles();
}
return this;
}
/**
Returns true if this pool is currently paused else false.
@see pauseVfs()
@see unpauseVfs()
*/
isPaused(){
return 0===this.#mapSAHToName.size;
}
/**
"Unpauses" this VFS, reacquiring all SAH's and (if successful)
re-registering it with SQLite. This is a no-op if the VFS is
not currently paused.
The returned Promise resolves to this function's argument, and
is intended solely for use by the OpfsSAHPoolUtil helper class.
@see isPaused()
@see pauseVfs()
*/
async unpauseVfs(returnValue){
if(0===this.#mapSAHToName.size){
return this.acquireAccessHandles(false).
then(()=>{
capi.sqlite3_vfs_register(this.#cVfs, 0);
return returnValue;
});
}
return returnValue;
}
//! Documented elsewhere in this file.
exportFile(name){
const sah = this.#mapFilenameToSAH.get(name) || toss("File not found:",name);
@ -984,6 +1049,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
async removeVfs(){ return this.#p.removeVfs() }
pauseVfs(){ this.#p.pauseVfs(); return this; }
async unpauseVfs(){ return this.#p.unpauseVfs(this); }
isPaused(){ return this.#p.isPaused() }
}/* class OpfsSAHPoolUtil */;
/**