dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/engine engine.h, 1.82, 1.83 heap.c, 1.19


From: Thong Nguyen <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/engine engine.h, 1.82, 1.83 heap.c, 1.19, 1.20 ilrun.c, 1.36, 1.37 lib_thread.c, 1.18, 1.19 monitor.c, 1.3, 1.4 process.c, 1.53, 1.54 thread.c, 1.21, 1.22 throw.c, 1.6, 1.7
Date: Tue, 15 Jul 2003 18:17:35 -0400

Update of /cvsroot/dotgnu-pnet/pnet/engine
In directory subversions:/tmp/cvs-serv24211/engine

Modified Files:
        engine.h heap.c ilrun.c lib_thread.c monitor.c process.c 
        thread.c throw.c 
Log Message:
Various updates to threading & finalization


Index: engine.h
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/engine.h,v
retrieving revision 1.82
retrieving revision 1.83
diff -C2 -r1.82 -r1.83
*** engine.h    13 Jul 2003 12:41:01 -0000      1.82
--- engine.h    15 Jul 2003 22:17:33 -0000      1.83
***************
*** 85,88 ****
--- 85,102 ----
  
  /*
+  *    Passed to objects when they are finalized.  Objects being finalized 
should
+  * verify the information in the context valid before continuuing finalization
+  * because it is possible for objects to be finalized *long* after their owner
+  * process has been destroyed.
+  */
+ typedef struct __tagILFinalizationContext ILFinalizationContext;
+ struct __tagILFinalizationContext
+ {
+       /* The process that created the object and registered the finalizer or 0
+           if that process has been destroyed. */
+       ILExecProcess *volatile process;
+ };
+ 
+ /*
   * Execution control context for a process.
   */
***************
*** 98,101 ****
--- 112,118 ----
        ILExecThread   *mainThread;
  
+       /* The finalizer thread for the process */
+       ILExecThread   *finalizerThread;
+ 
        /* Default stack size for new threads */
        ILUInt32                stackSize;
***************
*** 119,122 ****
--- 136,140 ----
        ILClass        *exceptionClass;
        ILClass        *clrTypeClass;
+       ILClass          *threadAbortClass;
  
        /* The object to throw when the system runs out of memory */
***************
*** 138,141 ****
--- 156,162 ----
  #endif
  
+       /* Finalization context used by this process */
+       ILFinalizationContext *finalizationContext;
+ 
        /* Hash table that maps program items to reflection objects */
        void               *reflectionHash;
***************
*** 228,231 ****
--- 249,255 ----
        ILObject       *thrownException;
  
+       /* Indicates if an abort is in progress */
+       int                             aborting;
+ 
        /* Security manager in use by this thread */
        ILObject           *securityManager;
***************
*** 652,655 ****
--- 676,699 ----
   */
  ILObject *_ILGetCurrentClrThread(ILExecThread *thread);
+ 
+ /*
+  *    Makes the given support thread execute in the context of the given 
engine thread.
+  */
+ void _ILThreadExecuteOn(ILThread *thread, ILExecThread *execThread);
+ 
+ /*
+  *    Throws a thread abort exception on the given thread.
+  */
+ void _ILExecThreadThrowThreadAbortException(ILExecThread *thread, ILObject 
*stateInfo);
+ 
+ /*
+  *    Aborts the current thread.
+  */
+ void _ILAbortThread(ILExecThread *thread);
+ 
+ /*
+  *    Handles thread aborts & interruption.
+  */
+ void _ILHandleWaitResult(ILExecThread *thread, int result);
  
  /*

Index: heap.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/heap.c,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -r1.19 -r1.20
*** heap.c      8 Jul 2003 12:05:17 -0000       1.19
--- heap.c      15 Jul 2003 22:17:33 -0000      1.20
***************
*** 26,32 ****
  #endif
  
- /* TODO: Design a better way to access the main executing process */
- static ILExecProcess *mainProcess;
- 
  /*
   * Initialize a class.
--- 26,29 ----
***************
*** 34,40 ****
  static int InitializeClass(ILExecThread *thread, ILClass *classInfo)
  {
-       /* Cache the main process needed by finalizers */
-       mainProcess = thread->process;
- 
        /* Quick check to see if the class is already laid out,
           to avoid acquiring the metadata lock if possible */
--- 31,34 ----
***************
*** 68,80 ****
  }
  
! /*
!  *    Cleanup handler that is attached to the finalizer thread so that it 
unregisters
!  * itself upon closing.
!  */
! static void DeregisterFinalizerThreadForManagedExecution(ILThread *thread)
! {
!       ILThreadUnregisterForManagedExecution(thread);
! }
! 
  void _ILFinalizeObject(void *block, void *data)
  {
--- 62,66 ----
  }
  
! /* This method assumes there is only one finalizer thread for the entire os 
process */
  void _ILFinalizeObject(void *block, void *data)
  {
***************
*** 83,128 ****
        ILMethod *method;
        ILType *signature;
        ILExecThread *execThread;
        
        /* Skip the object header within the block */
        object = GetObjectFromGcBase(block);
  
!       /* Get the object's class and locate the "Finalize" method */
!       classInfo = GetObjectClass(object);
! 
!       execThread = ILExecThreadCurrent();
  
!       if (execThread == 0)
        {
!               ILThread *thread;
  
!               /* The thread the finalizer isn't registered for managed 
execution */
!               /* Register the thread to execute managed code */
  
!               thread = ILThreadSelf();
  
!               if (!mainProcess)
!               {
!                       /* Impossible state */
!                       /* Finalizer on an object called before an object was 
allocated */
  
!                       return;
!               }
  
!               if ((execThread = 
ILThreadRegisterForManagedExecution(mainProcess, thread)) == 0)
                {
-                       /* Registering for managed execution failed */
- 
                        return;
                }
  
!               /* Register a cleanup handler that will deregister the thread 
from the engine
!                   when it finishes */
!               ILThreadRegisterCleanup(thread, 
DeregisterFinalizerThreadForManagedExecution);
! 
!               /* Mark the thread as a finalizer thread */
!               execThread->isFinalizerThread = 1;
        }
!       
        while(classInfo != 0)
        {
--- 69,121 ----
        ILMethod *method;
        ILType *signature;
+       ILThread *thread;
+       ILExecProcess *process;
        ILExecThread *execThread;
+       ILFinalizationContext *finalizationContext;
        
+       /* Get the finalization context */
+       finalizationContext = (ILFinalizationContext *)data;
+ 
        /* Skip the object header within the block */
        object = GetObjectFromGcBase(block);
  
!       /* Get the process that created the object */
!       process = finalizationContext->process;
  
!       /* Make sure the process is still alive */
!       if (process == 0)
        {
!               /* Our owner process died.  We're orphaned and can't finalize */
!               return;
!       }
  
!       /* Get the engine thread to execute the finalizer on */
!       execThread = process->finalizerThread;
  
!       /* Get the finalizer thread instance */
!       thread = ILThreadSelf();
  
!       if (execThread == 0)
!       {                               
!               /* Create a new engine thread for the finalizers of this 
process to run on */
  
!               execThread = _ILExecThreadCreate(process);
  
!               if (execThread == 0)
                {
                        return;
                }
  
!               execThread->supportThread = thread;
!               process->finalizerThread = execThread;
        }
! 
!       /* Make the finalizer thread execute in the context of the object's 
process's
!           finalizer thread */
!       _ILThreadExecuteOn(thread, execThread);
! 
!       /* Get the object's class and locate the "Finalize" method */
!       classInfo = GetObjectClass(object);
! 
        while(classInfo != 0)
        {
***************
*** 150,153 ****
--- 143,151 ----
                classInfo = ILClassGetParent(classInfo);
        }
+ 
+       execThread->supportThread = 0;
+ 
+       /* Make sure the finalizer thread can no longer execute managed code */
+       _ILThreadExecuteOn(thread, 0);  
  }
  
***************
*** 190,194 ****
           ((ILClassPrivate *)(classInfo->userData))->hasFinalizer)
        {
!               ILGCRegisterFinalizer(ptr, _ILFinalizeObject, 0);
        }
  
