From: stephan Date: Thu, 5 Mar 2026 11:51:27 +0000 (+0000) Subject: Strip the opfs-wl "back to formula", removing the current false starts so that this... X-Git-Tag: major-release~100^2~17 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=14b5eadefe0e8285f097fa948bfb08ae0dfa9f00;p=thirdparty%2Fsqlite.git Strip the opfs-wl "back to formula", removing the current false starts so that this can be tried again without tripping over any cruft. The current impl is subject, with no obvious way out of it, to starvation in the async proxy. FossilOrigin-Name: d022f1f5e74dedae044801330eb099022498f359f408e69b3574885641b312f5 --- diff --git a/ext/wasm/api/opfs-common-shared.c-pp.js b/ext/wasm/api/opfs-common-shared.c-pp.js index 43a1b05cdc..c709e0d15b 100644 --- a/ext/wasm/api/opfs-common-shared.c-pp.js +++ b/ext/wasm/api/opfs-common-shared.c-pp.js @@ -444,7 +444,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ - Set up any references they may need to state returned by the previous step. - - Call opfvs.doTheThing() + - Call opfvs.bindVfs() */ opfsUtil.initOptions = function(options, callee){ const urlParams = new URL(globalThis.location.href).searchParams; @@ -485,10 +485,10 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ capi.sqlite3_vfs instance. After setting up any local state needed, the caller must - call theVfs.doTheThing(X,Y), where X is an object containing + call theVfs.bindVfs(X,Y), where X is an object containing the sqlite3_io_methods to override and Y is a callback which gets triggered if init succeeds, before the final Promise - decides whether or not to reject. The result of doTheThing() + decides whether or not to reject. The result of bindVfs() must be returned from their main installation function. This object must, when it's passed to the async part, contain @@ -505,7 +505,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ sqlite3.config.log ]; const logImpl = (level,...args)=>{ - if(options.verbose>level) loggers[level]("OPFS syncer:",...args); + if(state.verbose>level) loggers[level]("OPFS syncer:",...args); }; const log = (...args)=>logImpl(2, ...args), warn = (...args)=>logImpl(1, ...args), @@ -670,7 +670,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ state.opIds.xUnlock = i++; state.opIds.xWrite = i++; state.opIds.mkdir = i++; - state.opIds.lockControl = i++ /* opfs-wl signals the intent to lock here */; /** Internal signals which are used only during development and testing via the dev console. */ state.opIds['opfs-async-metrics'] = i++; @@ -679,13 +678,6 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ semantics. Though we could hypothetically use the xSleep slot for that, doing so might lead to undesired side effects. */ state.opIds.retry = i++; - - state.lock = util.nu({ - /* Slots for submitting the lock type and receiving its - acknowledgement. Only used by "opfs-wl". */ - type: i++ /* SQLITE_LOCK_xyz value */, - atomicsHandshake: i++ /* 0=pending, 1=release, 2=granted */ - }); state.sabOP = new SharedArrayBuffer( i * 4/* ==sizeof int32, noting that Atomics.wait() and friends can only function on Int32Array views of an SAB. */); @@ -1080,7 +1072,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ where opfsVfs is the sqlite3_vfs object which was set up by opfsUtil.createVfsState(). */ - opfsVfs.doTheThing = function(ioMethods, callback){ + opfsVfs.bindVfs = function(ioMethods, callback){ Object.assign(opfsVfs.ioSyncWrappers, ioMethods); const thePromise = new Promise(function(promiseResolve_, promiseReject_){ let promiseWasRejected = undefined; @@ -1101,13 +1093,21 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ options.proxyUri += '?vfs='+vfsName; const W = opfsVfs.worker = //#if target:es6-bundler-friendly - new Worker(new URL("sqlite3-opfs-async-proxy.js?vfs=opfs", import.meta.url)); + (()=>{ + /* _Sigh_... */ + switch(vfsName){ + case 'opfs': + return new Worker(new URL("sqlite3-opfs-async-proxy.js?vfs=opfs", import.meta.url)); + case 'opfs-wl': + return new Worker(new URL("sqlite3-opfs-async-proxy.js?vfs=opfs-wl", import.meta.url)); + } + })(); //#elif target:es6-module new Worker(new URL(options.proxyUri, import.meta.url)); //#else new Worker(options.proxyUri); //#endif - setTimeout(()=>{ + let zombieTimer = setTimeout(()=>{ /* At attempt to work around a browser-specific quirk in which the Worker load is failing in such a way that we neither resolve nor reject it. This workaround gives that resolve/reject @@ -1211,7 +1211,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*sanityCheck()*/; W.onmessage = function({data}){ - //log("Worker.onmessage:",data); + //sqlite3.config.warn(vfsName,"Worker.onmessage:",data); switch(data.type){ case 'opfs-unavailable': /* Async proxy has determined that OPFS is unavailable. There's @@ -1232,6 +1232,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ if(true===promiseWasRejected){ break /* promise was already rejected via timer */; } + clearTimeout(zombieTimer); + zombieTimer = null; try { sqlite3.vfs.installVfs({ io: {struct: opfsVfs.ioMethods, methods: opfsVfs.ioSyncWrappers}, @@ -1278,7 +1280,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ }/*W.onmessage()*/; })/*thePromise*/; return thePromise; - }/*doTheThing()*/; + }/*bindVfs()*/; return state; }/*createVfsState()*/; diff --git a/ext/wasm/api/sqlite3-opfs-async-proxy.c-pp.js b/ext/wasm/api/sqlite3-opfs-async-proxy.c-pp.js index 8338b96c05..0db9a99141 100644 --- a/ext/wasm/api/sqlite3-opfs-async-proxy.c-pp.js +++ b/ext/wasm/api/sqlite3-opfs-async-proxy.c-pp.js @@ -326,7 +326,7 @@ const installAsyncProxy = function(){ } log("Got",opName+"() sync handle for",fh.filenameAbs, 'in',performance.now() - t,'ms'); - if(!isWebLocker && !fh.xLock){ + if(!fh.xLock){ __implicitLocks.add(fh.fid); log("Acquired implicit lock for",opName+"()",fh.fid,fh.filenameAbs); } @@ -611,74 +611,6 @@ const installAsyncProxy = function(){ } }/*vfsAsyncImpls*/; - /** - Starts a new WebLock request. - */ - const handleLockRequest = async function(){ - const view = state.sabOPView; -//#if not nope - const args = state.s11n.deserialize(true) - || toss("Expecting a filename argument from the proxy xLock()"); - const slock = state.lock; - const lockType = Atomics.load(view, slock.type); - warn("handleLockRequest()", args, lockType, JSON.stringify(slock)); - //hangs warn(JSON.stringify((await navigator.locks.query()).held)); - //warn("Navigator locks:", !!navigator.locks); - await navigator.locks.request('sqlite3-vfs-opfs:'+args[0], { - mode: 'exclusive' /*(lockType===state.sq3Codes.SQLITE_LOCK_EXCLUSIVE) - ? 'exclusive' : 'shared'*/ - }, async (wl)=>{ - warn("handleLockRequest() starting lock", args, lockType); - /** - A. Tell the C-side we have the browser lock. We use the same - handshake slot, but a specific 'Granted' value. - */ - Atomics.store(view, slock.atomicsHandshake, 2); - Atomics.notify(view, slock.atomicsHandshake); - /** - B. Sit here and keep the lock room occupied until the - Receptionist receives 'unlockControl'. - */ - while( 1!==Atomics.load(view, slock.atomicsHandshake) ){ - Atomics.wait(view, slock.atomicsHandshake, 2); - } - /* C. Reset the handshake slot. */ - Atomics.store(view, slock.atomicsHandshake, 0); - Atomics.notify(view, lock.atomicsHandshake); - }); - warn("handleLockRequest() ending", args, lockType); - //setTimeout(waitLoop, 0); -//#else - warn("handleLockRequest()", ...arguments); - const [filename] = state.s11n.deserialize(true); - const lockType = Atomics.load(view, state.lock.type); - warn("handleLockRequest()", filename, lockType); - // Use 'exclusive' to ensure we aren't getting a weak shared lock - navigator.locks.request(filename, { mode: 'exclusive' }, (lock) => { - warn("handleLockRequest() inside the lock"); - // VIOLENT DEBUGGING: Use globalThis.postMessage to bypass Atomics - globalThis.postMessage({type: 'debug', msg: 'CALLBACK ENTERED'}); - - // 1. Signal C-side: "I have it" - Atomics.store(view, state.lock.atomicsHandshake, 2); - Atomics.notify(view, state.lock.atomicsHandshake); - - // 2. The Guard: This loop must not be async. - // It must stay synchronous to keep the callback alive. - while(Atomics.load(view, state.lock.atomicsHandshake) !== 1){ - Atomics.wait(view, state.lock.atomicsHandshake, 2, 100); - } - - // 3. Departure - Atomics.store(view, state.lock.atomicsHandshake, 0); - globalThis.postMessage({type: 'debug', msg: 'CALLBACK EXITING'}); - return new Promise(()=>{/* never resolve to keep lock held until Departure */}); - }).catch(e => { - globalThis.postMessage({type: 'debug', msg: 'LOCK ERROR: ' + e.message}); - }); -//#endif - }; - const waitLoop = async function f(){ if( !f.inited ){ f.inited = true; @@ -717,12 +649,6 @@ const installAsyncProxy = function(){ continue; } const opId = Atomics.exchange(state.sabOPView, opIds.whichOp, 0); - warn("opId =",opId, opIds); - if( opId===opIds.lockControl ){ - handleLockRequest(); - setTimeout(f, 50); - return; - } const hnd = f.opHandlers[opId] ?? toss("No waitLoop handler for whichOp #",opId); const args = state.s11n.deserialize( true /* clear s11n to keep the caller from confusing this with @@ -741,6 +667,7 @@ const installAsyncProxy = function(){ navigator.storage.getDirectory().then(function(d){ state.rootDir = d; globalThis.onmessage = function({data}){ + warn(globalThis.location.href,"onmessage()",data); switch(data.type){ case 'opfs-async-init':{ /* Receive shared state from synchronous partner */ @@ -767,7 +694,7 @@ const installAsyncProxy = function(){ flagAsyncShutdown = false; waitLoop(); } - break; + break; } }; wPost('opfs-async-loaded'); diff --git a/ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js index b2d25b85e4..8119b32469 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js @@ -59,6 +59,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ const installOpfsWlVfs = async function callee(options){ options = opfsUtil.initOptions(options, callee); if( !options ) return sqlite3; + options.verbose = 2; const capi = sqlite3.capi, debug = (...args)=>sqlite3.config.warn("opfs-wl:",...args), state = opfsUtil.createVfsState('opfs-wl', options), @@ -67,85 +68,55 @@ const installOpfsWlVfs = async function callee(options){ mTimeStart = opfsVfs.mTimeStart, mTimeEnd = opfsVfs.mTimeEnd, __openFiles = opfsVfs.__openFiles; - debug("state",JSON.stringify(state,false,' ')); + //debug("state",JSON.stringify(state,false,' ')); /* At this point, createVfsState() has populated state and opfsVfs with any code common to both the "opfs" and "opfs-wl" VFSes. Now comes the VFS-dependent work... */ - return opfsVfs.doTheThing(util.nu({ - xLock: function(pFile, lockType){ + return opfsVfs.bindVfs(util.nu({ + xLock: function(pFile,lockType){ mTimeStart('xLock'); ++metrics.xLock.count; const f = __openFiles[pFile]; - debug("xLock()",f,lockType); let rc = 0; - /* See notes in sqlite3-vfs-opfs.c-pp.js. */ + /* All OPFS locks are exclusive locks. If xLock() has + previously succeeded, do nothing except record the lock + type. If no lock is active, have the async counterpart + lock the file. */ if( f.lockType ) { f.lockType = lockType; }else{ - try{ - const view = state.sabOPView; - /* We need to pass pFile's name to the async proxy so that - it can create the WebLock name. */ - state.s11n.serialize(f.filename) - Atomics.store(view, state.lock.atomicsHandshake, 0); - Atomics.store(view, state.lock.type, lockType); - Atomics.store(view, state.opIds.whichOp, state.opIds.lockControl); - Atomics.notify(state.sabOPView, state.opIds.whichOp) - debug("xLock waiting..."); -//#if not nope - while( 2 !== Atomics.load(view, state.lock.atomicsHandshake) ){ - Atomics.wait(view, state.lock.atomicsHandshake, 0); - } -//#else - while('not-equal'!==Atomics.wait(view, state.lock.atomicsHandshake, 0)){ - /* Loop is a workaround for environment-specific quirks. See - notes in similar loops. */ - debug("xLock still waiting..."); - } -//#endif - debug("xLock done waiting"); - f.lockType = lockType; - }catch(e){ - sqlite3.config.error("xLock(",arguments,") failed", e, f); - rc = capi.SQLITE_IOERR_LOCK; - } + rc = opRun('xLock', pFile, lockType); + if( 0===rc ) f.lockType = lockType; } mTimeEnd(); return rc; }, xUnlock: function(pFile,lockType){ - debug("xUnlock()",f,lockType); mTimeStart('xUnlock'); ++metrics.xUnlock.count; const f = __openFiles[pFile]; let rc = 0; - if( lockType < f.lockType ){ - try{ - const view = state.sabOPView; - Atomics.store(view, state.lock.atomicsHandshake, 1); - Atomics.notify(view, state.lock.atomicsHandshake); - Atomics.wait(view, state.lock.atomicsHandshake, 1); - }catch(e){ - sqlite3.config.error("xUnlock(",pFile,lockType,") failed",e, f); - rc = capi.SQLITE_IOERR_LOCK; - } + if( capi.SQLITE_LOCK_NONE === lockType + && f.lockType ){ + rc = opRun('xUnlock', pFile, lockType); } if( 0===rc ) f.lockType = lockType; mTimeEnd(); return rc; } }), function(sqlite3, vfs){ + //debug("registered VFS"); if(sqlite3.oo1){ const OpfsWlDb = function(...args){ const opt = sqlite3.oo1.DB.dbCtorHelper.normalizeArgs(...args); - opt.vfs = opfsVfs.$zName; + opt.vfs = vfs.$zName; sqlite3.oo1.DB.dbCtorHelper.call(this, opt); }; OpfsWlDb.prototype = Object.create(sqlite3.oo1.DB.prototype); sqlite3.oo1.OpfsWlDb = OpfsWlDb; OpfsWlDb.importDb = opfsUtil.importDb; }/*extend sqlite3.oo1*/ - })/*doTheThing()*/; + })/*bindVfs()*/; }/*installOpfsWlVfs()*/; installOpfsWlVfs.defaultProxyUri = "sqlite3-opfs-async-proxy.js"; globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{ diff --git a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js index 6fe317ec8d..89b52c836d 100644 --- a/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js +++ b/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js @@ -95,7 +95,7 @@ const installOpfsVfs = async function callee(options){ /* At this point, createVfsState() has populated state and opfsVfs with any code common to both the "opfs" and "opfs-wl" VFSes. Now comes the VFS-dependent work... */ - return opfsVfs.doTheThing(util.nu({ + return opfsVfs.bindVfs(util.nu({ xLock: function(pFile,lockType){ mTimeStart('xLock'); ++metrics.xLock.count; @@ -147,7 +147,7 @@ const installOpfsVfs = async function callee(options){ } ); }/*extend sqlite3.oo1*/ - })/*doTheThing()*/; + })/*bindVfs()*/; }/*installOpfsVfs()*/; installOpfsVfs.defaultProxyUri = "sqlite3-opfs-async-proxy.js"; globalThis.sqlite3ApiBootstrap.initializersAsync.push(async (sqlite3)=>{ diff --git a/ext/wasm/tests/opfs/concurrency/test.js b/ext/wasm/tests/opfs/concurrency/test.js index 9208ff47fc..18c01a5b7e 100644 --- a/ext/wasm/tests/opfs/concurrency/test.js +++ b/ext/wasm/tests/opfs/concurrency/test.js @@ -121,14 +121,15 @@ const li = []; for(const k of [ 'interval', 'iterations', 'unlock-asap', - 'verbose', 'vfs', 'workers' + 'opfsVerbose', 'vfs', 'workers' ]){ if( obj.hasOwnProperty(k) ) li.push(k+'='+obj[k]); } return li.join('&'); }; for(const opt of [ - {interval: 500, workers: 2, iterations: 30, vfs: 'opfs-wl', verbose: 2}, + {interval: 500, workers: 1, iterations: 5, vfs: 'opfs-wl', opfsVerbose: 2}, + {interval: 500, workers: 2, iterations: 5, vfs: 'opfs-wl', opfsVerbose: 2}, {interval: 1000, workers: 5, iterations: 30}, {interval: 500, workers: 5, iterations: 30}, {interval: 250, workers: 3, iterations: 30}, diff --git a/ext/wasm/tests/opfs/concurrency/worker.js b/ext/wasm/tests/opfs/concurrency/worker.js index b4cb5a30a4..77e320e9af 100644 --- a/ext/wasm/tests/opfs/concurrency/worker.js +++ b/ext/wasm/tests/opfs/concurrency/worker.js @@ -1,6 +1,7 @@ importScripts( (new URL(globalThis.location.href).searchParams).get('sqlite3.dir') + '/sqlite3.js' ); +//const sqlite3InitModule = (await import("../../../jswasm/sqlite3.mjs", )).default; globalThis.sqlite3InitModule.__isUnderTest = true; globalThis.sqlite3InitModule().then(async function(sqlite3){ const urlArgs = new URL(globalThis.location.href).searchParams; @@ -85,7 +86,7 @@ globalThis.sqlite3InitModule().then(async function(sqlite3){ }catch(e){ interval.error = e; } - stdout("doWork()",prefix,"error ",interval.error); + //stdout("doWork()",prefix,"error ",interval.error); }; setTimeout(async function timer(){ await doWork(); diff --git a/manifest b/manifest index a92a7a8886..c3f7604220 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sopfs-wl\slock\shang\shas\sbeen\straced\sto\sstarvation\sbetween\sthe\sWebLock\sand\sthe\stight\swait-on-VFS-calls\sAtomics.wait()\sloop.\sThis\scan\sreportedly\sbe\sresolved\swith\sanother\slevel\sof\sindirection\sin\swhich\sthe\sWebLock\stakes\sover\sthe\swait-on-VFS-calls\spart\suntil\sit's\sunlocked,\sreturning\sto\sthe\sglobal\sloop\swhen\sit's\sdone.\sThat\sexceeds\sthis\smorning's\sambitions\sbut\sis\snext\sto\stry\sout. -D 2026-03-05T06:30:57.097 +C Strip\sthe\sopfs-wl\s"back\sto\sformula",\sremoving\sthe\scurrent\sfalse\sstarts\sso\sthat\sthis\scan\sbe\stried\sagain\swithout\stripping\sover\sany\scruft.\sThe\scurrent\simpl\sis\ssubject,\swith\sno\sobvious\sway\sout\sof\sit,\sto\sstarvation\sin\sthe\sasync\sproxy. +D 2026-03-05T11:51:27.592 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea @@ -585,7 +585,7 @@ F ext/wasm/api/README.md a905d5c6bfc3e2df875bd391d6d6b7b48d41b43bdee02ad115b4724 F ext/wasm/api/extern-post-js.c-pp.js d9f42ecbedc784c0d086bc37800e52946a14f7a21600b291daa3f963c314f930 F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/opfs-common-inline.c-pp.js 5be8d6d91963849e218221b48206ae55612630bb2cd7f30b1b6fcf7a9e374b76 -F ext/wasm/api/opfs-common-shared.c-pp.js 404aa8fd676791f0ce71e5c48f5f19e13e7b8e967a9af6a76927d524bbb46158 +F ext/wasm/api/opfs-common-shared.c-pp.js d54054b9b39ceb088692153f400d2d9a147e4a45d039c8a027575bdc7a02ac68 F ext/wasm/api/post-js-footer.js a50c1a2c4d008aede7b2aa1f18891a7ee71437c2f415b8aeb3db237ddce2935b F ext/wasm/api/post-js-header.js f35d2dcf1ab7f22a93d565f8e0b622a2934fc4e743edf3b708e4dd8140eeff55 F ext/wasm/api/pre-js.c-pp.js 9234ea680a2f6a2a177e8dcd934bdc5811a9f8409165433a252b87f4c07bba6f @@ -594,12 +594,12 @@ F ext/wasm/api/sqlite3-api-oo1.c-pp.js 45454631265d9ce82685f1a64e1650ee19c8e121c F ext/wasm/api/sqlite3-api-prologue.js 98fedc159c9239b226d19567d7172300dee5ffce176e5fa2f62dd1f17d088385 F ext/wasm/api/sqlite3-api-worker1.c-pp.js 1041dd645e8e821c082b628cd8d9acf70c667430f9d45167569633ffc7567938 F ext/wasm/api/sqlite3-license-version-header.js 98d90255a12d02214db634e041c8e7f2f133d9361a8ebf000ba9c9af4c6761cc -F ext/wasm/api/sqlite3-opfs-async-proxy.c-pp.js 82339eb043af53638b127a4649685da62b6fa33426d2013520eb6aeb114ede46 +F ext/wasm/api/sqlite3-opfs-async-proxy.c-pp.js 81d24de69b43d3c0940dbaa9bc82de193b720107e5a2ddfd31bc50640dd4903d F ext/wasm/api/sqlite3-vfs-helper.c-pp.js 3f828cc66758acb40e9c5b4dcfd87fd478a14c8fb7f0630264e6c7fa0e57515d F ext/wasm/api/sqlite3-vfs-kvvfs.c-pp.js a61dd2b4d919d2d5d83c5c7e49b89ecbff2525ff81419f6a6dbaecaf3819c490 F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 1575ea6bbcf2da1e6df6892c17521a0c1c1c199a672e9090176ea0b88de48bd9 -F ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js 88add6362468df4ecbbd00878c7a83cd81e555c677103ead51c34bd2be1a3963 -F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 50a955ef393722d498177ad09c9e2d05bbe8dccae4c40c501482a860ca30017d +F ext/wasm/api/sqlite3-vfs-opfs-wl.c-pp.js 8233c5f9021b0213134e2adbaf6036b8f1dffd4747083a4087c1c19ae107f962 +F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js f3b7296480984bcc6050fe9724a8b215c405977dd69daea7145ece25751e4b33 F ext/wasm/api/sqlite3-vtab-helper.c-pp.js 366596d8ff73d4cefb938bbe95bc839d503c3fab6c8335ce4bf52f0d8a7dee81 F ext/wasm/api/sqlite3-wasm.c 45bb20e19b245136711f9b78584371233975811b6560c29ed9b650e225417e29 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js aa9715f661fb700459a5a6cb1c32a4d6a770723b47aa9ac0e16c2cf87d622a66 @@ -646,8 +646,8 @@ F ext/wasm/tester1-worker.c-pp.html d0032241d0b24d996cf1c4dd0dde364189693af9b5c9 F ext/wasm/tester1.c-pp.html 52d88fe2c6f21a046030a36410b4839b632f4424028197a45a3d5669ea724ddb F ext/wasm/tester1.c-pp.js 6b946cd6d4da130dbae4a401057716d27117ca02cad2ea8c29ae9c46c675d618 F ext/wasm/tests/opfs/concurrency/index.html 657578a6e9ce1e9b8be951549ed93a6a471f4520a99e5b545928668f4285fb5e -F ext/wasm/tests/opfs/concurrency/test.js b80e17488a8e4d5500deaf68f73a7298d7d351f74bb952691a4e7b6c02a5643b -F ext/wasm/tests/opfs/concurrency/worker.js de0be3be41da20e6639cdea10467fb5d9cdf540e711b403728a08d99bbb82ee6 +F ext/wasm/tests/opfs/concurrency/test.js 74f4ef9a827d081e6bb0ffb1d124bb54015dab8f7ae47abd5b5f26d71633331a +F ext/wasm/tests/opfs/concurrency/worker.js 3425e6dad755a1c69a6efc63a47a3ade4e7f0a9a138994ba37f996571fb46288 F ext/wasm/tests/opfs/sahpool/digest-worker.js b0ab6218588f1f0a6d15a363b493ceaf29bfb87804d9e0165915a9996377cf79 F ext/wasm/tests/opfs/sahpool/digest.html 206d08a34dc8bd570b2581d3d9ab3ecad3201b516a598dd096dcf3cf8cd81df8 F ext/wasm/tests/opfs/sahpool/index.html be736567fd92d3ecb9754c145755037cbbd2bca01385e2732294b53f4c842328 @@ -2191,8 +2191,8 @@ F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee F tool/warnings.sh d924598cf2f55a4ecbc2aeb055c10bd5f48114793e7ba25f9585435da29e7e98 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F tool/winmain.c 00c8fb88e365c9017db14c73d3c78af62194d9644feaf60e220ab0f411f3604c -P 62fc8b35aeec75f5648b3daa24162c638999d447aa874bdfcbac1431c5c97b6f -R 4e4429a4d6f21ed4af3f33058413d5c8 +P 113bd910e12fea17f9f4a0a3baf706f15627c08cfa6b47a960a83eee761ef4dd +R 4ea42d5818e8a1a0aa1e2fe935a1308b U stephan -Z 5eeca3e1560bb544ee40d011df9232c0 +Z 71a80b89b42b2027ae01cf15e67091dc # Remove this line to create a well-formed Fossil manifest. diff --git a/manifest.uuid b/manifest.uuid index c36b9ce9ac..e12e126346 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -113bd910e12fea17f9f4a0a3baf706f15627c08cfa6b47a960a83eee761ef4dd +d022f1f5e74dedae044801330eb099022498f359f408e69b3574885641b312f5