thread stuck problem - Mozilla

This is a discussion on thread stuck problem - Mozilla ; Hello, I am using thread in components to read and parse big file line by line, and send message to GUI about the progress. the implementation is very similar to the example from: http://skrul.com/blog/projects/threaddemo /***** * async thread for compiling ...

+ Reply to Thread
Results 1 to 2 of 2

Thread: thread stuck problem

  1. thread stuck problem

    Hello,

    I am using thread in components to read and parse big file line by
    line, and send message to GUI about the progress.

    the implementation is very similar to the example from:
    http://skrul.com/blog/projects/threaddemo

    /*****
    * async thread for compiling mb. provide interface to start, pause,
    resume, stop the compiling,
    * using calback function to report the compiling progress.
    *
    */
    const CLASS_ID = Components.ID("{d41911c1-41bd-4d7d-
    a1fa-1593febb0c4e}");
    const CLASS_NAME = "OAKIME_MB_COMPILE_THREAD";

    // textual unique identifier
    const CONTRACT_ID = "@ime.oak.com/mbcompiler;1";

    /*****
    * load other js files
    */

    var JS_FILES = [
    "chrome://oakime/content/util/oakutil.js",
    "chrome://oakime/content/util/OakString.js",
    "chrome://oakime/content/mb/mbconst.js",
    "chrome://oakime/content/mb/mbfile.js",
    "chrome://oakime/content/mb/mbdef.js",
    ];

    /************************************************** *********
    class definition
    ************************************************** *********/

    function _D (msg){
    var OakIMEconsole = Components.classes["@mozilla.org/consoleservice;
    1"].getService(Components.interfaces.nsIConsoleServic e);
    OakIMEconsole.logStringMessage('OAK-DUMP:' +"["+msg+"]\n");
    }

    function loadJS(url)
    {
    _D('loadJS:'+url);
    //get script loader
    var loader = Components.classes["@mozilla.org/moz/jssubscript-loader;
    1"].

    getService(Components.interfaces.mozIJSSubScriptLo ader);

    //load the script
    try {

    loader.loadSubScript(url, null);
    }catch (e){
    _D('load js failed:'+e);
    }
    }

    for (var js in JS_FILES){
    //_D('js.value='+js.value);
    loadJS(JS_FILES[js]);
    }

    function TextMBCompileThread (){

    }

    TextMBCompileThread.prototype = {

    // mbManager : null,
    mbFile : null,
    mb : null,
    thread : null,
    proxy : null,
    eq : null,
    eqs : null,
    pom : null,
    callback : null,
    _cancelCompiling : false,

    // nsISupports
    QueryInterface : function(aIID) {
    if(!aIID.equals(Components.interfaces.nsISupports) &&
    !aIID.equals(Components.interfaces.nsIRunnable) &&
    !aIID.equals(Components.interfaces.nsIOakImeCompil eThread) &&
    !aIID.equals(Components.interfaces.nsIClassInfo)){
    throw Components.results.NS_ERROR_NO_INTERFACE;
    }

    return this;
    },

    // nsIClassInfo
    getInterfaces : function(count) {
    var ifaces = [
    Components.interfaces.nsISupports,
    Components.interfaces.nsIRunnable,
    Components.interfaces.nsIOakImeCompileThread,
    Components.interfaces.nsIClassInfo
    ];
    count.value = ifaces.length;
    return ifaces;
    },

    getHelperForLanguage : function(language) {
    return null;
    },

    contractID : CONTRACT_ID,
    classDescription : CLASS_NAME,
    classID : CLASS_ID,
    implementationLanguage :
    Components.interfaces.nsIProgrammingLanguage.JAVAS CRIPT,
    flags : Components.interfaces.nsIClassInfo.THREADSAFE,

    // nsIRunnable
    run : function(){
    // Create an event queue for the asynch service
    this.eq = this.eqs.createFromIThread(this.thread, false);
    this.callback.updateInfo("thread started");

    // Start the event loop.
    //this.eq.eventLoop();
    this._cancelCompiling = false;

    var mb = new OakIMEMB ();
    mb.init ();
    var date0 = new Date();
    var ret = mb.compileMBbyTextFile(this.mbFile, this);
    var date1 = new Date();
    var date2 = date1.getTime() -date0.getTime();
    _D('time used:'+date2);
    this.callback.compileFinished(this.mbFile);
    if (ret){
    this.callback.addMB(mb);
    }
    // Clean up when the event loop exits
    this.eq.processPendingEvents();
    this.eq.stopAcceptingEvents();
    this.eq.processPendingEvents();
    this.eqs.destroyThreadEventQueue();
    this.callback.updateInfo("thread stopped");
    this.proxy = null;
    },

    start : function(filepath, callback){
    // _D('thread start: callback='+callback+'|filepath'+filepath);
    this.mbFile = filepath;
    this.pom = Components.classes["@mozilla.org/xpcomproxy;1"]
    .getService(Components.interfaces.nsIProxyObjectMa nager);

    this.eqs = Components.classes["@mozilla.org/event-queue-service;
    1"]
    .getService(Components.interfaces.nsIEventQueueSer vice);

    // Wrap the supplied callback in a proxy using UI's event queue
    this.callback =

    this.pom.getProxyForObject(this.eqs.getSpecialEven tQueue(Components.interfaces.UI_THREAD_EVENT_QUEUE ),

    Components.interfaces.nsIOakImeCompileCallback,
    callback,

    Components.interfaces.nsIProxyObjectManager.INVOKE _ASYNC);

    // Create and start a thread for the asynch service
    this.thread = Components.classes["@mozilla.org/thread;1"]
    .createInstance(Components.interfaces.nsIThread);
    this.thread.init(this,
    1024*1024,
    Components.interfaces.nsIThread.PRIORITY_LOW, //
    PRIORITY_NORMAL,
    Components.interfaces.nsIThread.SCOPE_GLOBAL,

    Components.interfaces.nsIThread.STATE_UNJOINABLE);//STATE_JOINABLE);//

    // this.thread.join();
    /*
    * HACK: We must wait for the event queue to be created on the
    worker thread
    * before creating the proxy.
    */
    var mainThread = Components.classes["@mozilla.org/thread;1"]
    .createInstance(Components.interfaces.nsIThread).c urrentThread;
    var i = 0;
    while(!this.eq && i < 10) {
    mainThread.sleep(10);
    }
    if(!this.eq) {
    throw Error("Event queue not found");
    }

    // Create a proxied version of this object for the UI to use
    this.proxy =
    this.pom.getProxyForObject(this.eq,

    Components.interfaces.nsIOakImeCompileThread,
    this,

    Components.interfaces.nsIProxyObjectManager.INVOKE _ASYNC);
    return this.proxy;
    },

    stop : function(){
    // _D('cancelCompiling: called');
    this._cancelCompiling = true;
    //this.thread.interrupt();
    //this.thread.interrupt();
    },
    };


    /************************************************** *********
    class factory
    ************************************************** *********/
    //var oakimeCompiler = new TextMBCompileThread();
    var OakimeCompilerFactory = {
    createInstance: function (aOuter, aIID)
    {
    if (aOuter != null)
    throw Components.results.NS_ERROR_NO_AGGREGATION;
    return (new TextMBCompileThread()).QueryInterface(aIID);
    }
    };

    /************************************************** *********
    module definition (xpcom registration)
    ************************************************** *********/
    var OakIMECompilerModule = {
    registerSelf: function(aCompMgr, aFileSpec, aLocation, aType)
    {
    aCompMgr = aCompMgr.
    QueryInterface(Components.interfaces.nsIComponentR egistrar);
    aCompMgr.registerFactoryLocation(CLASS_ID, CLASS_NAME,
    CONTRACT_ID, aFileSpec, aLocation, aType);
    },

    unregisterSelf: function(aCompMgr, aLocation, aType)
    {
    aCompMgr = aCompMgr.
    QueryInterface(Components.interfaces.nsIComponentR egistrar);
    aCompMgr.unregisterFactoryLocation(CLASS_ID, aLocation);
    },

    getClassObject: function(aCompMgr, aCID, aIID)
    {

    if (!aIID.equals(Components.interfaces.nsIFactory))
    throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

    if (aCID.equals(CLASS_ID))
    return OakimeCompilerFactory;

    throw Components.results.NS_ERROR_NO_INTERFACE;
    },

    canUnload: function(aCompMgr) { return true; }
    };

    /************************************************** *********
    module initialization

    When the application registers the component, this function
    is called.
    ************************************************** *********/
    function NSGetModule(aCompMgr, aFileSpec) { return
    OakIMECompilerModule; }


    ====================================
    instead of using the message loop, //this.eq.eventLoop();
    I am using thread.eq.pendingEvents () and
    thread.eq.processPendingEvents(); to check the interruption event
    inside the thread, while reading each of line.

    isCancelCompiling : function (){
    var ret = false;
    if (this._thread){
    if (this._thread.eq){
    if (this._thread.eq.pendingEvents ()){
    this._thread.eq.processPendingEvents();
    }
    }
    ret = this._thread._cancelCompiling;
    }else{
    ret = this._cancelCompiling;
    }
    return ret;
    },

    the callback to update GUI.

    notifyCompileInfo : function (info){

    if (this._callback){
    this._callback.updateInfo(info);
    }
    var thread = Components.classes["@mozilla.org/thread;1"]
    .createInstance(Components.interfaces.nsIThread).c urrentThread;
    thread.sleep(100);
    },

    ======================================
    GUI part:
    try {
    this._compiler = Components.classes['@ime.oak.com/mbcompiler;
    1'].createInstance(Components.interfaces.nsIOakImeCom pileThread);
    this._proxy = this._compiler.start(path, this);
    // DUMP('_proxy='+this._proxy);
    }catch (e){
    DUMP(e);
    }

    =======================================

    It can work for a while, my problem is, sometime the thread seems to
    stop after parse 2-3 lines, sometime it stops after reading 1000
    lines. it also stop to response to the callback event.
    the Firefox can still work fine, and I can still start another
    instance of the thread.

    there is no any exception or error messages, how can I debug into it,
    and check the status of the thread.

    the FF version is 2.0.0.14, Mozilla/5.0 (Windows; U; Windows NT 5.1;
    en-US; rv:1.8.1.14) Gecko/20080404 Firefox/2.0.0.14

    And I can not find official documents about the thread.init()
    interface. because I am doubting memory/stack size and some resource
    are locked by other thread.

    any one can give me some hints? thanks.


  2. Re: thread stuck problem

    I gave it up and using Firefox 3, new interface of Thread Manager, it
    works quite good.

+ Reply to Thread