Interthread Communication

Cited from mozillaZine Forum.

Posted by tores.

http://forums.mozillazine.org/viewtopic.php?p=2431475&sid=34dd1a953aa98874e9f7cbb476aaaa28

If you want to call a method which performs graphical works but you are

not in the graphical thread, you have to create a proxy from your

object and call the method on this proxy instead of your object.



http://www.mozilla.org/projects/xpcom/Proxies.html


////////  See for C++ Implementation  /////////

http://www.nabble.com/Multi-threaded-XPCOM-Question-t1745150.html

Set to
STATE_UNJOINABLE if you wish to have the main thread return control

after starting the worker thread.

////////   Add Observer //////////
function InterfaceAPI()
{
    this.register();
}
InterfaceAPI.prototype = {
 
    observerService : null,
   
    register: function () {
        /* Register “UI” observer callback */
        this.observerService = Components.classes[“@mozilla.org/observer-service;1”]
                              .getService(Components.interfaces.nsIObserverService);
        this.observerService.addObserver(this,”UI”,false);
    },
   
    /* Callback for observed data on topic “UI” */
    observe: function(subject ,topic, data){
        alert(“Response: ” + data);
    }
   
};

/////////  Notify Observer ///////////
/* Client watcher running in separate thread */
var Watcher = {
    proxyObserverService: null,
   
    /* Call this to start the thread */
    threadStart: function()
    {
        const nsIThread = Components.interfaces.nsIThread;
        var thread = Components.classes[“@mozilla.org/thread;1”].createInstance(nsIThread);
        thread.init(this,                       /* Execute run() in this object */
                    0,
                    nsIThread.PRIORITY_NORMAL,
                    nsIThread.SCOPE_GLOBAL,
                    nsIThread.STATE_JOINABLE);
    },

    /* Separate thread */
    run: function ()
    {
        /* Get UI thread event queue */
        const nsIEventQueueService = Components.interfaces.nsIEventQueueService;
        var eqService = Components.classes[“@mozilla.org/event-queue-service;1”]
                              .getService(nsIEventQueueService);
        var uiQ = eqService.getSpecialEventQueue(nsIEventQueueService.UI_THREAD_EVENT_QUEUE);
       
        /* Create basic observer */
        var observerService = Components.classes[“@mozilla.org/observer-service;1”]
                              .getService(Components.interfaces.nsIObserverService);

        /* Create a proxy around the observer */
        var proxyObjectManager = Components.classes[“@mozilla.org/xpcomproxy;1”]
                                 .getService(Components.interfaces.nsIProxyObjectManager);
        var proxyType = proxyObjectManager.INVOKE_ASYNC | proxyObjectManager.FORCE_PROXY_CREATION

        /* !!!!!!! Firefox chrashes during getProxyForObject call !!!!!!!
         * EDIT: The second parameter was not syntactically correct. Fixed now, and the code works. */
        this.proxyObserverService = proxyObjectManager.getProxyForObject(uiQ,
                                                                         Components.interfaces.nsIObserverService,
                                                                         observerService,
                                                                         proxyType);
        /* Notify other thread */
        this.proxyObserverService.notifyObservers(null,”UI”,”I’m alive!”);
    }
   
};

new InterfaceAPI();
Watcher.threadStart();

technorati tags:, , , ,

Blogged with Flock

Returning a JS Array to JavaScript from a C++/JavaScript XPCOM object access through XPConnect

Cited from

http://groups.google.co.in/group/mozilla.dev.tech.xpcom/browse_thread/thread/

37b18383a15b82a7/b26a4e4568c3caf4?lnk=gst&q=nsiarray&rnum=2&hl=en#b26a4e4568c3caf4

// XPIDL

void getArray(out unsigned long count, [array, size_is(count), retval] out long retv);

// C++  XPCOM

NS_IMETHODIMP MyComponent::GetArray(PRUint32* count, PRInt32** retv) {

    *count = 10;

    *retv = (PRInt32*)nsMemory::Alloc(*count * sizeof(PRInt32));

    for (int i = 0; i < 10; ++i) (*retv)[i] = i;

    return NS_OK;

}

// JavaScript  XPCOM

Component.prototype.getArray = function(count, retv) {

    count.value = 10; // You must assign the length of array to count.

    var array = new Array();

    ……..

    return array;

}

// JavaScript Calling

var arr = myComponent.getArray({});

Blogged with Flock