--- 188,192 ----
           ((ILClassPrivate *)(classInfo->userData))->hasFinalizer)
        {
!               ILGCRegisterFinalizer(ptr, _ILFinalizeObject, 
thread->process->finalizationContext);
        }
  
***************
*** 235,239 ****
           ((ILClassPrivate *)(classInfo->userData))->hasFinalizer)
        {
!               ILGCRegisterFinalizer(ptr, _ILFinalizeObject, 0);
        }
  
--- 233,237 ----
           ((ILClassPrivate *)(classInfo->userData))->hasFinalizer)
        {
!               ILGCRegisterFinalizer(ptr, _ILFinalizeObject, 
thread->process->finalizationContext);
        }
  

Index: ilrun.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/ilrun.c,v
retrieving revision 1.36
retrieving revision 1.37
diff -C2 -r1.36 -r1.37
*** ilrun.c     8 Jul 2003 04:11:14 -0000       1.36
--- ilrun.c     15 Jul 2003 22:17:33 -0000      1.37
***************
*** 442,448 ****
        }
  
!       /* Wait for all other foreground threads to finish */
        ILThreadWaitForForegroundThreads(-1);
! 
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
        /* Print profile information if requested */
--- 442,448 ----
        }
  
!       /* Wait for all foreground threads to finish */
        ILThreadWaitForForegroundThreads(-1);
!  
  #if !defined(IL_CONFIG_REDUCE_CODE) && !defined(IL_WITHOUT_TOOLS)
        /* Print profile information if requested */
***************
*** 489,492 ****
--- 489,493 ----
        error = ILExecProcessGetStatus(process);
        ILExecProcessDestroy(process);
+       ILExecDeinit();
  
        return (int)retval;

Index: lib_thread.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/lib_thread.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -r1.18 -r1.19
*** lib_thread.c        7 Jul 2003 16:00:59 -0000       1.18
--- lib_thread.c        15 Jul 2003 22:17:33 -0000      1.19
***************
*** 1,3 ****
- 
  /*
   * lib_thread.c - Internalcall methods for "System.Threading.*".
--- 1,2 ----
***************
*** 40,44 ****
   * Timeout value the managed WaitHandle uses.
   */
! #define WIN32_WAIT_TIMEOUT (258L)
  
  /*
--- 39,43 ----
   * Timeout value the managed WaitHandle uses.
   */
! #define IL_CLR_WAIT_TIMEOUT (258L)
  
  /*
***************
*** 48,61 ****
  
  /*
-  * Cache of the System.Threading.ThreadStart.Invoke() method.
-  */
- static ILMethod *c_ThreadStartInvokeMethod = NULL;
- 
- /*
-  *    Predeclartion of code that handles thread aborts & interruption.
-  */
- static void HandleWaitResult(ILExecThread *thread, int result);
- 
- /*
   * public static void Enter(Object obj);
   */
--- 47,50 ----
***************
*** 80,84 ****
                {
                        break;
!               }
        }
  }
--- 69,73 ----
                {
                        break;
!               }               
        }
  }
***************
*** 103,108 ****
   * lockword.
   */
! static int _IL_Monitor_CheckAndReturnMonitorToFreeList(ILExecThread *thread, 
ILExecMonitor *monitor, volatile ILObject *obj)
! {     
        if(monitor->waiters == 0 && 
ILWaitMonitorCanClose(monitor->supportMonitor))
        {
--- 92,103 ----
   * lockword.
   */
! static void _IL_Monitor_CheckAndReturnMonitorToFreeList(ILExecThread *thread, 
ILExecMonitor *monitor, volatile ILObject *obj)
! {
!       if (monitor == 0)
!       {
!               /* The monitor has already been claimed by another thread */
!               return;
!       }
! 
        if(monitor->waiters == 0 && 
ILWaitMonitorCanClose(monitor->supportMonitor))
        {
***************
*** 111,115 ****
                /* Remove the monitor from the object if the object hasn't been 
assigned
                      a new monitor */
!               current = CompareAndExchangeObjectLockWord(thread, obj, 0, 
IL_LW_MARK(monitor));
  
                if(current == IL_LW_MARK(monitor))
--- 106,110 ----
                /* Remove the monitor from the object if the object hasn't been 
assigned
                      a new monitor */
!               current = CompareAndExchangeObjectLockWord(thread, obj, 
IL_LW_MARK(0), IL_LW_MARK(monitor));
  
                if(current == IL_LW_MARK(monitor))
***************
*** 129,137 ****
                           has already been claimed as as free by another 
thread */
                }
- 
-               return 1;
        }
- 
-       return 0;
  }
  
--- 124,128 ----
***************
*** 221,227 ****
                                        monitor->next = thread->freeMonitor;
                                        thread->freeMonitor = monitor;
!                               }                               
  
!                               HandleWaitResult(thread, result);
  
                                return 0;
--- 212,218 ----
                                        monitor->next = thread->freeMonitor;
                                        thread->freeMonitor = monitor;
!                               }
  
