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.

142 lines
4.5 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. MERGERTHROTTLING.H
  5. Abstract:
  6. CMergerThrottling clas
  7. History:
  8. 30-Nov-00 sanjes Created.
  9. --*/
  10. #ifndef _MERGERTHROTTLING_H_
  11. #define _MERGERTHROTTLING_H_
  12. // Enables debug messages for additional info.
  13. #ifdef DBG
  14. //#define __DEBUG_MERGER_THROTTLING
  15. #endif
  16. // Defaults - can be overridden from the registry
  17. #define DEFAULT_THROTTLE_THRESHOLD 10
  18. #define DEFAULT_THROTTLE_RELEASE_THRESHOLD 4
  19. // Forward Class Definitions
  20. class CInternalMerger;
  21. class CWmiMergerRecord;
  22. // This class encapsulates the throttling behavior which will be used by the internal
  23. // merger in order to control delivery of parent and child objects.
  24. class CMergerThrottling
  25. {
  26. // Following members are used for throttling incoming objects so that our
  27. // parent and child objects don't get wildly out of control. Note that we
  28. // use separate throttling events, since the decision to throttle is made in
  29. // a critsec, but the actual throttling occurs outside. This can have the
  30. // unpleasant side effect of a race condition in which for example, the parent
  31. // decides to throttle, steps out of the critsec, and a context switch occurs,
  32. // in which the child gets a large number of objects, releases the throttle, but
  33. // then causes child throttling to occur, resetting the event. If the parent
  34. // thread switches in at this point, we're hosed, since we will now wait on the
  35. // parent and the child.
  36. HANDLE m_hParentThrottlingEvent;
  37. HANDLE m_hChildThrottlingEvent;
  38. DWORD m_dwNumChildObjects;
  39. DWORD m_dwNumParentObjects;
  40. DWORD m_dwNumThrottledThreads;
  41. // Contains the time of the last ping from a parent or child.
  42. // Used to calculate whether or not we timeout
  43. DWORD m_dwLastParentPing;
  44. DWORD m_dwLastChildPing;
  45. // These should NEVER both be TRUE
  46. bool m_bParentThrottled;
  47. bool m_bChildThrottled;
  48. // Stop us from throttling if one side or the other is done
  49. bool m_bParentDone;
  50. bool m_bChildDone;
  51. // This controls the point where we determine that we need to perform throttling
  52. // Once parent or children are > m_dwThrottlingThreshold objects apart, one or the
  53. // other will be throttled
  54. DWORD m_dwThrottlingThreshold;
  55. // This controls the threshold where we will release currently throttled threads
  56. // Once we are throttled, we will remain throttled until parent or children are <
  57. // m_dwReleaseThreshold objects out of sync with each other.
  58. DWORD m_dwReleaseThreshold;
  59. // This controls the amount of memory we will allow Indicates to process before
  60. // forcing them to send objects further down the line
  61. DWORD m_dwBatchingThreshold;
  62. // This controls the timeout value we wait for. If we timeout and a provider has
  63. // not pinged us in the specified timeout, then we will cancel the merger with
  64. // a provider timed out error.
  65. DWORD m_dwProviderDeliveryTimeout;
  66. // We will expose this for other synchronization activities
  67. CCritSec m_cs;
  68. // Helper functions to control throttling
  69. bool ShouldThrottle( bool bParent );
  70. HRESULT PrepareThrottle( bool bParent, HANDLE* phEvent );
  71. bool VerifyTimeout( DWORD dwLastTick, long lNumArbThrottledThreads, DWORD* pdwAdjust );
  72. public:
  73. CMergerThrottling();
  74. ~CMergerThrottling();
  75. // Two stage initialization
  76. HRESULT Initialize( void );
  77. // Returns TRUE if throttling occurred
  78. HRESULT Throttle( bool bParent, CWmiMergerRecord* pMergerRecord );
  79. // Returns TRUE if we released throttled threads.
  80. bool ReleaseThrottle( bool bForce = false );
  81. // Informs us that we are in fact, done with Child and/or Parent
  82. void SetChildrenDone( void );
  83. void SetParentDone( void );
  84. void Cancel( void );
  85. // Helpers to control the number of current parent and child objects
  86. // which we will then use to make decisions as to whether or not
  87. // we should block a thread or not
  88. DWORD AdjustNumParentObjects( long lNumParentObjects )
  89. { return ( m_dwNumParentObjects += lNumParentObjects ); }
  90. DWORD AdjustNumChildObjects( long lNumChildObjects )
  91. { return ( m_dwNumChildObjects += lNumChildObjects ); }
  92. // Access to our critical section
  93. void Enter( void ) { m_cs.Enter(); }
  94. void Leave( void ) { m_cs.Leave(); }
  95. // Adjusts ping times
  96. DWORD Ping( bool bParent, CWmiMerger* pWmiMerger );
  97. CCritSec* GetCritSec( void ) { return &m_cs; }
  98. // Checks batch size against our limit
  99. bool IsCompleteBatch( long lBatchSize ) { return lBatchSize >= m_dwBatchingThreshold; }
  100. };
  101. #endif
  102.