Bug 1976779 - rsclientcerts: make each backend responsible for rate-limiting calls to find_objects r=jschanck
Before this patch, `rsclientcerts::manager` would rate-limit calls to
`find_objects` to once every 3 seconds because the underlying operation can be
time-consuming (in particular, on macOS and Windows, if there are many
certificates/keys available). On Android, keys aren't available until the user
selects one, which means that if a call to `find_objects` happened before the
selection prompt was shown (which is what happens) and the user chose one in
less than 3 seconds, the backend wouldn't search again, thus making it seem like
no keys were available, which would cause Firefox to not send a client
certificate. This patch makes each backend implementation responsible for this
rate-limiting, because only they know if it's appropriate to do so (in particular,
on Android, `find_objects` doesn't have the same performance concern as
on macOS and Windows because rather than searching for certificates and
keys, it asks `ClientAuthCertificateManager` for the cached list of certificates
and keys that have already been approved for use by the user).
Differential Revision: https://phabricator.services.mozilla.com/D257065
<!--Copyright (c) 2019 The Khronos Group Inc.Use of this source code is governed by an MIT-style license that can befound in the LICENSE.txt file.--><!DOCTYPE html><html><head><metacharset="utf-8"><title>WebGL2 getBufferSubData validity tests</title><linkrel="stylesheet"href="../../resources/js-test-style.css"/><scriptsrc="../../js/js-test-pre.js"></script><scriptsrc="../../js/webgl-test-utils.js"></script></head><body><divid="description"></div><divid="console"></div><scriptid="vshader"type="x-shader/x-vertex">#version300esinuintin_data;flatoutuintout_data;voidmain(){out_data=in_data;}</script><scriptid="fshader"type="x-shader/x-fragment">#version300esvoidmain(){}</script><script>"use strict";description("Test that getBufferSubData returns valid data in edge cases");varwtu=WebGLTestUtils;vargl=wtu.create3DContext(undefined,undefined,2);constsrcData=newUint8Array([1,2,3,4,5,6,7,8]);constnoData=newUint8Array(8);constsrcBuffer=gl.createBuffer();gl.bindBuffer(gl.COPY_READ_BUFFER,srcBuffer);gl.bufferData(gl.COPY_READ_BUFFER,srcData,gl.STATIC_DRAW);constbadBuffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,badBuffer);gl.bufferData(gl.ARRAY_BUFFER,8,gl.STATIC_DRAW);letreadbackBuffer;functiondeleteReadbackBuffer(){gl.deleteBuffer(readbackBuffer);}functionrecreateReadbackBuffer(){readbackBuffer=gl.createBuffer();gl.bindBuffer(gl.COPY_WRITE_BUFFER,readbackBuffer);gl.bufferData(gl.COPY_WRITE_BUFFER,8,gl.STREAM_READ);}recreateReadbackBuffer();constdest=newUint8Array(8);// Makes a new "resolvable" Promisefunctionresolvable(){letresolve;constpromise=newPromise(res=>{resolve=res;});promise.resolve=resolve;returnpromise;}functionwait(){returnnewPromise(res=>{setTimeout(res,0);});}asyncfunctionfence(){constsync=gl.fenceSync(gl.SYNC_GPU_COMMANDS_COMPLETE,0);gl.flush();letstatus;do{awaitwait();status=gl.clientWaitSync(sync,0,0);}while(status!=gl.ALREADY_SIGNALED&&status!=gl.CONDITION_SATISFIED);gl.deleteSync(sync);}functioncheckGetBufferSubData(err,data){dest.fill(0);wtu.shouldGenerateGLError(gl,err,"gl.getBufferSubData(gl.COPY_WRITE_BUFFER, 0, dest)");if(!err){shouldBeTrue(`areArraysEqual(dest, ${data})`);}}consttfProgram=wtu.setupTransformFeedbackProgram(gl,["vshader","fshader"],["out_data"],gl.SEPARATE_ATTRIBS,["in_data"]);wtu.glErrorShouldBe(gl,gl.NO_ERROR,"linking transform feedback shader should not set an error");shouldBeNonNull("tfProgram");consttf=gl.createTransformFeedback();functioncopyBufferUsingTransformFeedback(src,dst){gl.enableVertexAttribArray(0);gl.bindBuffer(gl.ARRAY_BUFFER,src);gl.vertexAttribIPointer(0,1,gl.UNSIGNED_INT,0,0);gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK,tf);gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER,0,dst);gl.drawBuffers([gl.NONE]);gl.enable(gl.RASTERIZER_DISCARD);gl.beginTransformFeedback(gl.POINTS);// treats the input and output data as two uint32sgl.drawArrays(gl.POINTS,0,2);gl.endTransformFeedback();gl.disable(gl.RASTERIZER_DISCARD);gl.bindBuffer(gl.ARRAY_BUFFER,badBuffer);gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER,0,null);gl.bindTransformFeedback(gl.TRANSFORM_FEEDBACK,null);}(async()=>{debug("");debug("write-read");gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("fence-wait-write-read");awaitfence();gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("write-read-fence-wait");gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);checkGetBufferSubData(gl.NO_ERROR,"srcData");awaitfence();debug("");debug("write-fence-fence-wait-read");gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);fence();// no awaitawaitfence();checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("write-fence-wait-read");gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);awaitfence();checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("write-fence-wait-write-read");gl.copyBufferSubData(gl.ARRAY_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);awaitfence();gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("write-fence-write-wait-read");gl.copyBufferSubData(gl.ARRAY_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);{constp=fence();gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);awaitp;}checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("write-fence-transformfeedback-wait-read");gl.copyBufferSubData(gl.ARRAY_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);{constp=fence();gl.bindBuffer(gl.COPY_WRITE_BUFFER,null);copyBufferUsingTransformFeedback(srcBuffer,readbackBuffer);gl.bindBuffer(gl.COPY_WRITE_BUFFER,readbackBuffer);awaitp;}checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("write-unbind-fence-wait-bind-read");gl.bindBuffer(gl.COPY_WRITE_BUFFER,null);gl.bindBuffer(gl.ARRAY_BUFFER,readbackBuffer);gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.ARRAY_BUFFER,0,0,8);gl.bindBuffer(gl.ARRAY_BUFFER,badBuffer);awaitfence();gl.bindBuffer(gl.COPY_WRITE_BUFFER,readbackBuffer);checkGetBufferSubData(gl.NO_ERROR,"srcData");debug("");debug("write-fence-wait-delete-read");gl.copyBufferSubData(gl.ARRAY_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);awaitfence();deleteReadbackBuffer();checkGetBufferSubData(gl.INVALID_OPERATION,"noData");recreateReadbackBuffer();debug("");debug("write-fence-delete-wait-read");gl.copyBufferSubData(gl.ARRAY_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);{constp=fence();deleteReadbackBuffer();awaitp;}checkGetBufferSubData(gl.INVALID_OPERATION,"noData");recreateReadbackBuffer();debug("");debug("write-fence-delete-wait-read");gl.copyBufferSubData(gl.ARRAY_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);deleteReadbackBuffer();awaitfence();checkGetBufferSubData(gl.INVALID_OPERATION,"noData");recreateReadbackBuffer();// crbug.com/941930{debug("");debug("write-delete-recreate-fence-wait-read");gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);deleteReadbackBuffer();recreateReadbackBuffer();awaitfence();checkGetBufferSubData(gl.NO_ERROR,"noData");debug("");debug("write-delete-fence-wait-read");gl.copyBufferSubData(gl.COPY_READ_BUFFER,gl.COPY_WRITE_BUFFER,0,0,8);{constp=fence();deleteReadbackBuffer();awaitp;}wtu.glErrorShouldBe(gl,gl.NO_ERROR);}finishTest();})();varsuccessfullyParsed=true;</script></body></html>