!                               _ILHandleWaitResult(thread, result);
  
                                return 0;
***************
*** 234,238 ****
                        /* Finally allow other threads to enter the monitor */
                        _IL_ObjectLockword_Unmark(thread, obj);
! 
                        return 1;
                }
--- 225,229 ----
                        /* Finally allow other threads to enter the monitor */
                        _IL_ObjectLockword_Unmark(thread, obj);
!                       
                        return 1;
                }
***************
*** 255,261 ****
               disassociate the monitor with the object. */
        if (IL_LW_MARKED(lockword))
!       {
                /* Spin */
- 
                goto retry;
        }
--- 246,256 ----
               disassociate the monitor with the object. */
        if (IL_LW_MARKED(lockword))
!       {               
!               /* Yeld CPU time while spinning.  This appears to speed up 
monitors
!                   but may cause us to never enter the object's monitor, so 
threads releasing
!                       the same monitor will sleep too */
!               ILThreadSleep(0);
!               
                /* Spin */
                goto retry;
        }
***************
*** 285,288 ****
--- 280,284 ----
                _IL_ObjectLockword_Unmark(thread, obj);
  
+               /* Spin */
                goto retry;
        }
***************
*** 293,299 ****
        /* Try entering the monitor */  
        result = ILWaitMonitorTryEnter(monitor->supportMonitor, timeout);
! 
!       _IL_Interlocked_Decrement_Ri(thread, (ILInt32 *)&monitor->waiters);
! 
        /* Failed or timed out somehow */
        if (result != 0)
--- 289,293 ----
        /* Try entering the monitor */  
        result = ILWaitMonitorTryEnter(monitor->supportMonitor, timeout);
!       
        /* Failed or timed out somehow */
        if (result != 0)
***************
*** 311,315 ****
  
                /* Handle ThreadAbort etc */    
!               HandleWaitResult(thread, result);
        }
  
--- 305,313 ----
  
                /* Handle ThreadAbort etc */    
!               _ILHandleWaitResult(thread, result);
!       }
!       else
!       {
!               _IL_Interlocked_Decrement_Ri(thread, (ILInt32 
*)&monitor->waiters);
        }
  
***************
*** 322,325 ****
--- 320,324 ----
  void _IL_Monitor_Exit(ILExecThread *thread, ILObject *objnv)
  {
+       int result;
        ILLockWord lockword;
        ILExecMonitor *monitor;
***************
*** 335,339 ****
                return;
        }
!               
        /* Make sure noone is allowed to change the object's monitor */
        _IL_ObjectLockword_WaitAndMark(thread, obj);
--- 334,338 ----
                return;
        }
! 
        /* Make sure noone is allowed to change the object's monitor */
        _IL_ObjectLockword_WaitAndMark(thread, obj);
***************
*** 349,357 ****
                /* Hmm.  Can't call Monitor.Exit before Monitor.Enter */
  
                ILExecThreadThrowSystem
                        (
!                       thread,                         
!                       "System.Threading.SynchronizationLockException",        
!                       "Exception_ThreadNeedsLock"
                        );
  
--- 348,358 ----
                /* Hmm.  Can't call Monitor.Exit before Monitor.Enter */
  
+               _IL_ObjectLockword_Unmark(thread, obj);
+ 
                ILExecThreadThrowSystem
                        (
!                               thread,
!                               
"System.Threading.SynchronizationLockException",        
!                               "Exception_ThreadNeedsLock"
                        );
  
***************
*** 359,381 ****
        }
  
!       if (ILWaitMonitorSpeculativeLeave(monitor->supportMonitor) == 1 
                /* Note: No need to check for aborts on call to leave */)
!       {               
!               if (!_IL_Monitor_CheckAndReturnMonitorToFreeList(thread, 
monitor, obj))
                {
!                       /* There are waiters.  Unmark the lockword */           
!                       _IL_ObjectLockword_Unmark(thread, obj);
!               }
!               else
!               {       
!                       /* The object's lockword has been cleared.  This 
implicitly unmarks it */
!               }
  
!               ILWaitMonitorCompleteLeave(monitor->supportMonitor);
        }
        else
        {
!               /* We don't own the monitor */
!                               
                ILExecThreadThrowSystem
                        (
--- 360,388 ----
        }
  
!       if ((result = ILWaitMonitorSpeculativeLeave(monitor->supportMonitor)) > 0
                /* Note: No need to check for aborts on call to leave */)
!       {
!               _IL_Monitor_CheckAndReturnMonitorToFreeList(thread, monitor, 
obj);
!                               
!               /* There are waiters.  Unmark the lockword */           
!               _IL_ObjectLockword_Unmark(thread, obj);
!               
!               /* Notify waiting monitors */
!               ILWaitMonitorCompleteLeave(monitor->supportMonitor);            
! 
!               if (result != IL_WAIT_LEAVE_STILL_OWNS)
                {
!                       /* If we no longer own the monitor then give up some 
CPU time to prevent
!                           monitor hogging */
  
!                       ILThreadSleep(0);
!               }
        }
        else
        {
!               /* Unmark the lockword */
!               _IL_ObjectLockword_Unmark(thread, obj);
! 
!               /* We don't own the monitor */                          
                ILExecThreadThrowSystem
                        (
***************
*** 384,390 ****
                                "Exception_ThreadNeedsLock"
                        );
- 
-               /* Unmark the lockword */
-               _IL_ObjectLockword_Unmark(thread, obj);
        }       
  }
--- 391,394 ----
***************
*** 419,422 ****
--- 423,427 ----
        if (IL_LW_MARKED(lockword))
        {
+               
                /* Spin */
                goto retry;
***************
*** 521,524 ****
--- 526,530 ----
                _IL_ObjectLockword_Unmark(thread, obj);
  
+               /* Spin */
                goto retry;
        }
***************
*** 549,553 ****
--- 555,568 ----
                /* Thread doesn't currently own lock */
  
+               /* Mark the object's lockword */
+               _IL_ObjectLockword_WaitAndMark(thread, obj);
+ 
+               /* The current thread has exclusive access to the object's 
lockword */
+ 
                _IL_Interlocked_Decrement_Ri(thread, (ILInt32 
*)&monitor->waiters);
+               _IL_Monitor_CheckAndReturnMonitorToFreeList(thread, monitor, 
obj);
+ 
+               /* Unmark the object's lockword */
+               _IL_ObjectLockword_Unmark(thread, obj);
  
                ILExecThreadThrowSystem
***************
*** 564,568 ****
--- 579,592 ----
                /* Successfully waited */
  
