I have been trying to find a solution to what seems to be relatively simple scenario. I have JavaScript running in an html page that makes a call to an XPcom that I have written in C++. So far, so good.
This XPcom retrieves a reference to the observer-service (do_GetService("@mozilla.org/observer-service;1")
); fires a notify which is 'seen' by the JavaScript; the XPcom creates a windows thread (AFX), passes a copy of the observer-service reference and returns to the JavaScript caller; expecting the XPcom thread to send additional notifies at appropriate times (based on external events).
The notifies however fail to arrive in the JavaScript and my initial thought was the notify method will not deliver notifications from a 'different' thread. I've used the VStudio debugger to confirm the program sequence is as expected; ie the external event is being received by the thread and the notify method is being called... but, no notify event arrives.
I've read quite a few postings across the web and nothing really 'nails' the particular scenario I'm trying to address. I'm not married to the idea of using notify:
NS_DispatchToCurrentThread
however that is not working out either because I don't have an "event" from the JavaScript side to deliver. I can create one of my own within the context of the XPcom and I can 'notify it'; but, that was just a POC to prove I could deliver events from XPcom; now I need for the JavaScript side to give me an event to notify;nsiSupports
arg; but, the DispatchToCurrentThread
wants an nsiRunnable
and I cannot figure out how to pass one of those (the idl file does not support);nsiSupports
; but, am unsure about the details of doing so.The objective is quite simple. deliver asynchronous events or notifications from an XPcom thread to the main, or even sub, thread of the JavaScript; but, I'm getting less than 10% traction here. Has anyone accomplished this, or have ideas as to how to get it done?
You are correct, the observer service works only on the main thread (check the return value of your Notify()
call, it should be NS_ERROR_UNEXPECTED
). You are also correct as far as the solution goes - dispatch an event to the main thread, via NS_DispatchToMainThread()
. As to the actual implementation, function NS_NewRunnableMethod()
should help (unless you want to create your custom nsIRunnable
implementation - e.g. to pass parameters). You probably want to do something like this:
nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(xpcomComponent, &nsMyComponent::processEvent);
nsresult rv = NS_DispatchToMainThread(event);
Here xpcomComponent
would be a reference to your XPCOM component instance and nsMyComponent::processEvent
its method that needs to be called on main thread. That method would then be able to notify the observer.