This class manages common facilities for multi-threaded environments, It can register different facilities for each thread, and also a default one, so that they can be referred by static methods, while possibly having different ones for different threads. Also a default facility exists that is used for threads for which no particular facility has been registerd registered.

Currently the only kind of facilities managed is MsgLogger.

An example use of this class is if 2 instances of a decoder are running in different threads and the messages of the 2 instances should be separated.

The default MsgLogger is a StreamMsgLogger that uses System.out as the 'out' stream and System.err as the 'err' stream, and a line width of 78. This can be changed using the registerMsgLogger() method.

 /// <summary> The method that is run by the thread. This method first joins the
 /// idle state in the pool and then enters an infinite loop. In this
 /// loop it waits until a target to run exists and runs it. Once the
 /// target's run() method is done it re-joins the idle state and
 /// notifies the waiting lock object, if one exists.
 ///
 /// <P>An interrupt on this thread has no effect other than forcing a
 /// check on the target. Normally the target is checked every time the
 /// thread is woken up by notify, no interrupts should be done.
 ///
 /// <P>Any exception thrown by the target's 'run()' method is catched
 /// and this thread is not affected, except for 'ThreadDeath'. If a
 /// 'ThreadDeath' exception is catched a warning message is printed by
 /// the 'FacilityManager' and the exception is propagated up. For
 /// exceptions which are subclasses of 'Error' or 'RuntimeException'
 /// the corresponding error condition is set and this thread is not
 /// affected. For any other exceptions a new 'RuntimeException' is
 /// created and the error condition is set, this thread is not affected.
 ///
 /// </summary>
 override public void  Run()
 {
     // Join the idle threads list
     Enclosing_Instance.putInIdleList(this);
     // Permanently lock the object while running so that target can
     // not be changed until we are waiting again. While waiting for a
     // target the lock is released.
     lock (this)
     {
         while (true)
         {
             // Wait until we get a target
             while (target == null)
             {
                 try
                 {
                     System.Threading.Monitor.Wait(this);
                 }
                 catch (System.Threading.ThreadInterruptedException e)
                 {
                 }
             }
             // Run the target and catch all possible errors
             try
             {
                 target.Run();
             }
             //UPGRADE_NOTE: Exception 'java.lang.ThreadDeath' was converted to 'System.InvalidOperationException' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'"
             catch (System.Threading.ThreadAbortException td)
             {
                 // We have been instructed to abruptly terminate
                 // the thread, which should never be done. This can
                 // cause another thread, or the system, to lock.
                 FacilityManager.getMsgLogger().printmsg(CSJ2K.j2k.util.MsgLogger_Fields.WARNING, "Thread.stop() called on a ThreadPool " + "thread or ThreadDeath thrown. This is " + "deprecated. Lock-up might occur.");
                 throw td;
             }
             catch (System.InvalidOperationException e)
             {
                 Enclosing_Instance.targetE = e;
             }
             //UPGRADE_NOTE: Exception 'java.lang.Throwable' was converted to 'System.Exception' which has different behavior. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1100'"
             catch (System.Exception e)
             {
                 // A totally unexpected error has occurred
                 // (Thread.stop(Throwable) has been used, which should
                 // never be.
                 Enclosing_Instance.targetRE = new System.Exception("Unchecked exception " + "thrown by target's " + "run() method in pool " + Enclosing_Instance.poolName + ".");
             }
             // Join idle threads
             Enclosing_Instance.putInIdleList(this);
             // Release the target and notify lock (i.e. wakeup)
             target = null;
             if (lock_Renamed != null)
             {
                 lock (lock_Renamed)
                 {
                     if (doNotifyAll)
                     {
                         System.Threading.Monitor.PulseAll(lock_Renamed);
                     }
                     else
                     {
                         System.Threading.Monitor.Pulse(lock_Renamed);
                     }
                 }
             }
         }
     }
 }