Thanks a lot Xavier ! That article helped a lot. I could make my UI
completely  responsive while the XPCOM processed long running tasks in
a background thread.

For the second question, the PRThreadState needs to be set to
STATE_UNJOINABLE if you wish to have the main thread return control
after starting the worker thread.

So for reference here are some code snippets if you wish to perform
long running tasks in a background thread that sends progress
notifications to the UI thread.

// MyComp.cpp
// Code to start the worker thread
// Create a class that implements the nsIRunnable interface
// pass a pointer to my MyComp's Interface so that the worker thread
can invoke a
// notification method on it.
NS_IMETHODIMP MyComp::StartLongTask(....)
....
nsCOMPtr<IMyComp> myIComp = do_QueryInterface(this);
MyRunnable* myRunnable = new MyRunnable(myIComp);
nsCOMPtr<nsIRunnable> my_nsIRunnable = do_QueryInterface(myRunnable);
// create the worker thread:
nsCOMPtr<nsIThread> workerThread =
do_CreateInstance("@mozilla.org/thread;1");
workerThread->Init(my_nsIRunnable,
                        (PRUint32)0,
                        (PRThreadPriority)nsIThread::PRIORITY_NORMAL,
                        (PRThreadScope)nsIThread::SCOPE_GLOBAL,
                        (PRThreadState)nsIThread::STATE_UNJOINABLE);
workerThread->Join();
....

// notifyObserver method that will broadcast the registered topic to
all listeners
// This method must be a method defined in the IDL of IMyComp
NS_IMETHODIMP MyComp::NotifyObservers(const char *topic, const char
*data) {
        PRUnichar* pruData = NULL;
        nsCOMPtr<nsIObserverService> observerService =
do_GetService("@mozilla.org/observer-service;1");
        if (data != NULL) {
                // convert const char* to PRUnichar*
                pruData = ....
        }
        observerService->NotifyObservers (NULL, topic, pruData);
        return NS_OK;
}

// MyRunnable.cpp

NS_IMETHODIMP InstallProcessor::Run() {
      // do something
      notifyObservers(topic, data);
      // do more things
      notifyObservers(topic, data);
}

void MyRunnable::notifyObservers(const char* topic, const char* data) {
        nsresult rv = NS_OK;
        nsCOMPtr<nsIProxyObjectManager> pIProxyObjectManager =
        do_GetService("@mozilla.org/xpcomproxy;1");
        nsCOMPtr<IMyComp> proxyMyComp;
        rv = pIProxyObjectManager->GetProxyForObject( NS_UI_THREAD_EVENTQ,
                                                  IMyComp::GetIID(),
                                                  _myComp,     // the
MyComp pointer passed to constructor
                                                  PROXY_SYNC |
PROXY_ALWAYS,

getter_AddRefs(proxyMyComp));
        if (proxyMyComp) {
                proxyMyComp->NotifyObservers(topic, data);
        }
}

Finally in the JS

// implement the observer interface. This is very easy in JS
var myObserver = { observe : function(subject, topic, data)  {
                                     if (topic == "myTopic") {
                                          // update UI with progress
info
                                     }
                                  }
                              };


// register the observer
  var observerService =
Components.classes["@mozilla.org/observer-service;1"].
                                                
getService(Components.interfaces.nsIObserverService);
  observerService.addObserver(myObserver, "myTopic", false);
// start the long running task
   myComp.startLongTask(...);


-Sandip



BRUYET Xavier wrote:
> > Question1: How do I get the Main thread from the worker thread ?
>
> I asked the same question one month ago. The response (not easy to
> find) is here :
> http://www.mozilla.org/projects/xpcom/Proxies.html
>
> 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.
> 
> Xavier.

_______________________________________________
dev-tech-xpcom mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-xpcom

Reply via email to