1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5
6/*============================================================
7**
8** Header: COMSynchronizable.h
9**
10** Purpose: Native methods on System.SynchronizableObject
11** and its subclasses.
12**
13**
14===========================================================*/
15
16#ifndef _COMSYNCHRONIZABLE_H
17#define _COMSYNCHRONIZABLE_H
18
19#include "field.h" // For FieldDesc definition.
20
21//
22// Each function that we call through native only gets one argument,
23// which is actually a pointer to its stack of arguments. Our structs
24// for accessing these are defined below.
25//
26
27struct SharedState;
28
29class ThreadNative
30{
31friend class ThreadBaseObject;
32
33public:
34
35 enum
36 {
37 PRIORITY_LOWEST = 0,
38 PRIORITY_BELOW_NORMAL = 1,
39 PRIORITY_NORMAL = 2,
40 PRIORITY_ABOVE_NORMAL = 3,
41 PRIORITY_HIGHEST = 4,
42 };
43
44 enum
45 {
46 ThreadStopRequested = 1,
47 ThreadSuspendRequested = 2,
48 ThreadBackground = 4,
49 ThreadUnstarted = 8,
50 ThreadStopped = 16,
51 ThreadWaitSleepJoin = 32,
52 ThreadSuspended = 64,
53 ThreadAbortRequested = 128,
54 ThreadAborted = 256,
55 };
56
57 enum
58 {
59 ApartmentSTA = 0,
60 ApartmentMTA = 1,
61 ApartmentUnknown = 2
62 };
63
64 static void StartInner(ThreadBaseObject* pThisUNSAFE);
65
66 static FCDECL1(void, Abort, ThreadBaseObject* pThis);
67 static FCDECL1(void, ResetAbort, ThreadBaseObject* pThis);
68 static FCDECL1(void, Start, ThreadBaseObject* pThisUNSAFE);
69 static FCDECL1(INT32, GetPriority, ThreadBaseObject* pThisUNSAFE);
70 static FCDECL2(void, SetPriority, ThreadBaseObject* pThisUNSAFE, INT32 iPriority);
71 static FCDECL1(void, Interrupt, ThreadBaseObject* pThisUNSAFE);
72 static FCDECL1(FC_BOOL_RET, IsAlive, ThreadBaseObject* pThisUNSAFE);
73 static FCDECL2(FC_BOOL_RET, Join, ThreadBaseObject* pThisUNSAFE, INT32 Timeout);
74#undef Sleep
75 static FCDECL1(void, Sleep, INT32 iTime);
76#define Sleep(a) Dont_Use_Sleep(a)
77 static FCDECL3(void, SetStart, ThreadBaseObject* pThisUNSAFE, Object* pDelegateUNSAFE, INT32 iRequestedStackSize);
78 static FCDECL2(void, SetBackground, ThreadBaseObject* pThisUNSAFE, CLR_BOOL isBackground);
79 static FCDECL1(FC_BOOL_RET, IsBackground, ThreadBaseObject* pThisUNSAFE);
80 static FCDECL1(INT32, GetThreadState, ThreadBaseObject* pThisUNSAFE);
81 static FCDECL1(INT32, GetThreadContext, ThreadBaseObject* pThisUNSAFE);
82#ifdef FEATURE_COMINTEROP_APARTMENT_SUPPORT
83 static FCDECL1(INT32, GetApartmentState, ThreadBaseObject* pThis);
84 static FCDECL3(INT32, SetApartmentState, ThreadBaseObject* pThisUNSAFE, INT32 iState, CLR_BOOL fireMDAOnMismatch);
85 static FCDECL1(void, StartupSetApartmentState, ThreadBaseObject* pThis);
86#endif // FEATURE_COMINTEROP_APARTMENT_SUPPORT
87
88 static
89 void QCALLTYPE InformThreadNameChange(QCall::ThreadHandle thread, LPCWSTR name, INT32 len);
90
91 static
92 UINT64 QCALLTYPE GetProcessDefaultStackSize();
93
94 static FCDECL1(INT32, GetManagedThreadId, ThreadBaseObject* th);
95 static INT32 QCALLTYPE GetOptimalMaxSpinWaitsPerSpinIteration();
96 static FCDECL1(void, SpinWait, int iterations);
97 static BOOL QCALLTYPE YieldThread();
98 static FCDECL0(Object*, GetCurrentThread);
99 static UINT64 QCALLTYPE GetCurrentOSThreadId();
100 static FCDECL1(void, Finalize, ThreadBaseObject* pThis);
101#ifdef FEATURE_COMINTEROP
102 static FCDECL1(void, DisableComObjectEagerCleanup, ThreadBaseObject* pThis);
103#endif //FEATURE_COMINTEROP
104 static FCDECL1(FC_BOOL_RET,IsThreadpoolThread, ThreadBaseObject* thread);
105
106 static FCDECL2(void, SetAbortReason, ThreadBaseObject* pThisUNSAFE, Object* pObject);
107 static FCDECL1(void, ClearAbortReason, ThreadBaseObject* pThisUNSAFE);
108
109 static FCDECL0(INT32, GetCurrentProcessorNumber);
110
111private:
112
113 struct KickOffThread_Args {
114 Thread *pThread;
115 SharedState *share;
116 ULONG retVal;
117 };
118
119 static void KickOffThread_Worker(LPVOID /* KickOffThread_Args* */);
120 static ULONG WINAPI KickOffThread(void *pass);
121 static BOOL DoJoin(THREADBASEREF DyingThread, INT32 timeout);
122};
123
124
125#endif // _COMSYNCHRONIZABLE_H
126
127