+               /* Mark the object's lockword */
+               _IL_ObjectLockword_WaitAndMark(thread, obj);
+ 
+               /* The current thread has exclusive access to the object's 
lockword */
+ 
                _IL_Interlocked_Decrement_Ri(thread, (ILInt32 
*)&monitor->waiters);
+               _IL_Monitor_CheckAndReturnMonitorToFreeList(thread, monitor, 
obj);
+ 
+               /* Unmark the object's lockword */
+               _IL_ObjectLockword_Unmark(thread, obj);
  
                return 1;
***************
*** 573,579 ****
--- 597,611 ----
                /* Timed out */
  
+               /* Mark the object's lockword */
+               _IL_ObjectLockword_WaitAndMark(thread, obj);
+ 
+               /* The current thread has exclusive access to the object's 
lockword */
+ 
                _IL_Interlocked_Decrement_Ri(thread, (ILInt32 
*)&monitor->waiters);
                _IL_Monitor_CheckAndReturnMonitorToFreeList(thread, monitor, 
obj);
  
+               /* Unmark the object's lockword */
+               _IL_ObjectLockword_Unmark(thread, obj);
+ 
                return 0;
  
***************
*** 582,588 ****
                /* Handle ThreadAbort etc */
  
                _IL_Interlocked_Decrement_Ri(thread, (ILInt32 
*)&monitor->waiters);
  
!               HandleWaitResult(thread, result);
  
                return 0;
--- 614,629 ----
                /* Handle ThreadAbort etc */
  
+               /* Mark the object's lockword */
+               _IL_ObjectLockword_WaitAndMark(thread, obj);
+ 
+               /* The current thread has exclusive access to the object's 
lockword */
+ 
                _IL_Interlocked_Decrement_Ri(thread, (ILInt32 
*)&monitor->waiters);
+               _IL_Monitor_CheckAndReturnMonitorToFreeList(thread, monitor, 
obj);
  
!               /* Unmark the object's lockword */
!               _IL_ObjectLockword_Unmark(thread, obj);
! 
!               _ILHandleWaitResult(thread, result);
  
                return 0;
***************
*** 641,645 ****
                        /* Handle ThreadAbort etc */
  
!                       HandleWaitResult(thread, result);
  
                        return;
--- 682,686 ----
                        /* Handle ThreadAbort etc */
  
!                       _ILHandleWaitResult(thread, result);
  
                        return;
***************
*** 703,707 ****
                        /* Handle ThreadAbort etc */
  
!                       HandleWaitResult(thread, result);
  
                        return;
--- 744,748 ----
                        /* Handle ThreadAbort etc */
  
!                       _ILHandleWaitResult(thread, result);
  
                        return;
***************
*** 882,897 ****
  
        /* Get the ThreadStart.Invoke method */
! 
!       if (c_ThreadStartInvokeMethod == NULL)
!       {
!               method = ILExecThreadLookupMethod(thread,
!                       "System.Threading.ThreadStart", "Invoke", "(T)V");
!               
!               c_ThreadStartInvokeMethod = method;
!       }
!       else
!       {
!               method = c_ThreadStartInvokeMethod;
!       }
  
        /* Invoke the ThreadStart delegate */
--- 923,927 ----
  
        /* Get the ThreadStart.Invoke method */
!       method = ILExecThreadLookupMethod(thread, 
"System.Threading.ThreadStart", "Invoke", "(T)V");
  
        /* Invoke the ThreadStart delegate */
***************
*** 903,908 ****
                ILExecThreadPrintException(thread);
        }
-       
-       ILThreadUnregisterForManagedExecution(thread->supportThread);
  }
  
--- 933,936 ----
***************
*** 970,974 ****
   */
  void _IL_Thread_Abort(ILExecThread *thread, ILObject *_this)
! {     
        ILThreadAbort(((System_Thread *)_this)->privateData);
  }
--- 998,1002 ----
   */
  void _IL_Thread_Abort(ILExecThread *thread, ILObject *_this)
! {
        ILThreadAbort(((System_Thread *)_this)->privateData);
  }
***************
*** 1039,1048 ****
        case IL_JOIN_ABORTED:
  
!               ILExecThreadThrowSystem
!                       (
!                               thread,
!                               "System.Threading.ThreadAbortException",
!                               (const char *)0
!                       );
  
                return 0;
--- 1067,1071 ----
        case IL_JOIN_ABORTED:
  
!               _ILAbortThread(thread);
  
                return 0;
***************
*** 1074,1078 ****
  void _IL_Thread_ResetAbort(ILExecThread *thread)
  {
!       if ((ILThreadGetState(thread->supportThread) & IL_TS_ABORT_REQUESTED) 
!= 0)
        {
                /* No abort has been requested */
--- 1097,1101 ----
  void _IL_Thread_ResetAbort(ILExecThread *thread)
  {
!       if (!thread->aborting)
        {
                /* No abort has been requested */
***************
*** 1084,1088 ****
        }
  
!       ILThreadAbortReset();
  }
  
--- 1107,1111 ----
        }
  
!       thread->aborting = 0;
  }
  
***************
*** 1152,1161 ****
                if (ILThreadStart(supportThread) == 0)
                {
!                       /* Start unsuccessful.  Destroy the support & engine 
threads */
  
-                       ((System_Thread *)_this)->privateData = 0;              
                        ILThreadUnregisterForManagedExecution(supportThread);
!                       ILThreadDestroy(supportThread);
! 
                        /* Throw an OutOfMemoryException */
  
--- 1175,1183 ----
                if (ILThreadStart(supportThread) == 0)
                {
!                       /* Start unsuccessful.  Destroy the engine thread */
!                       /* The support thread will linger as long as the CLR 
thread does */
  
                        ILThreadUnregisterForManagedExecution(supportThread);
!                       
                        /* Throw an OutOfMemoryException */
  
***************
*** 1181,1184 ****
--- 1203,1213 ----
                                                                          
ILObject *_this, ILBool value)
  {
+       if (ILThreadGetState(((System_Thread *)_this)->privateData) == 
IL_TS_STOPPED)
+       {
+               ILExecThreadThrowSystem(thread, 
"System.Threading.ThreadStateException", (const char *)0);
+ 
+               return;
+       }
+ 
        ILThreadSetBackground(((System_Thread *)_this)->privateData, value);
  }
***************
*** 1198,1207 ****
                ILExecThreadThrowSystem(thread, 
"System.Threading.ThreadStateException", (const char *)0);
  
!               return 1;
        }
-       
-       /* TODO */
  
!       return 2;       /* Normal */
  }
  
