diff options
author | Jesús <heckyel@hyperbola.info> | 2019-12-30 15:55:13 -0500 |
---|---|---|
committer | Jesús <heckyel@hyperbola.info> | 2019-12-30 15:55:13 -0500 |
commit | 288df6a7bf8b933e2dc499e38f4915fcf974c14b (patch) | |
tree | 77bba994f260c064d3ee7f76c427ddfaa4f91710 /lib/CallbackWrapper.jsm | |
parent | a2c9deaa145b780722e93b3899600f287c8094a4 (diff) | |
download | ematrix-288df6a7bf8b933e2dc499e38f4915fcf974c14b.tar.lz ematrix-288df6a7bf8b933e2dc499e38f4915fcf974c14b.tar.xz ematrix-288df6a7bf8b933e2dc499e38f4915fcf974c14b.zip |
backport
- Flush caches on upgrade
- Properly handle FrameModule's unloading
- Use the new module and remove the old implementation
Diffstat (limited to 'lib/CallbackWrapper.jsm')
-rw-r--r-- | lib/CallbackWrapper.jsm | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/lib/CallbackWrapper.jsm b/lib/CallbackWrapper.jsm new file mode 100644 index 0000000..1d3664e --- /dev/null +++ b/lib/CallbackWrapper.jsm @@ -0,0 +1,92 @@ +/******************************************************************************* + + ηMatrix - a browser extension to black/white list requests. + Copyright (C) 2014-2019 The uMatrix/uBlock Origin authors + Copyright (C) 2019 Alessio Vanni + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see {http://www.gnu.org/licenses/}. + + Home: https://gitlab.com/vannilla/ematrix + uMatrix Home: https://github.com/gorhill/uMatrix +*/ + +'use strict'; + +var EXPORTED_SYMBOLS = ['CallbackWrapper']; + +var junkyard = []; + +var CallbackWrapper = function (messageManager, channelName, + listenerId, requestId) { + // This allows to avoid creating a closure for every single + // message which expects an answer. Having a closure created + // each time a message is processed has been always bothering + // me. Another benefit of the implementation here is to reuse + // the callback proxy object, so less memory churning. + // + // https://developers.google.com/speed/articles/optimizing-javascript + // "Creating a closure is significantly slower then creating + // an inner function without a closure, and much slower than + // reusing a static function" + // + // http://hacksoflife.blogspot.ca/2015/01/the-four-horsemen-of-performance.html + // "the dreaded 'uniformly slow code' case where every + // function takes 1% of CPU and you have to make one hundred + // separate performance optimizations to improve performance + // at all" + // + // http://jsperf.com/closure-no-closure/2 + this.callback = this.proxy.bind(this); // bind once + this.init(messageManager, channelName, listenerId, requestId); +}; + +CallbackWrapper.factory = function (messageManager, channelName, + listenerId, requestId) { + let wrapper = junkyard.pop(); + if (wrapper) { + wrapper.init(messageManager, channelName, listenerId, requestId); + return wrapper; + } + + return new CallbackWrapper(messageManager, channelName, + listenerId, requestId); +}; + +CallbackWrapper.prototype.init = function (messageManager, channelName, + listenerId, requestId) { + this.messageManager = messageManager; + this.channelName = channelName; + this.listenerId = listenerId; + this.requestId = requestId; +}; + +CallbackWrapper.prototype.proxy = function (response) { + let message = JSON.stringify({ + requestId: this.requestId, + channelName: this.channelName, + msg: response !== undefined ? response : null + }); + + if (this.messageManager.sendAsyncMessage) { + this.messageManager.sendAsyncMessage(this.listenerId, message); + } else { + this.messageManager.broadcastAsyncMessage(this.listenerId, message); + } + + // Mark for reuse + this.messageManager = this.channelName = + this.requestId = this.listenerId = null; + + junkyard.push(this); +}; |