Leaked source code of windows server 2003
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.

1098 lines
40 KiB

  1. /*++
  2. Copyright (c) 1995-1999 Microsoft Corporation
  3. Module Name:
  4. rtutils.h
  5. Abstract:
  6. Public declarations for the Router process utility functions.
  7. --*/
  8. #ifndef __ROUTING_RTUTILS_H__
  9. #define __ROUTING_RTUTILS_H__
  10. #if _MSC_VER > 1000
  11. #pragma once
  12. #endif
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. //////////////////////////////////////////////////////////////////////////////
  17. // //
  18. // TRACING FUNCTION PROTOTYPES //
  19. // //
  20. // See DOCUMENT for more information //
  21. // //
  22. //////////////////////////////////////////////////////////////////////////////
  23. //////////////////////////////////////////////////////////////////////////////
  24. // //
  25. // Definitions for flags and constants //
  26. // //
  27. //////////////////////////////////////////////////////////////////////////////
  28. #define TRACE_USE_FILE 0x00000001
  29. #define TRACE_USE_CONSOLE 0x00000002
  30. #define TRACE_NO_SYNCH 0x00000004
  31. #define TRACE_NO_STDINFO 0x00000001
  32. #define TRACE_USE_MASK 0x00000002
  33. #define TRACE_USE_MSEC 0x00000004
  34. #define INVALID_TRACEID 0xFFFFFFFF
  35. //////////////////////////////////////////////////////////////////////////////
  36. // //
  37. // ANSI entry-points //
  38. // //
  39. //////////////////////////////////////////////////////////////////////////////
  40. DWORD
  41. APIENTRY
  42. TraceRegisterExA(
  43. IN LPCSTR lpszCallerName,
  44. IN DWORD dwFlags
  45. );
  46. DWORD
  47. APIENTRY
  48. TraceDeregisterA(
  49. IN DWORD dwTraceID
  50. );
  51. DWORD
  52. APIENTRY
  53. TraceDeregisterExA(
  54. IN DWORD dwTraceID,
  55. IN DWORD dwFlags
  56. );
  57. DWORD
  58. APIENTRY
  59. TraceGetConsoleA(
  60. IN DWORD dwTraceID,
  61. OUT LPHANDLE lphConsole
  62. );
  63. DWORD
  64. APIENTRY
  65. TracePrintfA(
  66. IN DWORD dwTraceID,
  67. IN LPCSTR lpszFormat,
  68. IN ... OPTIONAL
  69. );
  70. DWORD
  71. APIENTRY
  72. TracePrintfExA(
  73. IN DWORD dwTraceID,
  74. IN DWORD dwFlags,
  75. IN LPCSTR lpszFormat,
  76. IN ... OPTIONAL
  77. );
  78. DWORD
  79. APIENTRY
  80. TraceVprintfExA(
  81. IN DWORD dwTraceID,
  82. IN DWORD dwFlags,
  83. IN LPCSTR lpszFormat,
  84. IN va_list arglist
  85. );
  86. DWORD
  87. APIENTRY
  88. TracePutsExA(
  89. IN DWORD dwTraceID,
  90. IN DWORD dwFlags,
  91. IN LPCSTR lpszString
  92. );
  93. DWORD
  94. APIENTRY
  95. TraceDumpExA(
  96. IN DWORD dwTraceID,
  97. IN DWORD dwFlags,
  98. IN LPBYTE lpbBytes,
  99. IN DWORD dwByteCount,
  100. IN DWORD dwGroupSize,
  101. IN BOOL bAddressPrefix,
  102. IN LPCSTR lpszPrefix
  103. );
  104. //////////////////////////////////////////////////////////////////////////////
  105. // //
  106. // ANSI entry-points macros //
  107. // //
  108. //////////////////////////////////////////////////////////////////////////////
  109. #define TraceRegisterA(a) TraceRegisterExA(a,0)
  110. #define TraceVprintfA(a,b,c) TraceVprintfExA(a,0,b,c)
  111. #define TracePutsA(a,b) TracePutsExA(a,0,b)
  112. #define TraceDumpA(a,b,c,d,e,f) TraceDumpExA(a,0,b,c,d,e,f)
  113. //////////////////////////////////////////////////////////////////////////////
  114. // //
  115. // Unicode entry-points //
  116. // //
  117. //////////////////////////////////////////////////////////////////////////////
  118. DWORD
  119. APIENTRY
  120. TraceRegisterExW(
  121. IN LPCWSTR lpszCallerName,
  122. IN DWORD dwFlags
  123. );
  124. DWORD
  125. APIENTRY
  126. TraceDeregisterW(
  127. IN DWORD dwTraceID
  128. );
  129. DWORD
  130. APIENTRY
  131. TraceDeregisterExW(
  132. IN DWORD dwTraceID,
  133. IN DWORD dwFlags
  134. );
  135. DWORD
  136. APIENTRY
  137. TraceGetConsoleW(
  138. IN DWORD dwTraceID,
  139. OUT LPHANDLE lphConsole
  140. );
  141. DWORD
  142. APIENTRY
  143. TracePrintfW(
  144. IN DWORD dwTraceID,
  145. IN LPCWSTR lpszFormat,
  146. IN ... OPTIONAL
  147. );
  148. DWORD
  149. APIENTRY
  150. TracePrintfExW(
  151. IN DWORD dwTraceID,
  152. IN DWORD dwFlags,
  153. IN LPCWSTR lpszFormat,
  154. IN ... OPTIONAL
  155. );
  156. DWORD
  157. APIENTRY
  158. TraceVprintfExW(
  159. IN DWORD dwTraceID,
  160. IN DWORD dwFlags,
  161. IN LPCWSTR lpszFormat,
  162. IN va_list arglist
  163. );
  164. DWORD
  165. APIENTRY
  166. TracePutsExW(
  167. IN DWORD dwTraceID,
  168. IN DWORD dwFlags,
  169. IN LPCWSTR lpszString
  170. );
  171. DWORD
  172. APIENTRY
  173. TraceDumpExW(
  174. IN DWORD dwTraceID,
  175. IN DWORD dwFlags,
  176. IN LPBYTE lpbBytes,
  177. IN DWORD dwByteCount,
  178. IN DWORD dwGroupSize,
  179. IN BOOL bAddressPrefix,
  180. IN LPCWSTR lpszPrefix
  181. );
  182. //////////////////////////////////////////////////////////////////////////////
  183. // //
  184. // Unicode entry-points macros //
  185. // //
  186. //////////////////////////////////////////////////////////////////////////////
  187. #define TraceRegisterW(a) TraceRegisterExW(a,0)
  188. #define TraceVprintfW(a,b,c) TraceVprintfExW(a,0,b,c)
  189. #define TracePutsW(a,b) TracePutsExW(a,0,b)
  190. #define TraceDumpW(a,b,c,d,e,f) TraceDumpExW(a,0,b,c,d,e,f)
  191. //////////////////////////////////////////////////////////////////////////////
  192. // //
  193. // Code-page dependent entry-point macros //
  194. // //
  195. //////////////////////////////////////////////////////////////////////////////
  196. #ifdef UNICODE
  197. #define TraceRegister TraceRegisterW
  198. #define TraceDeregister TraceDeregisterW
  199. #define TraceDeregisterEx TraceDeregisterExW
  200. #define TraceGetConsole TraceGetConsoleW
  201. #define TracePrintf TracePrintfW
  202. #define TraceVprintf TraceVprintfW
  203. #define TracePuts TracePutsW
  204. #define TraceDump TraceDumpW
  205. #define TraceRegisterEx TraceRegisterExW
  206. #define TracePrintfEx TracePrintfExW
  207. #define TraceVprintfEx TraceVprintfExW
  208. #define TracePutsEx TracePutsExW
  209. #define TraceDumpEx TraceDumpExW
  210. #else
  211. #define TraceRegister TraceRegisterA
  212. #define TraceDeregister TraceDeregisterA
  213. #define TraceDeregisterEx TraceDeregisterExA
  214. #define TraceGetConsole TraceGetConsoleA
  215. #define TracePrintf TracePrintfA
  216. #define TraceVprintf TraceVprintfA
  217. #define TracePuts TracePutsA
  218. #define TraceDump TraceDumpA
  219. #define TraceRegisterEx TraceRegisterExA
  220. #define TracePrintfEx TracePrintfExA
  221. #define TraceVprintfEx TraceVprintfExA
  222. #define TracePutsEx TracePutsExA
  223. #define TraceDumpEx TraceDumpExA
  224. #endif
  225. //////////////////////////////////////////////////////////////////////////////
  226. // //
  227. // EVENT LOGGING FUNCTION PROTOTYPES //
  228. // //
  229. //////////////////////////////////////////////////////////////////////////////
  230. //////////////////////////////////////////////////////////////////////////////
  231. // //
  232. // ANSI prototypes //
  233. // //
  234. //////////////////////////////////////////////////////////////////////////////
  235. VOID
  236. APIENTRY
  237. LogErrorA(
  238. IN DWORD dwMessageId,
  239. IN DWORD cNumberOfSubStrings,
  240. IN LPSTR *plpwsSubStrings,
  241. IN DWORD dwErrorCode
  242. );
  243. VOID
  244. APIENTRY
  245. LogEventA(
  246. IN DWORD wEventType,
  247. IN DWORD dwMessageId,
  248. IN DWORD cNumberOfSubStrings,
  249. IN LPSTR *plpwsSubStrings
  250. );
  251. //////////////////////////////////////////////////////////////////////////////
  252. // //
  253. // Unicode prototypes //
  254. // //
  255. //////////////////////////////////////////////////////////////////////////////
  256. VOID
  257. LogErrorW(
  258. IN DWORD dwMessageId,
  259. IN DWORD cNumberOfSubStrings,
  260. IN LPWSTR *plpwsSubStrings,
  261. IN DWORD dwErrorCode
  262. );
  263. VOID
  264. LogEventW(
  265. IN DWORD wEventType,
  266. IN DWORD dwMessageId,
  267. IN DWORD cNumberOfSubStrings,
  268. IN LPWSTR *plpwsSubStrings
  269. );
  270. #ifdef UNICODE
  271. #define LogError LogErrorW
  272. #define LogEvent LogEventW
  273. #else
  274. #define LogError LogErrorA
  275. #define LogEvent LogEventA
  276. #endif
  277. //////////////////////////////////////////////////////////////////////////////
  278. // //
  279. // The following functions allow the caller to specify the event source. //
  280. // //
  281. // Call RouterLogRegister with the strings which would be passed to //
  282. // RegisterEventSource; this returns a handle which can be passed //
  283. // to the functions RouterLogEvent and RouterLogEventData. //
  284. // //
  285. // Call RouterLogDeregister to close the handle. //
  286. // //
  287. // Macros are provided for the different kinds of event log entrys: //
  288. // RouterLogError logs an error (EVENTLOG_ERROR_TYPE) //
  289. // RouterLogWarning logs a warning (EVENTLOG_WARNING_TYPE) //
  290. // RouterLogInformation logs information (EVENTLOG_INFORMATION_TYPE) //
  291. // //
  292. //////////////////////////////////////////////////////////////////////////////
  293. //////////////////////////////////////////////////////////////////////////////
  294. // //
  295. // ANSI prototypes //
  296. // //
  297. //////////////////////////////////////////////////////////////////////////////
  298. HANDLE
  299. RouterLogRegisterA(
  300. LPCSTR lpszSource
  301. );
  302. VOID
  303. RouterLogDeregisterA(
  304. HANDLE hLogHandle
  305. );
  306. VOID
  307. RouterLogEventA(
  308. IN HANDLE hLogHandle,
  309. IN DWORD dwEventType,
  310. IN DWORD dwMessageId,
  311. IN DWORD dwSubStringCount,
  312. IN LPSTR *plpszSubStringArray,
  313. IN DWORD dwErrorCode
  314. );
  315. VOID
  316. RouterLogEventDataA(
  317. IN HANDLE hLogHandle,
  318. IN DWORD dwEventType,
  319. IN DWORD dwMessageId,
  320. IN DWORD dwSubStringCount,
  321. IN LPSTR *plpszSubStringArray,
  322. IN DWORD dwDataBytes,
  323. IN LPBYTE lpDataBytes
  324. );
  325. VOID
  326. RouterLogEventStringA(
  327. IN HANDLE hLogHandle,
  328. IN DWORD dwEventType,
  329. IN DWORD dwMessageId,
  330. IN DWORD dwSubStringCount,
  331. IN LPSTR *plpszSubStringArray,
  332. IN DWORD dwErrorCode,
  333. IN DWORD dwErrorIndex
  334. );
  335. VOID
  336. RouterLogEventExA(
  337. IN HANDLE hLogHandle,
  338. IN DWORD dwEventType,
  339. IN DWORD dwErrorCode,
  340. IN DWORD dwMessageId,
  341. IN LPCSTR ptszFormat,
  342. ...
  343. );
  344. VOID
  345. RouterLogEventValistExA(
  346. IN HANDLE hLogHandle,
  347. IN DWORD dwEventType,
  348. IN DWORD dwErrorCode,
  349. IN DWORD dwMessageId,
  350. IN LPCSTR ptszFormat,
  351. IN va_list arglist
  352. );
  353. DWORD
  354. RouterGetErrorStringA(
  355. IN DWORD dwErrorCode,
  356. OUT LPSTR * lplpszErrorString
  357. );
  358. #define RouterLogErrorA(h,msg,count,array,err) \
  359. RouterLogEventA(h,EVENTLOG_ERROR_TYPE,msg,count,array,err)
  360. #define RouterLogWarningA(h,msg,count,array,err) \
  361. RouterLogEventA(h,EVENTLOG_WARNING_TYPE,msg,count,array,err)
  362. #define RouterLogInformationA(h,msg,count,array,err) \
  363. RouterLogEventA(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err)
  364. #define RouterLogErrorDataA(h,msg,count,array,c,buf) \
  365. RouterLogEventDataA(h,EVENTLOG_ERROR_TYPE,msg,count,array,c,buf)
  366. #define RouterLogWarningDataA(h,msg,count,array,c,buf) \
  367. RouterLogEventDataA(h,EVENTLOG_WARNING_TYPE,msg,count,array,c,buf)
  368. #define RouterLogInformationDataA(h,msg,count,array,c,buf) \
  369. RouterLogEventDataA(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,c,buf)
  370. #define RouterLogErrorStringA(h,msg,count,array,err,index) \
  371. RouterLogEventStringA(h,EVENTLOG_ERROR_TYPE,msg,count,array, err,index)
  372. #define RouterLogWarningStringA(h,msg,count,array,err,index) \
  373. RouterLogEventStringA(h,EVENTLOG_WARNING_TYPE,msg,count,array,err,index)
  374. #define RouterLogInformationStringA(h,msg,count,array, err,index) \
  375. RouterLogEventStringA(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err,\
  376. index)
  377. //////////////////////////////////////////////////////////////////////////////
  378. // //
  379. // Unicode prototypes //
  380. // //
  381. //////////////////////////////////////////////////////////////////////////////
  382. HANDLE
  383. RouterLogRegisterW(
  384. LPCWSTR lpszSource
  385. );
  386. VOID
  387. RouterLogDeregisterW(
  388. HANDLE hLogHandle
  389. );
  390. VOID
  391. RouterLogEventW(
  392. IN HANDLE hLogHandle,
  393. IN DWORD dwEventType,
  394. IN DWORD dwMessageId,
  395. IN DWORD dwSubStringCount,
  396. IN LPWSTR *plpszSubStringArray,
  397. IN DWORD dwErrorCode
  398. );
  399. VOID
  400. RouterLogEventDataW(
  401. IN HANDLE hLogHandle,
  402. IN DWORD dwEventType,
  403. IN DWORD dwMessageId,
  404. IN DWORD dwSubStringCount,
  405. IN LPWSTR *plpszSubStringArray,
  406. IN DWORD dwDataBytes,
  407. IN LPBYTE lpDataBytes
  408. );
  409. VOID
  410. RouterLogEventStringW(
  411. IN HANDLE hLogHandle,
  412. IN DWORD dwEventType,
  413. IN DWORD dwMessageId,
  414. IN DWORD dwSubStringCount,
  415. IN LPWSTR *plpszSubStringArray,
  416. IN DWORD dwErrorCode,
  417. IN DWORD dwErrorIndex
  418. );
  419. VOID
  420. RouterLogEventExW(
  421. IN HANDLE hLogHandle,
  422. IN DWORD dwEventType,
  423. IN DWORD dwErrorCode,
  424. IN DWORD dwMessageId,
  425. IN LPCWSTR ptszFormat,
  426. ...
  427. );
  428. VOID
  429. RouterLogEventValistExW(
  430. IN HANDLE hLogHandle,
  431. IN DWORD dwEventType,
  432. IN DWORD dwErrorCode,
  433. IN DWORD dwMessageId,
  434. IN LPCWSTR ptszFormat,
  435. IN va_list arglist
  436. );
  437. DWORD
  438. RouterGetErrorStringW(
  439. IN DWORD dwErrorCode,
  440. OUT LPWSTR * lplpwszErrorString
  441. );
  442. #define RouterLogErrorW(h,msg,count,array,err) \
  443. RouterLogEventW(h,EVENTLOG_ERROR_TYPE,msg,count,array,err)
  444. #define RouterLogWarningW(h,msg,count,array,err) \
  445. RouterLogEventW(h,EVENTLOG_WARNING_TYPE,msg,count,array,err)
  446. #define RouterLogInformationW(h,msg,count,array,err) \
  447. RouterLogEventW(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err)
  448. #define RouterLogErrorDataW(h,msg,count,array,c,buf) \
  449. RouterLogEventDataW(h,EVENTLOG_ERROR_TYPE,msg,count,array,c,buf)
  450. #define RouterLogWarningDataW(h,msg,count,array,c,buf) \
  451. RouterLogEventDataW(h,EVENTLOG_WARNING_TYPE,msg,count,array,c,buf)
  452. #define RouterLogInformationDataW(h,msg,count,array,c,buf) \
  453. RouterLogEventDataW(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,c,buf)
  454. #define RouterLogErrorStringW(h,msg,count,array,err,index) \
  455. RouterLogEventStringW(h,EVENTLOG_ERROR_TYPE,msg,count,array,err,index)
  456. #define RouterLogWarningStringW(h,msg,count,array,err,index) \
  457. RouterLogEventStringW(h,EVENTLOG_WARNING_TYPE,msg,count,array,err,index)
  458. #define RouterLogInformationStringW(h,msg,count,array,err,index) \
  459. RouterLogEventStringW(h,EVENTLOG_INFORMATION_TYPE,msg,count,array,err,\
  460. index)
  461. #ifdef UNICODE
  462. #define RouterLogRegister RouterLogRegisterW
  463. #define RouterLogDeregister RouterLogDeregisterW
  464. #define RouterLogEvent RouterLogEventW
  465. #define RouterLogError RouterLogErrorW
  466. #define RouterLogWarning RouterLogWarningW
  467. #define RouterLogInformation RouterLogInformationW
  468. #define RouterLogEventData RouterLogEventDataW
  469. #define RouterLogErrorData RouterLogErrorDataW
  470. #define RouterLogWarningData RouterLogWarningDataW
  471. #define RouterLogInformationData RouterLogInformationDataW
  472. #define RouterLogEventString RouterLogEventStringW
  473. #define RouterLogEventEx RouterLogEventExW
  474. #define RouterLogEventValistEx RouterLogEventValistExW
  475. #define RouterLogErrorString RouterLogErrorStringW
  476. #define RouterLogWarningString RouterLogWarningStringW
  477. #define RouterLogInformationString RouterLogInformationStringW
  478. #define RouterGetErrorString RouterGetErrorStringW
  479. #
  480. #else
  481. #define RouterLogRegister RouterLogRegisterA
  482. #define RouterLogDeregister RouterLogDeregisterA
  483. #define RouterLogEvent RouterLogEventA
  484. #define RouterLogError RouterLogErrorA
  485. #define RouterLogWarning RouterLogWarningA
  486. #define RouterLogInformation RouterLogInformationA
  487. #define RouterLogEventData RouterLogEventDataA
  488. #define RouterLogErrorData RouterLogErrorDataA
  489. #define RouterLogWarningData RouterLogWarningDataA
  490. #define RouterLogInformationData RouterLogInformationDataA
  491. #define RouterLogEventString RouterLogEventStringA
  492. #define RouterLogEventEx RouterLogEventExA
  493. #define RouterLogEventValistEx RouterLogEventValistExA
  494. #define RouterLogErrorString RouterLogErrorStringA
  495. #define RouterLogWarningString RouterLogWarningStringA
  496. #define RouterLogInformationString RouterLogInformationStringA
  497. #define RouterGetErrorString RouterGetErrorStringA
  498. #endif
  499. //////////////////////////////////////////////////////////////////////////////
  500. // //
  501. // WORKER THREAD POOL FUNCTIONS //
  502. // //
  503. //////////////////////////////////////////////////////////////////////////////
  504. //////////////////////////////////////////////////////////////////////////////
  505. // //
  506. // definition of worker function passed in QueueWorkItem API //
  507. // //
  508. //////////////////////////////////////////////////////////////////////////////
  509. typedef VOID (APIENTRY * WORKERFUNCTION)(PVOID);
  510. //////////////////////////////////////////////////////////////////////////////
  511. // //
  512. // Function: Queues the supplied work item in the work queue. //
  513. // //
  514. // functionptr: function to be called must be of WORKERFUNCTION type //
  515. // context: opaque ptr //
  516. // serviceinalertablethread: if TRUE gets scheduled in //
  517. // a alertably waiting thread that never dies //
  518. // Returns: 0 (success) //
  519. // Win32 error codes for cases like out of memory //
  520. // //
  521. //////////////////////////////////////////////////////////////////////////////
  522. DWORD
  523. APIENTRY
  524. QueueWorkItem(
  525. IN WORKERFUNCTION functionptr,
  526. IN PVOID context,
  527. IN BOOL serviceinalertablethread
  528. );
  529. //////////////////////////////////////////////////////////////////////////////
  530. // //
  531. // Function: Associates file handle with the completion port (all //
  532. // asynchronous i/o on this handle will be queued to //
  533. // the completion port) //
  534. // //
  535. // FileHandle: File handle to be associated with completion port //
  536. // //
  537. // CompletionProc: Procedure to be called when io associated with the file //
  538. // handle completes. This function will be executed in //
  539. // the context of non-alertable worker thread //
  540. // //
  541. //////////////////////////////////////////////////////////////////////////////
  542. DWORD
  543. APIENTRY
  544. SetIoCompletionProc (
  545. IN HANDLE FileHandle,
  546. IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionProc
  547. );
  548. //////////////////////////////////////////////////////////////////////////////
  549. // //
  550. // The following defines are included here as a hint on how the worker //
  551. // thread pool is managed: //
  552. // //
  553. // There are NUM_ALERTABLE_THREADS permanent threads that never quit and //
  554. // wait alertably on a alertable worker queue. These threads should solely //
  555. // be used for work items that intiate asyncronous operation (file io, //
  556. // waitable timer) that ABSOLUTELY require APCs to complete (preferable //
  557. // method for IO is the usage of completio port API) //
  558. // //
  559. // There is a pool of the threads that wait on completion port //
  560. // that used both for processing of IO and non-IO related work items //
  561. // //
  562. // The minimum number of threads is Number of processors //
  563. // The maximum number of threads is MAX_WORKER_THREADS //
  564. // //
  565. // A new thread is created if worker queue has not been served for more //
  566. // that WORK_QUEUE_TIMEOUT //
  567. // The existing thread will be shut down if it is not used for more than //
  568. // THREAD_IDLE_TIMEOUT //
  569. // //
  570. // Note that worker threads age guaranteed to be alive for at least //
  571. // THREAD_IDLE_TIMEOUT after the last work item is executed. This timeout //
  572. // is chosen such that bulk of IO request could be completed before it //
  573. // expires. If it is not enough for your case, use alertable thread with //
  574. // APC, or create your own thread. //
  575. // //
  576. // Note: changing these flags will not change anything. //
  577. // //
  578. //////////////////////////////////////////////////////////////////////////////
  579. //////////////////////////////////////////////////////////////////////////////
  580. // //
  581. // Number of alertable threads //
  582. // //
  583. //////////////////////////////////////////////////////////////////////////////
  584. #define NUM_ALERTABLE_THREADS 2
  585. //////////////////////////////////////////////////////////////////////////////
  586. // //
  587. // Max number of threads at any time //
  588. // //
  589. //////////////////////////////////////////////////////////////////////////////
  590. #define MAX_WORKER_THREADS 10
  591. //////////////////////////////////////////////////////////////////////////////
  592. // //
  593. // Time that the worker queue is not served before starting new thread //
  594. // //
  595. //////////////////////////////////////////////////////////////////////////////
  596. #define WORK_QUEUE_TIMEOUT 1 //sec
  597. //////////////////////////////////////////////////////////////////////////////
  598. // //
  599. // Time that thread has to be idle before exiting //
  600. // //
  601. //////////////////////////////////////////////////////////////////////////////
  602. #define THREAD_IDLE_TIMEOUT 10 //sec
  603. //////////////////////////////////////////////////////////////////////////////
  604. // //
  605. // ROUTER ASSERT DECLARATION //
  606. // //
  607. //////////////////////////////////////////////////////////////////////////////
  608. VOID
  609. RouterAssert(
  610. IN PSTR pszFailedAssertion,
  611. IN PSTR pszFileName,
  612. IN DWORD dwLineNumber,
  613. IN PSTR pszMessage OPTIONAL
  614. );
  615. #if DBG
  616. #define RTASSERT(exp) \
  617. if (!(exp)) \
  618. RouterAssert(#exp, __FILE__, __LINE__, NULL)
  619. #define RTASSERTMSG(msg, exp) \
  620. if (!(exp)) \
  621. RouterAssert(#exp, __FILE__, __LINE__, msg)
  622. #else
  623. #define RTASSERT(exp)
  624. #define RTASSERTMSG(msg, exp)
  625. #endif
  626. //////////////////////////////////////////////////////////////////////////////
  627. // //
  628. // REGISTRY CONFIGURATION FUNCTIONS //
  629. // //
  630. // The following definitions are used to read configuration information //
  631. // about installed protocols. //
  632. // //
  633. // Call 'MprSetupProtocolEnum' to enumerate the routing-protocols //
  634. // for transport 'dwTransportId'. This fills an array with entries //
  635. // of type 'MPR_PROTOCOL_0'. //
  636. // //
  637. // The array loaded can be destroyed by calling 'MprSetupProtocolFree'. //
  638. // //
  639. //////////////////////////////////////////////////////////////////////////////
  640. #define MAX_PROTOCOL_NAME_LEN 40
  641. #define MAX_PROTOCOL_DLL_LEN 48
  642. typedef struct _MPR_PROTOCOL_0 {
  643. DWORD dwProtocolId; // e.g. IP_RIP
  644. WCHAR wszProtocol[MAX_PROTOCOL_NAME_LEN+1]; // e.g. "IPRIP"
  645. WCHAR wszDLLName[MAX_PROTOCOL_DLL_LEN+1]; // e.g. "iprip2.dll"
  646. } MPR_PROTOCOL_0;
  647. DWORD APIENTRY
  648. MprSetupProtocolEnum(
  649. IN DWORD dwTransportId,
  650. OUT LPBYTE* lplpBuffer, // MPR_PROTOCOL_0
  651. OUT LPDWORD lpdwEntriesRead
  652. );
  653. DWORD APIENTRY
  654. MprSetupProtocolFree(
  655. IN LPVOID lpBuffer
  656. );
  657. //////////////////////////////////////////////////////////////////////////////
  658. // Extensions to Rtutils to improve worker thread utilization. //
  659. // //
  660. //////////////////////////////////////////////////////////////////////////////
  661. #define ROUTING_RESERVED
  662. #define OPT1_1
  663. #define OPT1_2
  664. #define OPT2_1
  665. #define OPT2_2
  666. #define OPT3_1
  667. #define OPT3_2
  668. //
  669. // When everyone is migrated to using Winsock2
  670. //
  671. #if 0
  672. //==========================================================================================================//
  673. //==========================================================================================================//
  674. // ASYNC_SOCKET_DATA structure is used to pass / receive back data from an //
  675. // asynchronous wait recv from call //
  676. typedef struct _ASYNC_SOCKET_DATA {
  677. OVERLAPPED Overlapped; // reserved. not to be used
  678. IN WSABUF WsaBuf; // WsaBuf.buf to be initialized to point to buffer
  679. // WsaBuf.len set to the length of the buffer
  680. OUT SOCKADDR_IN SrcAddress; // AsyncWsaRecvFrom fills this with the source address of the packet
  681. OUT DWORD NumBytesReceived; // AsyncWsaRecvFrom fills this with the number of bytes returned in the packet
  682. IN OUT DWORD Flags; // Used to set flags for WSARecvFrom, and returns the flags set by WSARecvFrom
  683. OUT DWORD Status; // status returned by IO Completion Port
  684. IN WORKERFUNCTION pFunction; // Function to be executed on receiving packet
  685. IN PVOID pContext; // context for the above function
  686. } ASYNC_SOCKET_DATA, *PASYNC_SOCKET_DATA;
  687. // AsyncSocketInit() binds the socket to the IOCompletionPort. This should be called//
  688. // after the socket is created and before AsyncWsaRecvFrom() call is made //
  689. DWORD
  690. APIENTRY
  691. AsyncSocketInit (
  692. SOCKET sock
  693. );
  694. // This should be called only after the appropriate fields in SockData are initialized //
  695. // This sets up an asynchronous WSARecvFrom(), and on its return dispatches the //
  696. // function to a worker thread. It should be remembered that the function will run in //
  697. // a worker thread which might later on be deleted. So SetWaitableTimer() and //
  698. // asynchronous receive calls should be avoided unless you are sure that it would not be//
  699. // a problem. It is adviced that if you want the function to run in an alertable thread,//
  700. // then have the callback function queue a work item to alertable thread. Queue work //
  701. // items to alertable worker threads for SetWaitableTimer() and async receives. //
  702. // One must not make many AsyncWSArecvFrom() calls, as the buffer are non-paged //
  703. DWORD
  704. APIENTRY
  705. AsyncWSARecvFrom (
  706. SOCKET sock,
  707. PASYNC_SOCKET_DATA pSockData
  708. );
  709. #endif // all winsock2 functions
  710. //==========================================================================================================//
  711. //==========================================================================================================//
  712. // forward declarations
  713. struct _WAIT_THREAD_ENTRY;
  714. struct _WT_EVENT_ENTRY;
  715. typedef struct _WT_TIMER_ENTRY {
  716. LONGLONG te_Timeout;
  717. WORKERFUNCTION te_Function;
  718. PVOID te_Context;
  719. DWORD te_ContextSz;
  720. BOOL te_RunInServer;
  721. DWORD te_Status;
  722. #define TIMER_INACTIVE 3
  723. #define TIMER_ACTIVE 4
  724. DWORD te_ServerId;
  725. struct _WAIT_THREAD_ENTRY *teP_wte;
  726. LIST_ENTRY te_ServerLinks;
  727. LIST_ENTRY te_Links;
  728. BOOL te_Flag; //todo: not used
  729. DWORD te_TimerId;
  730. } WT_TIMER_ENTRY, *PWT_TIMER_ENTRY;
  731. typedef struct _WT_WORK_ITEM {
  732. WORKERFUNCTION wi_Function; // function to call
  733. PVOID wi_Context; // context passed into function call
  734. DWORD wi_ContextSz; // size of context, used for allocating
  735. BOOL wi_RunInServer; // run in wait server thread or get queued to some worker thread
  736. struct _WT_EVENT_ENTRY *wiP_ee;
  737. LIST_ENTRY wi_ServerLinks;
  738. LIST_ENTRY wi_Links; //todo not req // link to next and prev element
  739. } WT_WORK_ITEM, *PWT_WORK_ITEM;
  740. #define WT_EVENT_BINDING WT_WORK_ITEM
  741. #define PWT_EVENT_BINDING PWT_WORK_ITEM
  742. //
  743. // WT_EVENT_ENTRY
  744. //
  745. typedef struct _WT_EVENT_ENTRY {
  746. HANDLE ee_Event;
  747. BOOL ee_bManualReset; // is the event manually reset
  748. BOOL ee_bInitialState; // is the initial state of the event active
  749. BOOL ee_bDeleteEvent; // was the event created as part of createWaitEvent
  750. DWORD ee_Status; // current status of the event entry
  751. BOOL ee_bHighPriority;
  752. LIST_ENTRY eeL_wi;
  753. BOOL ee_bSignalSingle; // signal single function or multiple functions // how many functions to activate when event signalled (default:1)
  754. BOOL ee_bOwnerSelf; // the owner if the client which create this event
  755. INT ee_ArrayIndex; // index in the events array if active
  756. DWORD ee_ServerId; // Id of server: used while deleting
  757. struct _WAIT_THREAD_ENTRY *eeP_wte; // pointer to wait thread entry
  758. LIST_ENTRY ee_ServerLinks; // used by wait server thread
  759. LIST_ENTRY ee_Links; // used by client
  760. DWORD ee_RefCount;
  761. BOOL ee_bFlag; //todo: notused // reserved for use during deletion
  762. DWORD ee_EventId; //todo: remove it, being used only for testing/debugging
  763. } WT_EVENT_ENTRY, *PWT_EVENT_ENTRY;
  764. // PROTOTYPES OF FUNCTIONS USED IN THIS FILE ONLY
  765. //
  766. // used by client to create a wait event
  767. // context size should be 0 if you are passing a dword instead of a pointer
  768. // if pEvent field is set, then lpName and security attributes are ignored
  769. // if pFunction is NULL, then pContext, dwContextSz, and bRunInServerContext are ignored
  770. PWT_EVENT_ENTRY
  771. APIENTRY
  772. CreateWaitEvent (
  773. //IN PWT_EVENT_ENTRY pEventEntry, // handle to event entry if initialized by others
  774. IN HANDLE pEvent OPT1_1, // handle to event if already created
  775. IN LPSECURITY_ATTRIBUTES lpEventAttributes OPT1_2, // pointer to security attributes
  776. IN BOOL bManualReset,
  777. IN BOOL bInitialState,
  778. IN LPCTSTR lpName OPT1_2, // pointer to event-object name
  779. IN BOOL bHighPriority, // create high priority event
  780. IN WORKERFUNCTION pFunction OPT2_1, // if null, means will be set by other clients
  781. IN PVOID pContext OPT2_1, // can be null
  782. IN DWORD dwContextSz OPT2_1, // size of context: used for allocating context to functions
  783. IN BOOL bRunInServerContext OPT2_1 // run in server thread or get dispatched to worker thread
  784. );
  785. //dwContextSz should be 0 if a dword is being passed. >0 only if pointer to block of that size is being passed.
  786. PWT_EVENT_BINDING
  787. APIENTRY
  788. CreateWaitEventBinding (
  789. IN PWT_EVENT_ENTRY pee,
  790. IN WORKERFUNCTION pFunction,
  791. IN PVOID pContext,
  792. IN DWORD dwContextSz,
  793. IN BOOL bRunInServerContext
  794. );
  795. PWT_TIMER_ENTRY
  796. APIENTRY
  797. CreateWaitTimer (
  798. IN WORKERFUNCTION pFunction,
  799. IN PVOID pContext,
  800. IN DWORD dwContextSz,
  801. IN BOOL bRunInServerContext
  802. );
  803. DWORD
  804. APIENTRY
  805. DeRegisterWaitEventBindingSelf (
  806. IN PWT_EVENT_BINDING pwiWorkItem
  807. );
  808. DWORD
  809. APIENTRY
  810. DeRegisterWaitEventBinding (
  811. IN PWT_EVENT_BINDING pwiWorkItem
  812. );
  813. //all the events and timers should be registered with one waitThread server
  814. //todo: change the above requirement
  815. DWORD
  816. APIENTRY
  817. DeRegisterWaitEventsTimers (
  818. PLIST_ENTRY pLEvents, // list of events linked by ee_Links field
  819. PLIST_ENTRY pLTimers // list of timers linked by te_Links field:
  820. //these lists can be a single list entry, or a multiple entry list with a list header entry.
  821. );
  822. // this should be used only when called within a server thread
  823. DWORD
  824. APIENTRY
  825. DeRegisterWaitEventsTimersSelf (
  826. IN PLIST_ENTRY pLEvents,
  827. IN PLIST_ENTRY pLTimers
  828. );
  829. DWORD
  830. APIENTRY
  831. RegisterWaitEventBinding (
  832. IN PWT_EVENT_BINDING pwiWorkItem
  833. );
  834. // Register the client with the wait thread
  835. DWORD
  836. APIENTRY
  837. RegisterWaitEventsTimers (
  838. IN PLIST_ENTRY pLEventsToAdd,
  839. IN PLIST_ENTRY pLTimersToAdd
  840. );
  841. DWORD
  842. APIENTRY
  843. UpdateWaitTimer (
  844. IN PWT_TIMER_ENTRY pte,
  845. IN LONGLONG *time
  846. );
  847. VOID
  848. APIENTRY
  849. WTFree (
  850. PVOID ptr
  851. );
  852. //used to free wait-event. Should be deallocated using DeRegisterWaitEventsTimers
  853. //This function is to be used only when the events have not been registered
  854. VOID
  855. APIENTRY
  856. WTFreeEvent (
  857. IN PWT_EVENT_ENTRY peeEvent
  858. );
  859. //used to free wait-timer. Should be deallocated using DeRegisterWaitEventsTimers
  860. //This function is to be used only when the timers have not been registered
  861. VOID
  862. APIENTRY
  863. WTFreeTimer (
  864. IN PWT_TIMER_ENTRY pteTimer
  865. );
  866. VOID
  867. APIENTRY
  868. DebugPrintWaitWorkerThreads (
  869. DWORD dwDebugLevel
  870. );
  871. #define DEBUGPRINT_FILTER_NONCLIENT_EVENTS 0x2
  872. #define DEBUGPRINT_FILTER_EVENTS 0x4
  873. #define DEBUGPRINT_FILTER_TIMERS 0x8
  874. //
  875. //ERROR VALUES
  876. //
  877. #define ERROR_WAIT_THREAD_UNAVAILABLE 1
  878. #define ERROR_WT_EVENT_ALREADY_DELETED 2
  879. #define TIMER_HIGH(time) \
  880. (((LARGE_INTEGER*)&time)->HighPart)
  881. #define TIMER_LOW(time) \
  882. (((LARGE_INTEGER*)&time)->LowPart)
  883. #ifdef __cplusplus
  884. }
  885. #endif
  886. #endif // ___ROUTING_RTUTILS_H__