--- 1227,1234 ----
                ILExecThreadThrowSystem(thread, 
"System.Threading.ThreadStateException", (const char *)0);
  
!               return 0;
        }
  
!       return ILThreadGetPriority(supportThread);
  }
  
***************
*** 1223,1226 ****
--- 1250,1255 ----
                return;
        }
+ 
+       ILThreadSetPriority(supportThread, priority);
  }
  
***************
*** 1563,1595 ****
  }
  
  /*
   * Handle the result from an "ILWait*" function call.
   */
! static void HandleWaitResult(ILExecThread *thread, int result)
  {
!       if(result == IL_WAIT_INTERRUPTED)
        {
!               ILExecThreadThrowSystem
!                       (thread, "System.Threading.ThreadInterruptedException",
!                        (const char *)0);
!       }
!       else if(result == IL_WAIT_ABORTED)
!       {
!               /* Determine if we currently have an abort in progress,
!                  or if we need to throw a new abort exception */
!               if(ILThreadIsAborting())
                {
!                       if(ILThreadAbort(ILThreadSelf()))
!                       {
!                               /* Allocate an instance of 
"ThreadAbortException" and throw */
!                               /* TODO */
! 
!                               ILExecThreadThrowSystem
!                                       (
!                                               thread,
!                                               
"System.Threading.ThreadAbortException",
!                                               (const char *)0
!                                       );
!                       }
                }
        }
--- 1592,1642 ----
  }
  
+ void _ILAbortThread(ILExecThread *thread)
+ {
+       /* Determine if we currently have an abort in progress,
+       or if we need to throw a new abort exception */
+       if(ILThreadIsAborting())
+       {
+               if(ILThreadAbort(ILThreadSelf()))
+               {
+                       /* Allocate an instance of "ThreadAbortException" and 
throw */
+ 
+                       ILThreadAbortReset();
+                       thread->aborting = 1;
+                       _ILExecThreadThrowThreadAbortException(thread, 0);      
                
+               }
+       }
+ }
+ 
  /*
   * Handle the result from an "ILWait*" function call.
   */
! void _ILHandleWaitResult(ILExecThread *thread, int result)
  {
!       switch (result)
        {
!               case IL_WAIT_INTERRUPTED:
                {
!                       ILExecThreadThrowSystem
!                               (
!                                       thread,
!                                       
"System.Threading.ThreadInterruptedException",
!                                       (const char *)0
!                               );
!               }
!               break;
!               case IL_WAIT_ABORTED:
!               {
!                       _ILAbortThread(thread);                 
!               }
!               break;
!               case IL_WAIT_FAILED:
!               {
!                       ILExecThreadThrowSystem
!                               (
!                                       thread,
!                                       "System.Threading.SystemException",
!                                       (const char *)0
!                               );
                }
        }
***************
*** 1646,1650 ****
        if(!(waitHandles->length))
        {
!               return 1;
        }
  
--- 1693,1697 ----
        if(!(waitHandles->length))
        {
!               return 0;
        }
  
***************
*** 1657,1662 ****
        /* Perform the wait */
        result = ILWaitAll(handles, (ILUInt32)(waitHandles->length), timeout);
!       HandleWaitResult(_thread, result);
!       return (result == 0);
  }
  
--- 1704,1722 ----
        /* Perform the wait */
        result = ILWaitAll(handles, (ILUInt32)(waitHandles->length), timeout);
! 
!       if (result == IL_WAIT_TIMEOUT)
!       {
!               return exitContext;
!       }
!       else if (result < 0)
!       {
!               _ILHandleWaitResult(_thread, result);
! 
!               return 0;
!       }
!       else
!       {
!               return exitContext;
!       }
  }
  
***************
*** 1686,1701 ****
        /* Perform the wait */
        result = ILWaitAny(handles, (ILUInt32)(waitHandles->length), timeout);
-       HandleWaitResult(_thread, result);
-       /*return (result == 0);*/
-       
-       /* Now returns index of the handle that was set and proper timeout 
value */
  
        if (result == IL_WAIT_TIMEOUT)
        {
!               result = WIN32_WAIT_TIMEOUT;
        }
        else if (result < 0)
        {
!               /* TODO: FIXME: Docs don't state how to report an error! */
        }
  
--- 1746,1759 ----
        /* Perform the wait */
        result = ILWaitAny(handles, (ILUInt32)(waitHandles->length), timeout);
  
        if (result == IL_WAIT_TIMEOUT)
        {
!               result = IL_CLR_WAIT_TIMEOUT;
        }
        else if (result < 0)
        {
!               _ILHandleWaitResult(_thread, result);
! 
!               result = 0;
        }
  
***************
*** 1713,1717 ****
        {
                int result = ILWaitOne((ILWaitHandle *)privateData, timeout);
!               HandleWaitResult(_thread, result);
                return (result == 0);
        }
--- 1771,1775 ----
        {
                int result = ILWaitOne((ILWaitHandle *)privateData, timeout);
!               _ILHandleWaitResult(_thread, result);
                return (result == 0);
        }

Index: monitor.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/monitor.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -r1.3 -r1.4
*** monitor.c   26 Jun 2003 22:23:35 -0000      1.3
--- monitor.c   15 Jul 2003 22:17:33 -0000      1.4
***************
*** 41,44 ****
--- 41,46 ----
        if((monitor->supportMonitor = ILWaitMonitorCreate()) == 0)
        {
+               ILFree(monitor);
+ 
                return 0;
        }

Index: process.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/process.c,v
retrieving revision 1.53
retrieving revision 1.54
diff -C2 -r1.53 -r1.54
*** process.c   13 Jul 2003 12:41:01 -0000      1.53
--- process.c   15 Jul 2003 22:17:33 -0000      1.54
***************
*** 4,7 ****
--- 4,9 ----
   * Copyright (C) 2001  Southern Storm Software, Pty Ltd.
   *
+  * Contributions by Thong Nguyen (address@hidden)
+  *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
***************
*** 28,33 ****
  void ILExecInit(unsigned long maxSize)
  {
-       /* Tum changed init order because the GC needs threading support */
- 
        /* Initialize the thread routines */    
        ILThreadInit();
--- 30,33 ----
***************
*** 37,40 ****
--- 37,49 ----
  }
  
