Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

390 lines
6.2 KiB

4 years ago
  1. /* --------------------------------------------------------------------
  2. Microsoft OS/2 LAN Manager
  3. Copyright(c) Microsoft Corp., 1990
  4. -------------------------------------------------------------------- */
  5. /* --------------------------------------------------------------------
  6. File: threads.hxx
  7. Description:
  8. This file provides a system independent threads package.
  9. History:
  10. mikemon 05/24/90 File created.
  11. mikemon 10/15/90 Added the PauseExecution entry point.
  12. -------------------------------------------------------------------- */
  13. #ifndef __THREADS__
  14. #define __THREADS__
  15. #include "interlck.hxx"
  16. typedef void
  17. (*THREAD_PROC) (
  18. void * Parameter
  19. );
  20. #ifdef DOSWIN32RPC
  21. typedef DWORD THREAD_IDENTIFIER;
  22. #else // DOSWIN32RPC
  23. typedef HANDLE THREAD_IDENTIFIER;
  24. #endif // DOSWIN32RPC
  25. class THREAD
  26. {
  27. private:
  28. void * HandleToThread;
  29. void * Context;
  30. void * SharedMemoryProtocol;
  31. THREAD_PROC SavedProcedure;
  32. void * SavedParameter;
  33. INTERLOCKED_INTEGER ProtectCount;
  34. public:
  35. unsigned long TimeLow;
  36. long CancelTimeout; // seconds. Default=RPC_C_CANCEL_INFINITE_TIMEOUT.
  37. void __RPC_FAR * ServerContextList;
  38. void * SecurityContext;
  39. long ImpersonatingClient;
  40. unsigned Slot ;
  41. #ifdef NTENV
  42. HANDLE hThreadEvent;
  43. #endif
  44. // Construct a new thread which will execute the procedure specified, taking
  45. // Param as the argument.
  46. THREAD (
  47. IN THREAD_PROC Procedure,
  48. IN void * Parameter,
  49. OUT RPC_STATUS * RpcStatus
  50. );
  51. THREAD (
  52. OUT RPC_STATUS * RpcStatus
  53. );
  54. ~THREAD (
  55. );
  56. void
  57. StartRoutine (
  58. ) {(*SavedProcedure)(SavedParameter);}
  59. void *
  60. ThreadHandle (
  61. );
  62. friend THREAD * ThreadSelf();
  63. friend void **ThreadSharedMemoryContext();
  64. friend void * RpcpGetThreadContext();
  65. friend void RpcpSetThreadContext(void * Context);
  66. void
  67. ProtectThread (
  68. );
  69. void
  70. UnprotectThread (
  71. );
  72. long
  73. InqProtectCount (
  74. );
  75. };
  76. inline void
  77. THREAD::ProtectThread (
  78. )
  79. /*++
  80. Routine Description:
  81. This thread needs to be protected from deletion. We just need to
  82. increment the protect count.
  83. --*/
  84. {
  85. ProtectCount.Increment();
  86. }
  87. inline void
  88. THREAD::UnprotectThread (
  89. )
  90. /*++
  91. Routine Description:
  92. This thread no longer needs to be protected from deletion. As a
  93. result, we can decrement the protect count by one.
  94. --*/
  95. {
  96. ProtectCount.Decrement();
  97. }
  98. inline long
  99. THREAD::InqProtectCount (
  100. )
  101. /*++
  102. Return Value:
  103. The protect count for this thread is returned; a value of zero indicates
  104. that it is safe to delete this thread.
  105. --*/
  106. {
  107. return(ProtectCount.GetInteger());
  108. }
  109. extern THREAD_IDENTIFIER
  110. GetThreadIdentifier (
  111. );
  112. extern void PauseExecution(unsigned long time);
  113. // This class represents a dynamic link library. When it is constructed,
  114. // the dll is loaded, and when it is destructed, the dll is unloaded.
  115. // The only operation is obtaining the address of an entry point into
  116. // the dll.
  117. class DLL
  118. {
  119. private:
  120. void * DllHandle;
  121. public:
  122. DLL (
  123. IN RPC_CHAR * DllName,
  124. OUT RPC_STATUS * Status
  125. );
  126. ~DLL (
  127. );
  128. void *
  129. GetEntryPoint (
  130. IN char * Procedure
  131. );
  132. };
  133. extern int
  134. InitializeThreads (
  135. );
  136. extern RPC_STATUS
  137. SetThreadStackSize (
  138. IN unsigned long ThreadStackSize
  139. );
  140. #define HIGHBITSET (0x80000000)
  141. #define MAXINTERNALCANCELTIMEOUT (0x7FFFFFFF)
  142. extern long
  143. ThreadGetRpcCancelTimeout(
  144. );
  145. extern void
  146. ThreadSetRpcCancelTimeout(
  147. long Timeout
  148. );
  149. class ACTIVE_THREAD_DICT
  150. {
  151. public:
  152. ACTIVE_THREAD_DICT(
  153. RPC_STATUS * pStatus
  154. )
  155. {
  156. Size = 8;
  157. Data = new THREAD_CALL_INFO[Size];
  158. if (!Data)
  159. {
  160. *pStatus = RPC_S_OUT_OF_MEMORY;
  161. return;
  162. }
  163. memset(Data,
  164. 0,
  165. Size * sizeof(THREAD_CALL_INFO)
  166. );
  167. }
  168. ~ACTIVE_THREAD_DICT(
  169. )
  170. {
  171. delete Data;
  172. }
  173. unsigned
  174. RegisterThread(
  175. unsigned long ThreadId,
  176. CONNECTION * Connection,
  177. unsigned PreviousSlot
  178. );
  179. CONNECTION *
  180. UnregisterThread(
  181. unsigned Index
  182. );
  183. void *
  184. ACTIVE_THREAD_DICT::Find(
  185. unsigned long ThreadId
  186. );
  187. unsigned
  188. HashThreadId(
  189. unsigned long Id
  190. )
  191. {
  192. unsigned Low = Id % 0x10000;
  193. unsigned High = Id / 0x10000;
  194. return (Low ^ High) % Size;
  195. }
  196. private:
  197. struct THREAD_CALL_INFO
  198. {
  199. unsigned long ThreadId;
  200. CONNECTION * Connection;
  201. };
  202. unsigned Size;
  203. THREAD_CALL_INFO * Data;
  204. };
  205. RPC_STATUS
  206. RegisterForCancels(
  207. CONNECTION * Conn
  208. );
  209. RPC_STATUS
  210. UnregisterForCancels(
  211. );
  212. unsigned
  213. RpcpThreadTestCancel(
  214. );
  215. RPC_STATUS
  216. RpcpThreadCancel(
  217. void * ThreadHandle
  218. );
  219. #ifdef DOSWIN32RPC
  220. extern unsigned long RpcTlsIndex;
  221. inline THREAD *
  222. RpcpGetThreadPointer(
  223. )
  224. {
  225. return (THREAD *) TlsGetValue(RpcTlsIndex);
  226. }
  227. inline void
  228. RpcpSetThreadPointer(
  229. THREAD * Thread
  230. )
  231. {
  232. TlsSetValue(RpcTlsIndex, Thread);
  233. }
  234. inline THREAD_IDENTIFIER
  235. GetThreadIdentifier (
  236. )
  237. {
  238. return(GetCurrentThreadId());
  239. }
  240. #elif NTENV
  241. inline THREAD *
  242. RpcpGetThreadPointer(
  243. )
  244. {
  245. return (THREAD *) NtCurrentTeb()->ReservedForNtRpc;
  246. }
  247. inline void
  248. RpcpSetThreadPointer(
  249. THREAD * Thread
  250. )
  251. {
  252. NtCurrentTeb()->ReservedForNtRpc = Thread;
  253. }
  254. inline THREAD_IDENTIFIER
  255. GetThreadIdentifier (
  256. )
  257. {
  258. return(NtCurrentTeb()->ClientId.UniqueThread);
  259. }
  260. #endif
  261. inline void *
  262. RpcpGetThreadContext (
  263. )
  264. {
  265. THREAD * Thread = RpcpGetThreadPointer();
  266. if ( Thread == 0 || ((unsigned long) Thread & HIGHBITSET))
  267. {
  268. return(0);
  269. }
  270. return(Thread->Context);
  271. }
  272. inline void
  273. RpcpSetThreadContext (
  274. void * Context
  275. )
  276. {
  277. RpcpGetThreadPointer()->Context = Context;
  278. }
  279. inline
  280. void RpcpSetThisCallSecurityContext (
  281. void * SecurityContext
  282. )
  283. {
  284. RpcpGetThreadPointer()->SecurityContext = SecurityContext;
  285. }
  286. inline
  287. void RpcpSetCallImpersonatedFlag (
  288. long Flag
  289. )
  290. {
  291. RpcpGetThreadPointer()->ImpersonatingClient = Flag;
  292. }
  293. #endif // __THREADS__