@@ -362,63 +362,17 @@ extern "C" void QCALLTYPE ThreadNative_SetPriority(QCall::ObjectHandleOnStack th
362362    END_QCALL;
363363}
364364
365- FCIMPL1 (FC_BOOL_RET, ThreadNative::IsAlive, ThreadBaseObject* pThisUNSAFE )
365+ extern   " C "   void  QCALLTYPE  ThreadNative_GetCurrentThread (QCall::ObjectHandleOnStack thread )
366366{
367-     FCALL_CONTRACT;
368- 
369-     if  (pThisUNSAFE==NULL )
370-         FCThrowRes (kNullReferenceException , W (" NullReference_This" 
371- 
372-     THREADBASEREF thisRef (pThisUNSAFE);
373-     BOOL ret = false ;
374- 
375-     //  Keep managed Thread object alive, since the native object's
376-     //  lifetime is tied to the managed object's finalizer.  And with
377-     //  resurrection, it may be possible to get a dangling pointer here -
378-     //  consider both protecting thisRef and setting the managed object's
379-     //  Thread* to NULL in the GC's ScanForFinalization method.
380-     HELPER_METHOD_FRAME_BEGIN_RET_1 (thisRef);
381- 
382-     Thread  *thread = thisRef->GetInternal ();
383- 
384-     if  (thread == 0 )
385-         COMPlusThrow (kThreadStateException , IDS_EE_THREAD_CANNOT_GET);
386- 
387-     ret = ThreadIsRunning (thread);
388- 
389-     HELPER_METHOD_POLL ();
390-     HELPER_METHOD_FRAME_END ();
391- 
392-     FC_RETURN_BOOL (ret);
393- }
394- FCIMPLEND
395- 
396- NOINLINE static  Object* GetCurrentThreadHelper ()
397- {
398-     FCALL_CONTRACT;
399-     FC_INNER_PROLOG (ThreadNative::GetCurrentThread);
400-     OBJECTREF   refRetVal  = NULL ;
401- 
402-     HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_1 (Frame::FRAME_ATTR_EXACT_DEPTH|Frame::FRAME_ATTR_CAPTURE_DEPTH_2, refRetVal);
403-     refRetVal = GetThread ()->GetExposedObject ();
404-     HELPER_METHOD_FRAME_END ();
367+     QCALL_CONTRACT;
405368
406-     FC_INNER_EPILOG ();
407-     return  OBJECTREFToObject (refRetVal);
408- }
369+     BEGIN_QCALL;
409370
410- FCIMPL0 (Object*, ThreadNative::GetCurrentThread)
411- {
412-     FCALL_CONTRACT;
413-     OBJECTHANDLE ExposedObject = GetThread ()->m_ExposedObject ;
414-     _ASSERTE (ExposedObject != 0 ); // Thread's constructor always initializes its GCHandle
415-     Object* result = *((Object**) ExposedObject);
416-     if  (result != 0 )
417-         return  result;
371+     GCX_COOP ();
372+     thread.Set (GetThread ()->GetExposedObject ());
418373
419-     FC_INNER_RETURN (Object*,  GetCurrentThreadHelper ()) ;
374+     END_QCALL ;
420375}
421- FCIMPLEND
422376
423377extern  " C" ThreadNative_GetCurrentOSThreadId ()
424378{
@@ -442,33 +396,36 @@ extern "C" UINT64 QCALLTYPE ThreadNative_GetCurrentOSThreadId()
442396    return  threadId;
443397}
444398
445- FCIMPL1 ( void , ThreadNative::Initialize, ThreadBaseObject* pThisUNSAFE )
399+ extern   " C "   void  QCALLTYPE  ThreadNative_Initialize (QCall::ObjectHandleOnStack t )
446400{
447-     FCALL_CONTRACT ;
401+     QCALL_CONTRACT ;
448402
449-     THREADBASEREF   pThis       = (THREADBASEREF) pThisUNSAFE ;
403+     BEGIN_QCALL ;
450404
451-     HELPER_METHOD_FRAME_BEGIN_1 (pThis);
405+     GCX_COOP ();
406+ 
407+     THREADBASEREF threadRef = NULL ;
408+     GCPROTECT_BEGIN (threadRef)
409+     threadRef = (THREADBASEREF)t.Get ();
452410
453-     _ASSERTE (pThis  != NULL );
454-     _ASSERTE (pThis-> m_InternalThread  == NULL );
411+     _ASSERTE (threadRef  != NULL );
412+     _ASSERTE (threadRef-> GetInternal ()  == NULL );
455413
456414    //  if we don't have an internal Thread object associated with this exposed object,
457415    //  now is our first opportunity to create one.
458-     Thread      *unstarted = SetupUnstartedThread ();
459- 
416+     Thread* unstarted = SetupUnstartedThread ();
460417    PREFIX_ASSUME (unstarted != NULL );
461418
462-     pThis ->SetInternal (unstarted);
463-     pThis ->SetManagedThreadId (unstarted->GetThreadId ());
464-     unstarted->SetExposedObject (pThis );
419+     threadRef ->SetInternal (unstarted);
420+     threadRef ->SetManagedThreadId (unstarted->GetThreadId ());
421+     unstarted->SetExposedObject (threadRef );
465422
466423    //  Initialize the thread priority to normal.
467-     pThis ->SetPriority (ThreadNative::PRIORITY_NORMAL);
424+     threadRef ->SetPriority (ThreadNative::PRIORITY_NORMAL);
468425
469-     HELPER_METHOD_FRAME_END ();
426+     GCPROTECT_END ();
427+     END_QCALL;
470428}
471- FCIMPLEND
472429
473430//  Return whether or not this is a background thread.
474431FCIMPL1 (FC_BOOL_RET, ThreadNative::GetIsBackground, ThreadBaseObject* pThisUNSAFE)
@@ -489,57 +446,43 @@ FCIMPL1(FC_BOOL_RET, ThreadNative::GetIsBackground, ThreadBaseObject* pThisUNSAF
489446FCIMPLEND
490447
491448//  Deliver the state of the thread as a consistent set of bits.
492- //  This copied in VM\EEDbgInterfaceImpl.h's
493- //      CorDebugUserState GetUserState( Thread *pThread )
494- //  , so propagate changes to both functions
495- FCIMPL1 (INT32, ThreadNative::GetThreadState, ThreadBaseObject* pThisUNSAFE)
449+ //  Duplicate logic in DacDbiInterfaceImpl::GetPartialUserState()
450+ extern  " C" ThreadNative_GetThreadState (QCall::ThreadHandle thread)
496451{
497-     FCALL_CONTRACT;
498- 
499-     INT32               res = 0 ;
500-     Thread::ThreadState state;
501- 
502-     if  (pThisUNSAFE==NULL )
503-         FCThrowRes (kNullReferenceException , W (" NullReference_This" 
504- 
505-     //  validate the thread.  Failure here implies that the thread was finalized
506-     //  and then resurrected.
507-     Thread  *thread = pThisUNSAFE->GetInternal ();
508- 
509-     if  (!thread)
510-         FCThrowEx (kThreadStateException , IDS_EE_THREAD_CANNOT_GET, NULL , NULL , NULL );
452+     CONTRACTL
453+     {
454+         QCALL_CHECK_NO_GC_TRANSITION;
455+         PRECONDITION (thread != NULL );
456+     }
457+     CONTRACTL_END;
511458
512-     HELPER_METHOD_FRAME_BEGIN_RET_0 () ;
459+     INT32 res =  0 ;
513460
514461    //  grab a snapshot
515-     state = thread->GetSnapshotState ();
462+     Thread::ThreadState  state = thread->GetSnapshotState ();
516463
517464    if  (state & Thread::TS_Background)
518-         res |= ThreadBackground;
465+         res |= ThreadNative:: ThreadBackground;
519466
520467    if  (state & Thread::TS_Unstarted)
521-         res |= ThreadUnstarted;
468+         res |= ThreadNative:: ThreadUnstarted;
522469
523470    //  Don't report a StopRequested if the thread has actually stopped.
524471    if  (state & Thread::TS_Dead)
525472    {
526-         res |= ThreadStopped;
473+         res |= ThreadNative:: ThreadStopped;
527474    }
528475    else 
529476    {
530477        if  (state & Thread::TS_AbortRequested)
531-             res |= ThreadAbortRequested;
478+             res |= ThreadNative:: ThreadAbortRequested;
532479    }
533480
534481    if  (state & Thread::TS_Interruptible)
535-         res |= ThreadWaitSleepJoin;
536- 
537-     HELPER_METHOD_POLL ();
538-     HELPER_METHOD_FRAME_END ();
482+         res |= ThreadNative::ThreadWaitSleepJoin;
539483
540484    return  res;
541485}
542- FCIMPLEND
543486
544487#ifdef  FEATURE_COMINTEROP_APARTMENT_SUPPORT
545488
@@ -942,16 +885,12 @@ extern "C" void QCALLTYPE ThreadNative_DisableComObjectEagerCleanup(QCall::Threa
942885{
943886    CONTRACTL
944887    {
945-         QCALL_CHECK ;
888+         QCALL_CHECK_NO_GC_TRANSITION ;
946889        PRECONDITION (thread != NULL );
947890    }
948891    CONTRACTL_END;
949892
950-     BEGIN_QCALL;
951- 
952893    thread->SetDisableComObjectEagerCleanup ();
953- 
954-     END_QCALL;
955894}
956895#endif  // FEATURE_COMINTEROP
957896
0 commit comments