+ void ILExecDeinit()
+ {
+       /* Deinitialize the global garbage collector */ 
+       ILGCDeinit();   
+ 
+       /* Deinitialize the thread routines */  
+       ILThreadDeinit();       
+ }
+ 
  ILExecProcess *ILExecProcessCreate(unsigned long stackSize, unsigned long 
cachePageSize)
  {
***************
*** 51,54 ****
--- 60,64 ----
        process->firstThread = 0;
        process->mainThread = 0;
+       process->finalizerThread = 0;
  #ifdef USE_HASHING_MONITORS
        process->monitorHash = 0;
***************
*** 65,70 ****
        process->exceptionClass = 0;
        process->clrTypeClass = 0;
!       process->outOfMemoryObject = 0;
        process->commandLineObject = 0;
        ILGetCurrTime(&(process->startTime));
        process->internHash = 0;
--- 75,81 ----
        process->exceptionClass = 0;
        process->clrTypeClass = 0;
!       process->outOfMemoryObject = 0; 
        process->commandLineObject = 0;
+       process->threadAbortClass = 0;
        ILGetCurrTime(&(process->startTime));
        process->internHash = 0;
***************
*** 95,98 ****
--- 106,112 ----
        }
  
+       /* Associate the process with the context */
+       ILContextSetUserData(process->context, process);
+ 
        /* Initialize the CVM coder */
        process->coder = ILCoderCreate(&_ILCVMCoderClass, 100000, 
cachePageSize);
***************
*** 121,124 ****
--- 135,148 ----
  #endif
  
+       /* Initialize the finalization context */
+       process->finalizationContext = (ILFinalizationContext 
*)ILGCAlloc(sizeof(ILFinalizationContext));
+       if (!process->finalizationContext)
+       {
+               ILExecProcessDestroy(process);
+               return 0;
+       }
+ 
+       process->finalizationContext->process = process;
+ 
        /* Initialize the metadata lock */
        process->metadataLock = ILRWLockCreate();
***************
*** 137,140 ****
--- 161,170 ----
                return 0;
        }
+ 
+       /* If threading isn't supported, then the main thread is the finalizer 
thread */
+       if (!ILHasThreads())
+       {
+               process->finalizerThread = process->mainThread;
+       }
        
        /* Initialize the random seed pool lock */
***************
*** 150,222 ****
  }
  
  void ILExecProcessDestroy(ILExecProcess *process)
  {
!       ILExecThread *thread, *next;
!       ILExecThread *firstFinalizerThread;
  
!       /* Note: All non-finalizer threads have to be destroyed *before* 
GCDeinit
!           is called so the GC can reclaim & finalize everything on those 
threads'
!               stacks - Tum */
  
!       /* Wait for all foreground threads to finish */
!       ILThreadWaitForForegroundThreads(-1);
!       
!       /* Delete all non-finalizer threads */
  
!       firstFinalizerThread = 0;
!       thread = process->firstThread;
  
!       while (thread)
!       {
!               next = thread->nextThread;
  
!               /* Add the thread to the finalizer threads list if it is a 
finalizer thread */
!               if (thread->isFinalizerThread)
                {
!                       if (firstFinalizerThread)
                        {
!                               firstFinalizerThread->nextThread = thread;
                        }
                        else
                        {
!                               firstFinalizerThread = thread;
                        }
                }
-               else
-               {
-                       /* The thread isn't a finalizer thread so destroy it to 
free up its stack space
-                           so the finalizer can reclaim everything 
-                               Note: This is threadsafe.  There's no way the 
finalizer could run on the
-                               CLR thread while we still hold a reference to 
it */
  
!                       if (thread->clrThread)
                        {
!                               /* Null out the privateData field so the thread 
doesn't try to destroy
!                                   the ILThread twice when it finalizes */
  
!                               ((System_Thread 
*)thread->clrThread)->privateData = 0;
!                       }
  
!                       /* Destroy the support thread */
!                       ILThreadDestroy(thread->supportThread);
  
!                       /* Destroy the engine thread */
!                       _ILExecThreadDestroy(thread);
                }
  
!               thread = next;
        }
  
!       /* The only threads left in the process are finalizer threads */
!       process->firstThread = firstFinalizerThread;
  
!       /* Tell the GC we're history */ 
!       /* This performs a final collect and finalizer run and also destroy any 
finalizer threads */
!       ILGCDeinit();
  
!       /* All threads should be destroyed now */
  
!       /* Destroy the CVM coder instance */
!       ILCoderDestroy(process->coder);
  
        /* Destroy the metadata lock */
--- 180,373 ----
  }
  
