costin      01/05/15 14:44:29

  Modified:    java/src/org/apache/xalan/stree SourceTreeHandler.java
               java/src/org/apache/xalan/transformer TransformerImpl.java
  Log:
  This is the "thread pooling hook".
  
  It slightly changes the API used to create and wait for the transform thread.
  Instead of using threadCreate() and Thread.start() that creates a new thread
  and  thread.join() that waits for a thread to end, we now use a 
ThreadControler
  class that has the equivalent methods:
  - run( Runnable ) - executes a task in a thread. The default implementation
  is identical with what we had, using new Thread() and start()
  - waitTread() - waits for a task to end. The default impl. is identical with
  the previous code, using thread.join().
  
  Someone wanting to use a thread pool for xalan will have to extend
  the ThreadControler and override the 2 methods, then call setThreadController.
  
  Xalan itself doesn't implement a thread pool right now ( for mosts uses it's
  not even needed - if you just do few transforms for example ), instead
  a server that runs xalan could plug it's own thread pool.
  
  Revision  Changes    Path
  1.36      +11 -30    
xml-xalan/java/src/org/apache/xalan/stree/SourceTreeHandler.java
  
  Index: SourceTreeHandler.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/stree/SourceTreeHandler.java,v
  retrieving revision 1.35
  retrieving revision 1.36
  diff -u -r1.35 -r1.36
  --- SourceTreeHandler.java    2001/03/28 04:41:02     1.35
  +++ SourceTreeHandler.java    2001/05/15 21:44:17     1.36
  @@ -365,6 +365,7 @@
         m_sourceTreeHandler.startDocument();
       }
   
  +    // Do the transformation in parallel with source reading
       if (m_useMultiThreading && (null != m_transformer))
       {
         if (m_transformer.isParserEventsOnMain())
  @@ -401,29 +402,26 @@
               resultTransformer.setOutputProperties(resultProps);
               
             }
  -        } 
  +        }
           
           if(null != m_docFrag)
             m_transformer.setSourceTreeDocForThread(m_docFrag);
           else
             m_transformer.setSourceTreeDocForThread(m_root);
  -
  -        Thread t = m_transformer.createTransformThread();
  -
  -        m_transformer.setTransformThread(t);
  -
  -        int cpriority = Thread.currentThread().getPriority();
   
  -        // t.setPriority(cpriority-1);
  -        t.setPriority(cpriority);
  -        t.start();
  +     int cpriority = Thread.currentThread().getPriority();
  +         
  +     // runTransformThread is equivalent with the 2.0.1 code,
  +     // except that the Thread may come from a pool.
  +     m_transformer.runTransformThread( cpriority );
  +     
         }
       }
   
       notifyWaiters();
     }
     
  -
  + 
     /**
      * Implement the endDocument event.
      *
  @@ -467,25 +465,8 @@
       // printTree(m_root);
       if (m_useMultiThreading && (null != m_transformer))
       {
  -      Thread transformThread = m_transformer.getTransformThread();
  -
  -      if (null != transformThread)
  -      {
  -        try
  -        {
  -
  -          // This should wait until the transformThread is considered not 
alive.
  -          transformThread.join();
  -          if(!m_transformer.hasTransformThreadErrorCatcher())
  -          {
  -            Exception e = m_transformer.getExceptionThrown();
  -            if(null != e)
  -              throw new org.xml.sax.SAXException(e);
  -          }
  -          m_transformer.setTransformThread(null);
  -        }
  -        catch (InterruptedException ie){}
  -      }
  +      // may throw SAXException ( if error reading transform )
  +      m_transformer.waitTransformThread();
       }
       m_entryCount--; // incremented at the start of startDocument
     }
  
  
  
  1.96      +102 -16   
xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java
  
  Index: TransformerImpl.java
  ===================================================================
  RCS file: 
/home/cvs/xml-xalan/java/src/org/apache/xalan/transformer/TransformerImpl.java,v
  retrieving revision 1.95
  retrieving revision 1.96
  diff -u -r1.95 -r1.96
  --- TransformerImpl.java      2001/05/07 18:56:58     1.95
  +++ TransformerImpl.java      2001/05/15 21:44:24     1.96
  @@ -133,6 +133,7 @@
   import org.xml.sax.InputSource;
   import javax.xml.transform.TransformerException;
   import org.xml.sax.XMLReader;
  +import org.xml.sax.SAXException;
   import org.xml.sax.XMLFilter;
   import org.xml.sax.Locator;
   import org.xml.sax.helpers.XMLReaderFactory;
  @@ -444,6 +445,8 @@
       return m_parserEventsOnMain;
     }
   
  +  // Both get/setTransformThread are called only from this
  +
     /**
      * <meta name="usage" content="internal"/>
      * Get the thread that the transform process is on.
  @@ -623,9 +626,12 @@
             }
             else
             {
  -            Thread t = createTransformThread();
  -//            m_reportInPostExceptionFromThread = false;
  -            t.start();
  +         runTransformThread();
  +         /** Code used in 2.0.1, replaced by runTransformThread
  +             Thread t = createTransformThread();
  +             //            m_reportInPostExceptionFromThread = false;
  +             t.start();
  +         */
               transformNode(doc);
             }
           }
  @@ -682,8 +688,9 @@
       {
         String msg = spe.getMessage();
         SAXSourceLocator loc = new SAXSourceLocator(spe);
  -      
  -      m_errorHandler.fatalError(new TransformerException( msg, loc ));
  +
  +      //      m_errorHandler.fatalError(new TransformerException( msg , loc 
));
  +      m_errorHandler.fatalError(new TransformerException( spe ));
       }
       catch(org.xml.sax.SAXException se)
       {
  @@ -2859,21 +2866,100 @@
     ////////////////////////
     // Implement Runnable //  
     ////////////////////////
  +  /** Base thread controler for xalan. Must be overriden with
  +      a derived class to support thread pooling.
  +
  +      All thread-related stuff is in this class.
  +  */
  +  public static class ThreadControler {
  +    
  +    /** Will get a thread from the pool, execute the task
  +     *  and return the thread to the pool.
  +     *
  +     *  The return value is used only to wait for completion
  +     *
  +     * @param priority if >0 the task will run with the given priority
  +     *  ( doesn't seem to be used in xalan, since it's allways the default )
  +     * @returns The thread that is running the task, can be used
  +     *          to wait for completion
  +     */
  +    public Thread run( Runnable task, int priority ) {
  +      Thread t=new Thread(task);
  +      t.start();
  +//       if( priority > 0 )
  +//   t.setPriority( priority );
  +      return t;
  +    }
  +
  +
  +    /**
  +     *  Wait until the task is completed on the worker
  +     *  thread. 
  +     */
  +    public void waitThread( Thread worker, Runnable task )
  +      throws InterruptedException
  +    {
  +      // This should wait until the transformThread is considered not alive.
  +      worker.join();
  +    }
  +  }
  +
  +  static ThreadControler tpool=new ThreadControler();
  +
  +  /** Change the ThreadControler that will be used to
  +   *  manage the transform threads.
  +   */
  +  public static void setThreadControler( ThreadControler tp ) {
  +    tpool=tp;
  +  }
     
  -  /**
  -   * Create a thread for the transform.  This can be overridden by derived 
  -   * implementations to provide their own thread, for thread pooling and the 
  -   * like.
  -   * 
  -   * @return thread suitable to use for the transformation.
  +  /** Called by SourceTreeHandler to start the transformation
  +   *  in a separate thread
      */
  -  public Thread createTransformThread()
  -  {
  -    Thread t = new Thread(this);
  -    // System.out.println("created thread: "+t.getName());
  -    return t;
  +  public void runTransformThread( int priority ) {
  +    // used in SourceTreeHandler
  +    Thread t=tpool.run( this, priority );
  +    this.setTransformThread( t );
  +  }
  +
  +  /** Called by this.transform() if isParserEventsOnMain()==false.
  +   *  Similar with runTransformThread(), but no priority is set
  +   *  and setTransformThread is not set.
  +   */
  +  public void runTransformThread( ) {
  +    tpool.run( this, -1);
  +  }
  +
  +
  +  /** Used by SourceTreeHandler to wait until the transform
  +   *   completes
  +   */
  +  public void waitTransformThread() throws SAXException {
  +    // This is called to make sure the task is done.
  +    // It is possible that the thread has been reused -
  +    // but for a different transformation. ( what if we 
  +    // recycle the transformer ? Not a problem since this is
  +    // still in use. )
  +    Thread transformThread = this.getTransformThread();
  +    if (null != transformThread)
  +      {
  +        try
  +       {
  +         tpool.waitThread( transformThread, this );
  +         
  +         if(!this.hasTransformThreadErrorCatcher())
  +           {
  +             Exception e = this.getExceptionThrown();
  +             if(null != e)
  +               throw new org.xml.sax.SAXException(e);
  +           }
  +         this.setTransformThread(null);
  +       }
  +        catch (InterruptedException ie){}
  +      }
     }
   
  +  
     /**
      * Get the exception thrown by the secondary thread (normally 
      * the transform thread).
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to