Требуется пустить в бекграунде новый поток. Сделал как описано здесь: https://developer.mozilla.org/en/Code_snippets/Threads
Все работает, но при первой попытке обратиться из потока к DOM, браузер сразу вешается. Что собственно логично, и об этом на этой странице написано.
Копаю дальше, нахожу такую статью: http://forums.mozillazine.org/viewtopic.php?p=2431475&sid=7ed44ffe653b76ee4738f37eb6b07ad0
т.е. можно синхронизировать поток в основным через nsIProxyObjectManager. но тут как я понимаю описан старый механизм, "@mozilla.org/event-queue-service;1" уже нету, "@mozilla.org/thread;1" тоже.
Кто подскажет аналог для современного браузера?

Вот, например:

Выделить код

Код:

var b = document. getElementById ("custombuttons-button17");

var proxyObjectManager = Components.classes["@mozilla.org/xpcomproxy;1"]
                                 .getService(Components.interfaces.nsIProxyObjectManager);
var proxyType = proxyObjectManager.INVOKE_ASYNC | proxyObjectManager.FORCE_PROXY_CREATION;

var thread = Components.classes["@mozilla.org/thread-manager;1"]
                        .getService(Components.interfaces.nsIThreadManager)
                        .newThread(0);

var po = proxyObjectManager.getProxyForObject (null, Components.interfaces.nsIDOMElement, b, proxyType);
// po = b; // crash test

var fun = (function (elt) {
    return function (s)
    {
        elt. setAttribute ("label", s);
    };
}) (po);

var backgroundTask = {
   run: function() {
   var i, j, s = "a";
   for (i = 0; i < 3; i++)
   {
       fun (s);
       for (j = 0; j < 10000000; j++)
       {
           j = (j + 1) - 1;
       }
       s += "a";
   }
   }
 }
 
 
thread.dispatch(backgroundTask, thread.DISPATCH_NORMAL);

спасибо, именно такой пример нужен был! ;)

эмм.. работает, но немного не так как я ожидал. подскажите, а это вообще реально, чтобы из дочернего потока можно было выполнить такие команды как например alert("blabla") или gBrowser.contentWindow.location = "http://google.com" ?
вот например я из потока получаю элемент <input type="text">, находящийся на открытой странице браузера, и ставлю ему element.value = "hello". запускаю, значение элемента меняется на hello, но сразу после этого браузер повисает. то же самое с alert и window.location. может я зря мучаюсь, пытаясь найти решение, и такое взаимодействие между потоками невозможно?

LedVisel пишет

значение элемента меняется на hello, но сразу после этого браузер повисает. то же самое с alert и window.location.

По моим наблюдениям - зависает не всегда.
Зависания, возможно, происходят из-за того, что проксированный объект в какой-то момент перестает существовать (страница, например, обновилась - визуально объект тот же, но старого, для которого создавался прокси, уже нет).
Или, может быть, из-за ASYNC флага.

Еще можно попробовать выполнять нужные действия из основного потока, передавая дочернему потоку объект основного, что-то вроде:

Выделить код

Код:

var proxyObjectManager = Components.classes["@mozilla.org/xpcomproxy;1"]
                                 .getService(Components.interfaces.nsIProxyObjectManager);
var proxyType = proxyObjectManager.INVOKE_SYNC | proxyObjectManager.FORCE_PROXY_CREATION;

var thread = Components.classes["@mozilla.org/thread-manager;1"]
                        .getService(Components.interfaces.nsIThreadManager)
                        .newThread(0);

var mto =
{
    QueryInterface: function (iid)
    {
        return this;
    },
    
    observe: function (s, t, d)
    {
        gBrowser. contentWindow. location. href = d;
    }
};

var po = proxyObjectManager.getProxyForObject (null, Components.interfaces.nsIObserver, mto, proxyType);

var fun = (function (elt) {
    return function (s)
    {
        elt. observe (null, "", s);
    };
}) (po);

var backgroundTask = {
   run: function() {
   var i, j, s = "a";
   for (i = 0; i < 3; i++)
   {
       fun ("http://www.google.com");
       for (j = 0; j < 10000000; j++)
       {
           j = (j + 1) - 1;
       }
       s += "a";
   }
   }
 }
 
 
thread.dispatch(backgroundTask, thread.DISPATCH_NORMAL);

спасибо за этот вариант, держите в репу. я пытался сам сделать нечто похожее, но что-то не получалось, уже не помню что.
а возможно ли при таком подходе реализовать механизм обратной связи? ну чтобы можно было еще и дочерний поток уведомлять из главного об определенных событиях?

LedVisel пишет

а возможно ли при таком подходе реализовать механизм обратной связи? ну чтобы можно было еще и дочерний поток уведомлять из главного об определенных событиях?

Возможно. Например, backgroundTask реализует интерфейс nsIObserver и, получая глобальное уведомление изменяет внутренний флаг, который периодически проверяется кодом из run ()