+ typedef struct _tagThreadListEntry ThreadListEntry;
+ struct _tagThreadListEntry
+ {
+       ILThread *thread;
+       ThreadListEntry *next;
+ };
+ 
  void ILExecProcessDestroy(ILExecProcess *process)
  {
!       int result;
!       int mainIsFinalizer = 0;
!       ILThread *mainSupportThread;
!       ILExecThread *thread, *nextThread;      
!       ThreadListEntry *firstEntry, *entry, *next;
  
!       if (process->mainThread)
!       {
!               /* TODO: Stack still contains last frame */
!               ILMemZero(process->mainThread->stackBase, sizeof(int));
!       }
  
!       /* Delete all managed threads so the objects they used can be 
finalizerd */
!       /* Keeps deleting managed threads until they're all gone just in case
!           threads spawn new threads when they exit */
!       for (;;)
!       {                               
!               firstEntry = 0;
  
!               /* Lock down the process */
!               ILMutexLock(process->lock);
  
!               /* Walk all the threads */
!               thread = process->firstThread;
  
!               while (thread)
                {
!                       if (thread != process->finalizerThread && 
!                               /* Make sure its a managed thread */
!                               (thread->clrThread || thread == 
process->mainThread)
!                               && thread->supportThread != ILThreadSelf())
                        {
!                               /*
!                                * Instead of aborting and then waiting on each 
thread, we abort all
!                                * threads and then wait for them all at the 
bottom.  This prevents us from
!                                *      deadlocking on a thread that's waiting 
on another (not yet aborted) thread.
!                                */
! 
!                               nextThread = thread->nextThread;
! 
!                               entry = ILMalloc(sizeof(ThreadListEntry));
! 
!                               if (!entry)
!                               {
!                                       
ILExecThreadThrowOutOfMemory(ILExecThreadCurrent());
! 
!                                       return;
!                               }
! 
!                               entry->thread = thread->supportThread;
!                                                               
!                               if (!firstEntry)
!                               {
!                                       entry->next = 0;
!                                       firstEntry = entry;
!                               }
!                               else
!                               {
!                                       entry->next = firstEntry;
!                                       firstEntry = entry;
!                               }
! 
!                               /* Abort the thread */                  
!                               ILThreadAbort(thread->supportThread);
! 
!                               thread = nextThread;
! 
!                               /* Note: The CLR thread (and thus the support 
thread) might still be used
!                                       by another thread so the support thread 
is left to be destroyed by the 
!                                       CLR thread's finalizer */
                        }
                        else
                        {
!                               /* Move onto the next thread */
!                               thread = thread->nextThread;
                        }
                }
  
!               /* Unlock the process */
!               ILMutexUnlock(process->lock);
! 
!               entry = firstEntry;
! 
!               /*
!                *      Wait for the threads that have been aborted.
!                */
! 
!               if (entry)
!               {
!                       while (entry)
                        {
!                               next = entry->next;
  
!                               result = ILThreadJoin(entry->thread, -1);
! 
!                               ILFree(entry);
! 
!                               if (result != 0)
!                               {
!                                       /* The thread might be aborted while 
trying to exit */
! 
!                                       entry = next;
  
!                                       while (entry)
!                                       {
!                                               next = entry->next;
!                                               ILFree(entry);
!                                               entry = next;
!                                       }
  
!                                       
_ILHandleWaitResult(ILExecThreadCurrent(), result);
! 
!                                       return;
!                               }
! 
!                               entry = next;
!                       }
                }
+               else
+               {
+                       break;
+               }
+       }
+       
+       mainIsFinalizer = process->mainThread == process->finalizerThread;
+       mainSupportThread = process->mainThread->supportThread;
  
!       /* Destory the engine thread for the main thread if it isn't needed 
anymore.
!           This isn't strictly necessary but may help remove stray pointers on 
the CVM stack */
!       /* If the main thread is the finalizer thread, then the engine thread 
will be automatically
!           destroyed when main thread is destroyed */
!       if (!mainIsFinalizer)
!       {
!               
ILThreadUnregisterForManagedExecution(process->mainThread->supportThread);
        }
+       
+       /* Invoke the finalizers -- hopefully finalizes all objects left in the 
process being destroyed */
+       /* Any objects left lingering (because of a stray or fake pointer) are 
orphans */
+       ILGCCollect();
+       ILGCInvokeFinalizers();
+ 
+       /* We must ensure that objects created and then orphaned by this 
process won't 
+           finalize themselves from this point on (because the process will no 
longer be valid).
+               Objects can be orphaned if we're using a conservative GC like 
the Boehm GC */
+ 
+       /* Disable finalizers to ensure no finalizers are running until we 
reenable them */
+       ILGCDisableFinalizers();
+ 
+       /* Mark the process as dead in the finalization context.  This prevents 
orphans from
+           finalizing */
+       process->finalizationContext->process = 0;
  
!       /* Reenable finalizers */
!       ILGCEnableFinalizers(); 
  
!       /* Destroy the main thread if we aren't the main thread or the 
finalizer thread*/
!       if (!mainIsFinalizer && ILThreadSelf() != mainSupportThread)
!       {
!               /* Abort the thread */
!               ILThreadAbort(mainSupportThread);
  
!               /* Wait for the thread to be aborted */
!               ILThreadJoin(mainSupportThread, -1);
  
!               /* Destroy the thread object */
!               ILThreadDestroy(mainSupportThread);
!       }
!       
!       /* Destroy the finalizer thread */
!       if (process->finalizerThread)
!       {
!               /* Only destroy the engine thread.  The support thread is 
shared by other
!                   engine processes and is destroyed when the engine is 
deinitialized */
!               _ILExecThreadDestroy(process->finalizerThread);
!       }
! 
!       if (process->coder)
!       {
!               /* Destroy the CVM coder instance */
!               ILCoderDestroy(process->coder);
!       }
  
        /* Destroy the metadata lock */
***************
*** 232,242 ****
        }
  
!       /* Destroy the main part of the intern'ed hash table.
!          The rest will be cleaned up by the garbage collector */
!       ILGCFreePersistent(process->internHash);
! 
!       /* Destroy the main part of the reflection hash table.
!          The rest will be cleaned up by the garbage collector */
!       ILGCFreePersistent(process->reflectionHash);
  
  #ifdef IL_CONFIG_PINVOKE
--- 383,399 ----
        }
  
!       if (process->internHash)
!       {
!               /* Destroy the main part of the intern'ed hash table.
!               The rest will be cleaned up by the garbage collector */
!               ILGCFreePersistent(process->internHash);
!       }
! 
!       if (process->reflectionHash)
!       {
!               /* Destroy the main part of the reflection hash table.
!               The rest will be cleaned up by the garbage collector */
!               ILGCFreePersistent(process->reflectionHash);
!       }
  
  #ifdef IL_CONFIG_PINVOKE
***************
*** 282,288 ****
  #endif
  
!       /* Destroy the random seed pool */
!       ILMutexDestroy(process->randomLock);
!       ILMemZero(process->randomPool, sizeof(process->randomPool));
  
  #ifdef USE_HASHING_MONITORS
--- 439,452 ----
  #endif
  
!       if (process->randomLock)
!       {
!               /* Destroy the random seed pool */
!               ILMutexDestroy(process->randomLock);
!       }
! 
!       if (process->randomPool)
!       {
!               ILMemZero(process->randomPool, sizeof(process->randomPool));
!       }
  
  #ifdef USE_HASHING_MONITORS
***************
*** 291,302 ****
  #endif
  
!       /* Destroy the object lock */
!       ILMutexDestroy(process->lock);
  
        /* Free the process block itself */
        ILGCFreePersistent(process);
- 
-       /* Cleanup the threading subsystem */
-       ILThreadDeinit();
  }
  
--- 455,466 ----
  #endif
  
!       if (process->lock)
!       {
!               /* Destroy the object lock */
!               ILMutexDestroy(process->lock);
!       }
  
        /* Free the process block itself */
        ILGCFreePersistent(process);
  }
  
***************
*** 328,346 ****
        {
                /* If this image caused "OutOfMemoryException" to be
!                  loaded, then create an object based upon it.  We must
!                  allocate this object ahead of time because we won't be
!                  able to when the system actually runs out of memory */
                classInfo = ILClassLookupGlobal(ILImageToContext(image),
!                                                                       
"OutOfMemoryException", "System");
                if(classInfo)
                {
                        /* We don't call the "OutOfMemoryException" constructor,
!                          to avoid various circularity problems at this stage
!                          of the loading process */
                        process->outOfMemoryObject =
                                _ILEngineAllocObject(process->mainThread, 
classInfo);
                }
        }
! 
        /* Look for "System.Object" */
        if(!(process->objectClass))
