I have reworked a lot of code, removing a lot of extra cruft and have
(for the time being) gotten Windows to not crash when I try to start a
background thread. This code is run when starting an app and will
happily add to the <listbox id="thread_dump"> forever in OS X but will
only run for about 11 seconds on Windows.
This is run on startup:
var async = Cc['@flickr.com/async;1'].createInstance(Ci.IAsync);
async.start(callback);
The callback code is in the same file as the rest of the UI stuff:
var callback = {
add: function(id, result) {
var lb = document.getElementById('thread_dump');
var item = lb.appendItem('id: ' + id + ', result: ' + result);
lb.ensureElementIsVisible(item);
},
QueryInterface: function(iid) {
if(!iid.equals(Ci.nsISupports) &&
!iid.equals(Ci.ICallback))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
getInterfaces: function(count) {
var ifaces = [
Ci.nsISupports,
Ci.ICallback,
Ci.nsIClassInfo
];
count.value = ifaces.length;
return ifaces;
},
getHelperForLanguage: function(language) {
return null;
},
contractID: null,
classDescription: 'callback',
classID: null,
implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
flags: 0
};
The ICallback and IAsync interfaces:
#include "nsISupports.idl"
[scriptable, uuid(31ec9ecc-3ace-11dc-8314-0800200c9a66)]
interface ICallback : nsISupports
{
void add(in long id, in AString result);
};
#include "nsISupports.idl"
interface ICallback;
[scriptable, uuid(46732fb4-3a31-11dc-8314-0800200c9a66)]
interface IAsync : nsISupports
{
void start(in ICallback callback);
void add(in long id, in long thumbSize, in AString path);
};
This code is in the app's components/ directory and implements the
IAsync interface:
const CLASSNAME = 'async';
const CONTRACTID = "@flickr.com/async;1";
const CID = Components.ID('{46732fb4-3a31-11dc-8314-0800200c9a66}');
const Cc = Components.classes;
const Ci = Components.interfaces;
var async = function() {
};
async.prototype = {
add: function(id, thumbSize, path) {
},
start: function(callback) {
var pom =
Cc['@mozilla.org/xpcomproxy;1'].getService(Ci.nsIProxyObjectManager);
var eqs =
Cc['@mozilla.org/event-queue-service;1'].getService(Ci.nsIEventQueueService);
var callback =
pom.getProxyForObject(eqs.getSpecialEventQueue(Ci.UI_THREAD_EVENT_QUEUE),
Ci.ICallback, callback,
Ci.nsIProxyObjectManager.INVOKE_ASYNC);
var thread =
Cc['@mozilla.org/thread;1'].createInstance(Ci.nsIThread);
thread.init(new background(callback), 0,
Ci.nsIThread.PRIORITY_NORMAL,
Ci.nsIThread.SCOPE_GLOBAL, Ci.nsIThread.STATE_JOINABLE);
},
QueryInterface: function(iid) {
if(!iid.equals(Ci.nsISupports) &&
!iid.equals(Ci.async))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
getInterfaces: function(count) {
var ifaces = [
Ci.nsISupports,
Ci.async,
Ci.nsIClassInfo
];
count.value = ifaces.length;
return ifaces;
},
getHelperForLanguage: function(language) {
return null;
},
contractID: null,
classDescription: 'async',
classID: null,
implementationLanguage: Ci.nsIProgrammingLanguage.JAVASCRIPT,
flags: 0
};
var background = function(callback) {
this.callback = callback;
};
background.prototype = {
run: function() {
var thread =
Cc['@mozilla.org/thread;1'].createInstance(Ci.nsIThread).currentThread;
var i = 0;
while (true) {
this.callback.add(i++, 'foo');
thread.sleep(1000);
}
}
};
var Module = new Object();
Module.registerSelf = function(compMgr, fileSpec, location, type) {
compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
compMgr.registerFactoryLocation(CID, CLASSNAME, CONTRACTID, fileSpec,
location, type);
}
Module.getClassObject = function(compMgr, cid, iid) {
if(!cid.equals(CID)) throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
if(!iid.equals(Ci.nsIFactory)) throw
Components.results.NS_ERROR_NO_INTERFACE;
return Factory;
}
Module.canUnload = function(compMgr) {
return true;
}
var Factory = {};
Factory.createInstance = function(outer, iid) {
if(outer != null) throw Components.results.NS_ERROR_NO_AGGREGATION;
return new async();
}
function NSGetModule(compMgr, fileSpec) {
return Module;
}
This is again rather similar to Steve's example at
http://skrul.com/blog/projects/threaddemo but takes much of the
complexity out in the name of getting something working.
In Windows XULRunner 1.8.1.3 this will run, adding 11 items to the
listbox before the background thread goes dead. The UI remains
responsive throughout. In OS X this will run indefinitely, again with
the UI remaining responsive throughout.
I can't find any documented similar situations. Is there some condition
I am tripping that makes the thread die?
Thanks,
Richard
[EMAIL PROTECTED]
_______________________________________________
dev-tech-xpcom mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-xpcom