开发者

Implementing a lock using GM_getValue GM_setValue

I've got a greasemonkey script that, when it runs, checks to see if an update is available, and prompts the user to download the update if so. This normally works fine, except that if a user opens multiple tabs simultaneously (say, on starting the browser, or using "Open All in Tabs" for a bookmark folder), the greasemonkey script will ping the user in each tab simultaneously, which is a bit of a PITA for a user.

I think the only communication channel I have between the instances of the script is GM_setValue/GM_getValue, which allows the instances access to a key/value store.

What I need to do is come up with a locking scheme (let's call it GM_setLock/GM_releaseLock), so I can do the following:

GM_setLock();
const tried_update开发者_Go百科 = GM_getValue(available_version);
GM_setValue(available_version, true);
GM_releaseLock();

if (!tried_update) { prompt_user() }

Without the locking I could have multiple instances in different tabs all read GM_getValue(available_version) before any of them get to GM_setValue(available_version, true), so the user could be pinged multiple times.

The thing is, I don't know how to implement locking off the top of my head if I only have access to (what I'm willing to pretend are) an atomic read and an atomic write operation (and no atomic write and return previous value). Any ideas?


You can't quite do it with that syntax in Greasemonkey, but something like this should do what you want:

Wrap the upgrade check (or whatever), like so:

function UpgradeCheckFunction ()
{
    //--- Put payload code here.

    alert ("I just ran an an upgrade check?!");
}

.
Then define PerformOnceAcrossTabs(), like so:

function PerformOnceAcrossTabs (sName, oFunction)
{
    var OldValue    = GM_getValue (sName);
    if (OldValue)
    {
        //--- Optionally also do a timestamp check and clear any "locks" that are X hours old.
        return;
    }

    GM_setValue (sName, new Date().toString() );

    //--- run payload function here.
    (oFunction)();

    //--- Clear "Lock".
    GM_deleteValue (sName);
}

.
Then call it like so:

PerformOnceAcrossTabs ("UpgradeCheckLock", UpgradeCheckFunction);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