--- 492,510 ----
        {
                /* If this image caused "OutOfMemoryException" to be
!               loaded, then create an object based upon it.  We must
!               allocate this object ahead of time because we won't be
!               able to when the system actually runs out of memory */
                classInfo = ILClassLookupGlobal(ILImageToContext(image),
!                       "OutOfMemoryException", "System");
                if(classInfo)
                {
                        /* We don't call the "OutOfMemoryException" constructor,
!                       to avoid various circularity problems at this stage
!                       of the loading process */
                        process->outOfMemoryObject =
                                _ILEngineAllocObject(process->mainThread, 
classInfo);
                }
        }
!       
        /* Look for "System.Object" */
        if(!(process->objectClass))
***************
*** 369,372 ****
--- 533,543 ----
                process->clrTypeClass = 
ILClassLookupGlobal(ILImageToContext(image),
                                                                        
"ClrType", "System.Reflection");
+       }
+ 
+       /* Look for "System.Threading.ThreadAbortException" */
+       if(!(process->threadAbortClass))
+       {
+               process->threadAbortClass = 
ILClassLookupGlobal(ILImageToContext(image),
+                       "ThreadAbortException", "System.Threading");
        }
  }

Index: thread.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/thread.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -r1.21 -r1.22
*** thread.c    9 Jul 2003 06:58:23 -0000       1.21
--- thread.c    15 Jul 2003 22:17:33 -0000      1.22
***************
*** 70,73 ****
--- 70,89 ----
  
  /*
+  *    Makes the given support thread execute in the context of the given 
engine thread.
+  */
+ void _ILThreadExecuteOn(ILThread *thread, ILExecThread *execThread)
+ {
+       ILThreadSetObject(thread, execThread);
+ }
+ 
+ /*
+  *    Cleanup handler for threads that have been registered for managed 
execution.
+  */
+ static void ILExecThreadCleanup(ILThread *thread)
+ {
+       ILThreadUnregisterForManagedExecution(thread);
+ }
+ 
+ /*
   *    Registers a thread for managed execution
   */
***************
*** 76,88 ****
        ILExecThread *execThread;
  
        /* Create a new engine-level thread */  
!       execThread = _ILExecThreadCreate(process);
  
        /* Associate the new engine-level thread with the OS-level thread */
!       ILThreadSetObject(thread, execThread);
  
        /* Associate the OS-level thread with the new engine-level thread */
        execThread->supportThread = thread;
  
        return execThread;
  }
--- 92,116 ----
        ILExecThread *execThread;
  
+       /* If the thread has already been registerered then return the existing 
engine thread */
+       if ((execThread = ILThreadGetObject(thread)) != 0)
+       {
+               return execThread;
+       }
+ 
        /* Create a new engine-level thread */  
!       if ((execThread = _ILExecThreadCreate(process)) == 0)
!       {
!               return 0;
!       }
  
        /* Associate the new engine-level thread with the OS-level thread */
!       _ILThreadExecuteOn(thread, execThread);
  
        /* Associate the OS-level thread with the new engine-level thread */
        execThread->supportThread = thread;
  
+       /* Register a cleanup handler for the thread */
+       ILThreadRegisterCleanup(thread, ILExecThreadCleanup);
+ 
        return execThread;
  }
***************
*** 95,100 ****
--- 123,142 ----
        ILExecThread *execThread;
  
+       /* Get the engine thread from the support thread */
        execThread = ILThreadGetObject(thread);
  
+       if (execThread == 0)
+       {
+               /* Already unregistered */
+               return;
+       }
+ 
+       /* Unregister the cleanup handler */
+       ILThreadUnregisterCleanup(thread, ILExecThreadCleanup);
+ 
+       /* Disassociate the engine thread with the support thread */
+       _ILThreadExecuteOn(thread, 0);
+ 
+       /* Destroy the engine thread */
        _ILExecThreadDestroy(execThread);
  }
***************
*** 134,137 ****
--- 176,180 ----
        /* Initialize the thread state */
        thread->supportThread = 0;
+       thread->aborting = 0;
        thread->clrThread = 0;  
        thread->freeMonitor = 0;        
***************
*** 141,145 ****
        thread->stackTop = thread->stackBase;
        thread->method = 0;
!       thread->thrownException = 0;
        thread->securityManager = 0;
        thread->threadStaticSlots = 0;
--- 184,188 ----
        thread->stackTop = thread->stackBase;
        thread->method = 0;
!       thread->thrownException = 0;    
        thread->securityManager = 0;
        thread->threadStaticSlots = 0;
***************
*** 175,178 ****
--- 218,226 ----
        {
                process->mainThread = 0;
+       }
+ 
+       if (process->finalizerThread == thread)
+       {
+               process->finalizerThread = 0;
        }
  

Index: throw.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/engine/throw.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -r1.6 -r1.7
*** throw.c     26 Jun 2003 10:34:51 -0000      1.6
--- throw.c     15 Jul 2003 22:17:33 -0000      1.7
***************
*** 191,195 ****
        }
  }
- 
  void ILExecThreadThrowOutOfMemory(ILExecThread *thread)
  {
--- 191,194 ----
***************
*** 200,203 ****
--- 199,222 ----
  }
  
+ void _ILExecThreadThrowThreadAbortException(ILExecThread *thread, ILObject 
*stateInfo)
+ {
+       ILObject *object;
+ 
+       /* Bail out if there already is a pending exception */
+       if(ILExecThreadHasException(thread))
+       {
+               return;
+       }
+ 
+       object = ILExecThreadNew(thread, 
"System.Threading.ThreadAbortException",
+                                               "(ToSystem.Object;)V", 
stateInfo);
+       
+       _ILSetExceptionStackTrace(thread, object);
+       if(!ILExecThreadHasException(thread))
+       {
+               ILExecThreadSetException(thread, object);
+       }
+ }
+ 
  void ILExecThreadPrintException(ILExecThread *thread)
  {
***************
*** 229,235 ****
        }
  
        /* Attempt to use "ToString" to format the exception, but not
           if we know that the exception is reporting out of memory */
!       if(exception != thread->process->outOfMemoryObject)
        {
                str = ILObjectToString(thread, exception);
--- 248,263 ----
        }
  
+       /*
+        *      Don't print out ThreadAbortExceptions.
+        */
+ 
+       if (GetObjectClass(exception) == thread->process->threadAbortClass)
+       {
+               return;
+       }
+ 
        /* Attempt to use "ToString" to format the exception, but not
           if we know that the exception is reporting out of memory */
!       if(exception != thread->process->outOfMemoryObject)             
        {
                str = ILObjectToString(thread, exception);





reply via email to

[Prev in Thread] Current Thread [Next in Thread]