Source code of Windows XP (NT5)
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.

366 lines
7.9 KiB

  1. /*++
  2. Copyright (c) 1989 Microsoft Corporation
  3. Module Name:
  4. thread.c
  5. Abstract:
  6. This module implements verification functions for thread interfaces.
  7. Author:
  8. Silviu Calinoiu (SilviuC) 22-Feb-2001
  9. Revision History:
  10. --*/
  11. #include "pch.h"
  12. #include "verifier.h"
  13. #include "support.h"
  14. //WINBASEAPI
  15. DECLSPEC_NORETURN
  16. VOID
  17. WINAPI
  18. AVrfpExitThread(
  19. IN DWORD dwExitCode
  20. )
  21. {
  22. typedef VOID (WINAPI * FUNCTION_TYPE) (DWORD);
  23. FUNCTION_TYPE Function;
  24. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  25. AVRF_INDEX_KERNEL32_EXITTHREAD);
  26. //
  27. // Checking for orphaned locks is a no op if lock verifier
  28. // is not enabled.
  29. //
  30. RtlCheckForOrphanedCriticalSections(NtCurrentThread());
  31. //
  32. // Perform all typical checks for a thread that will exit.
  33. //
  34. AVrfpCheckThreadTermination ();
  35. //
  36. // Call the real thing.
  37. //
  38. (* Function)(dwExitCode);
  39. }
  40. //WINBASEAPI
  41. BOOL
  42. WINAPI
  43. AVrfpTerminateThread(
  44. IN OUT HANDLE hThread,
  45. IN DWORD dwExitCode
  46. )
  47. {
  48. typedef BOOL (WINAPI * FUNCTION_TYPE) (HANDLE, DWORD);
  49. FUNCTION_TYPE Function;
  50. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  51. AVRF_INDEX_KERNEL32_TERMINATETHREAD);
  52. //
  53. // Checking for orphaned locks is a no op if lock verifier
  54. // is not enabled.
  55. //
  56. RtlCheckForOrphanedCriticalSections(hThread);
  57. //
  58. // This API should not be called. We need to report this.
  59. // This is useful if we did not detect any orphans but we still want
  60. // to complain.
  61. //
  62. VERIFIER_STOP (APPLICATION_VERIFIER_TERMINATE_THREAD_CALL,
  63. "TerminateThread() called. This function should not be used.",
  64. NtCurrentTeb()->ClientId.UniqueProcess, "Caller thread ID",
  65. 0, NULL, 0, NULL, 0, NULL);
  66. return (* Function)(hThread, dwExitCode);
  67. }
  68. //WINBASEAPI
  69. DWORD
  70. WINAPI
  71. AVrfpSuspendThread(
  72. IN HANDLE hThread
  73. )
  74. {
  75. typedef DWORD (WINAPI * FUNCTION_TYPE) (HANDLE);
  76. FUNCTION_TYPE Function;
  77. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  78. AVRF_INDEX_KERNEL32_SUSPENDTHREAD);
  79. //
  80. // Checking for orphaned locks is a no op if lock verifier
  81. // is not enabled.
  82. //
  83. // SilviuC: disabled this check for now because java VM and others
  84. // might do this in valid conditions.
  85. //
  86. // RtlCheckForOrphanedCriticalSections(hThread);
  87. //
  88. return (* Function)(hThread);
  89. }
  90. //WINBASEAPI
  91. HANDLE
  92. WINAPI
  93. AVrfpCreateThread(
  94. IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
  95. IN SIZE_T dwStackSize,
  96. IN LPTHREAD_START_ROUTINE lpStartAddress,
  97. IN LPVOID lpParameter,
  98. IN DWORD dwCreationFlags,
  99. OUT LPDWORD lpThreadId
  100. )
  101. {
  102. typedef HANDLE (WINAPI * FUNCTION_TYPE) (LPSECURITY_ATTRIBUTES,
  103. SIZE_T,
  104. LPTHREAD_START_ROUTINE,
  105. LPVOID,
  106. DWORD,
  107. LPDWORD);
  108. FUNCTION_TYPE Function;
  109. HANDLE Result;
  110. DWORD ThreadId;
  111. PAVRF_THREAD_INFO Info;
  112. Function = AVRFP_GET_ORIGINAL_EXPORT (AVrfpKernel32Thunks,
  113. AVRF_INDEX_KERNEL32_CREATETHREAD);
  114. Info = RtlAllocateHeap (RtlProcessHeap(), 0, sizeof *Info);
  115. if (Info == NULL) {
  116. NtCurrentTeb()->LastErrorValue = ERROR_OUTOFMEMORY;
  117. return NULL;
  118. }
  119. Info->Parameter = lpParameter;
  120. Info->Function = lpStartAddress;
  121. Result = (* Function) (lpThreadAttributes,
  122. dwStackSize,
  123. AVrfpStandardThreadFunction,
  124. (PVOID)Info,
  125. dwCreationFlags,
  126. lpThreadId);
  127. return Result;
  128. }
  129. /////////////////////////////////////////////////////////////////////
  130. /////////////////////////////////////////////////// Thread pool hooks
  131. /////////////////////////////////////////////////////////////////////
  132. typedef struct _AVRF_WORKER_INFO {
  133. WORKERCALLBACKFUNC Function;
  134. PVOID Context;
  135. } AVRF_WORKER_INFO, * PAVRF_WORKER_INFO;
  136. typedef struct _AVRF_WAIT_INFO {
  137. WAITORTIMERCALLBACKFUNC Function;
  138. PVOID Context;
  139. } AVRF_WAIT_INFO, * PAVRF_WAIT_INFO;
  140. ULONG
  141. AVrfpWorkerFunctionExceptionFilter (
  142. ULONG ExceptionCode,
  143. PVOID ExceptionRecord
  144. )
  145. {
  146. VERIFIER_STOP (APPLICATION_VERIFIER_UNEXPECTED_EXCEPTION,
  147. "unexpected exception raised in worker thread",
  148. ExceptionCode, "Exception code",
  149. ExceptionRecord, "Exception record (.exr on 1st word, .cxr on 2nd word)",
  150. 0, "",
  151. 0, "");
  152. return EXCEPTION_EXECUTE_HANDLER;
  153. }
  154. VOID
  155. NTAPI
  156. AVrfpStandardWorkerCallback (
  157. PVOID Context
  158. )
  159. {
  160. PAVRF_WORKER_INFO Info = (PAVRF_WORKER_INFO)Context;
  161. try {
  162. //
  163. // Call the real thing.
  164. //
  165. (Info->Function)(Info->Context);
  166. }
  167. except (AVrfpWorkerFunctionExceptionFilter (_exception_code(), _exception_info())) {
  168. //
  169. // Nothing.
  170. //
  171. }
  172. RtlCheckForOrphanedCriticalSections (NtCurrentThread());
  173. RtlFreeHeap (RtlProcessHeap(), 0, Info);
  174. }
  175. VOID
  176. NTAPI
  177. AVrfpStandardWaitCallback (
  178. PVOID Context,
  179. BOOLEAN Value
  180. )
  181. {
  182. PAVRF_WAIT_INFO Info = (PAVRF_WAIT_INFO)Context;
  183. try {
  184. //
  185. // Call the real thing.
  186. //
  187. (Info->Function)(Info->Context, Value);
  188. }
  189. except (AVrfpWorkerFunctionExceptionFilter (_exception_code(), _exception_info())) {
  190. //
  191. // Nothing.
  192. //
  193. }
  194. RtlCheckForOrphanedCriticalSections (NtCurrentThread());
  195. RtlFreeHeap (RtlProcessHeap(), 0, Info);
  196. }
  197. //NTSYSAPI
  198. NTSTATUS
  199. NTAPI
  200. AVrfpRtlQueueWorkItem(
  201. IN WORKERCALLBACKFUNC Function,
  202. IN PVOID Context,
  203. IN ULONG Flags
  204. )
  205. {
  206. NTSTATUS Status;
  207. PAVRF_WORKER_INFO Info;
  208. Info = RtlAllocateHeap (RtlProcessHeap(), 0, sizeof *Info);
  209. if (Info == NULL) {
  210. return STATUS_NO_MEMORY;
  211. }
  212. Info->Context = Context;
  213. Info->Function = Function;
  214. Status = RtlQueueWorkItem (AVrfpStandardWorkerCallback,
  215. (PVOID)Info,
  216. Flags);
  217. return Status;
  218. }
  219. //NTSYSAPI
  220. NTSTATUS
  221. NTAPI
  222. AVrfpRtlRegisterWait (
  223. OUT PHANDLE WaitHandle,
  224. IN HANDLE Handle,
  225. IN WAITORTIMERCALLBACKFUNC Function,
  226. IN PVOID Context,
  227. IN ULONG Milliseconds,
  228. IN ULONG Flags
  229. )
  230. {
  231. NTSTATUS Status;
  232. PAVRF_WAIT_INFO Info;
  233. Info = RtlAllocateHeap (RtlProcessHeap(), 0, sizeof *Info);
  234. if (Info == NULL) {
  235. return STATUS_NO_MEMORY;
  236. }
  237. Info->Context = Context;
  238. Info->Function = Function;
  239. Status = RtlRegisterWait (WaitHandle,
  240. Handle,
  241. AVrfpStandardWaitCallback,
  242. (PVOID)Info,
  243. Milliseconds,
  244. Flags);
  245. return Status;
  246. }
  247. //NTSYSAPI
  248. NTSTATUS
  249. NTAPI
  250. AVrfpRtlCreateTimer (
  251. IN HANDLE TimerQueueHandle,
  252. OUT HANDLE *Handle,
  253. IN WAITORTIMERCALLBACKFUNC Function,
  254. IN PVOID Context,
  255. IN ULONG DueTime,
  256. IN ULONG Period,
  257. IN ULONG Flags
  258. )
  259. {
  260. NTSTATUS Status;
  261. PAVRF_WAIT_INFO Info;
  262. Info = RtlAllocateHeap (RtlProcessHeap(), 0, sizeof *Info);
  263. if (Info == NULL) {
  264. return STATUS_NO_MEMORY;
  265. }
  266. Info->Context = Context;
  267. Info->Function = Function;
  268. Status = RtlCreateTimer (TimerQueueHandle,
  269. Handle,
  270. AVrfpStandardWaitCallback,
  271. (PVOID)Info,
  272. DueTime,
  273. Period,
  274. Flags);
  275. return Status;
  276. }