mozilla

Revision 165309 of User:Mossop

  • Revision slug: User:Mossop
  • Revision title: User:Mossop
  • Revision id: 165309
  • Created:
  • Creator: Mossop
  • Is current revision? No
  • Comment

Revision Content

This is a dumping ground for articles I am working on

JS Threading (1.8 branch only)

Work in progress. This code seems to work in general but I found that it would hang the browser often while calling the callbacks.

const Cc = Components.classes;
const Ci = Components.interfaces;

function myThread(proxy)
{
  this.proxy = proxy;
}

myThread.prototype = {
proxy: null,

// This runs in its own thread, but cannot affect any DOM or UI except by calls on the proxy object
run: function()
{
  // long running code
  this.proxy.method1();
  // long running code
  this.proxy.method2();
  // long running code
  this.proxy.method3();
},

QueryInterface: function(iid)
{
  if (iid.equals(Ci.nsIRunnable)
   || iid.equals(Ci.nsISupports))
  {
    return this;
  }
  else
  {
    throw Components.results.NS_ERROR_NO_INTERFACE;
  }
}
}

myComponent = {

startThread: function()
{
  // Retrieves the event queue for the UI thread
  var eQs = Cc["@mozilla.org/event-queue-service;1"]
              .getService(Ci.nsIEventQueueService);
  var eQueue = eQs.getSpecialEventQueue(Ci.UI_THREAD_EVENT_QUEUE);
  
  // Creates a proxy for this object that will make calls on the UI event queue.
  var nsIPOM = Ci.nsIProxyObjectManager;
  var proxyManager = Cc["@mozilla.org/xpcomproxy;1"]
                       .getService(Ci.nsIProxyObjectManager);
  var proxy = proxyManager.getProxyForObject(eQueue, 
                                             Ci.myComponent, 
                                             this, 
                                             Ci.nsIProxyObjectManager.INVOKE_SYNC
                                              + Ci.nsIProxyObjectManager.FORCE_PROXY_CREATION);

  // Creates the thread
  var runnable = new myThread(proxy);
  var thread = Cc["@mozilla.org/thread;1"]
		 .createInstance(Ci.nsIThread);
  
  // Starts the thread
  // These settings came from some source I found, they may not be correct.
  thread.init(runnable, 0, Ci.nsIThread.PRIORITY_NORMAL, 
                           Ci.nsIThread.SCOPE_LOCAL, 
                           Ci.nsIThread.STATE_UNJOINABLE);
},

// Must be declared in the myComponent interface idl
method1: function()
{
  // This runs in the main UI thread
},

// Must be declared in the myComponent interface idl
method2: function()
{
  // This runs in the main UI thread
},

// Must be declared in the myComponent interface idl
method3: function()
{
  // This runs in the main UI thread
},

QueryInterface: function(iid)
{
  if (iid.equals(Ci.myComponent)
   || iid.equals(Ci.nsISupports))
  {
    return this;
  }
  else
  {
    throw Components.results.NS_ERROR_NO_INTERFACE;
  }
}
}

Revision Source

<p>This is a dumping ground for articles I am working on
</p>
<ul><li> <a href="User:Mossop/UpdateManifest">Update Manifests</a>
</li></ul>
<h2 name="JS_Threading_.281.8_branch_only.29"> JS Threading (1.8 branch only) </h2>
<p>Work in progress. This code seems to work in general but I found that it would hang the browser often while calling the callbacks.
</p>
<pre>const Cc = Components.classes;
const Ci = Components.interfaces;

function myThread(proxy)
{
  this.proxy = proxy;
}

myThread.prototype = {
proxy: null,

// This runs in its own thread, but cannot affect any DOM or UI except by calls on the proxy object
run: function()
{
  // long running code
  this.proxy.method1();
  // long running code
  this.proxy.method2();
  // long running code
  this.proxy.method3();
},

QueryInterface: function(iid)
{
  if (iid.equals(Ci.nsIRunnable)
   || iid.equals(Ci.nsISupports))
  {
    return this;
  }
  else
  {
    throw Components.results.NS_ERROR_NO_INTERFACE;
  }
}
}

myComponent = {

startThread: function()
{
  // Retrieves the event queue for the UI thread
  var eQs = Cc["@mozilla.org/event-queue-service;1"]
              .getService(Ci.nsIEventQueueService);
  var eQueue = eQs.getSpecialEventQueue(Ci.UI_THREAD_EVENT_QUEUE);
  
  // Creates a proxy for this object that will make calls on the UI event queue.
  var nsIPOM = Ci.nsIProxyObjectManager;
  var proxyManager = Cc["@mozilla.org/xpcomproxy;1"]
                       .getService(Ci.nsIProxyObjectManager);
  var proxy = proxyManager.getProxyForObject(eQueue, 
                                             Ci.myComponent, 
                                             this, 
                                             Ci.nsIProxyObjectManager.INVOKE_SYNC
                                              + Ci.nsIProxyObjectManager.FORCE_PROXY_CREATION);

  // Creates the thread
  var runnable = new myThread(proxy);
  var thread = Cc["@mozilla.org/thread;1"]
		 .createInstance(Ci.nsIThread);
  
  // Starts the thread
  // These settings came from some source I found, they may not be correct.
  thread.init(runnable, 0, Ci.nsIThread.PRIORITY_NORMAL, 
                           Ci.nsIThread.SCOPE_LOCAL, 
                           Ci.nsIThread.STATE_UNJOINABLE);
},

// Must be declared in the myComponent interface idl
method1: function()
{
  // This runs in the main UI thread
},

// Must be declared in the myComponent interface idl
method2: function()
{
  // This runs in the main UI thread
},

// Must be declared in the myComponent interface idl
method3: function()
{
  // This runs in the main UI thread
},

QueryInterface: function(iid)
{
  if (iid.equals(Ci.myComponent)
   || iid.equals(Ci.nsISupports))
  {
    return this;
  }
  else
  {
    throw Components.results.NS_ERROR_NO_INTERFACE;
  }
}
}

</pre>
Revert to this revision