@@ -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" UINT64 QCALLTYPE 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" INT32 QCALLTYPE 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