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.

166 lines
5.3 KiB

  1. 1) OUT params are not guaranteed to be initialized except in
  2. the case of "Num of handles returned in an Enumeration" -
  3. - like NumDests in RtmGetEnumDests etc.
  4. 2) Callbacks to entities - there are certain restrictions on
  5. what Rtm calls can be used in the context of an RTM event
  6. callback -
  7. Entity Registration/De-registration callbacks:
  8. RtmRegisterEntity
  9. RtmDeregisterEntity
  10. RtmGetRegdEntities
  11. RtmGetInstances
  12. RtmGetInstanceInfo
  13. RtmGetAddrFamilyInfo
  14. Route Timed-out callback:
  15. Can call anything (as of now)
  16. Change Notification callback:
  17. RtmRegisterForChangeNotification
  18. RtmDeregisterForChangeNotification
  19. 3) If RTM has to take care of the fact that no ops should be
  20. allowed after deregistration -
  21. //------------------------------------------------------
  22. Code in RTMDeregisterEntity -
  23. /*-----------------------------------------------------
  24. This function marks the entity as deregistered thereby
  25. preventing this entity from making any more operations.
  26. It also waits until all pending operations on (or) by
  27. this entity are completed before it start cleaning up
  28. the state of the entity being deregistered.
  29. If other entities have handles open on objects of this
  30. entity, then this memory is reclaimed when these handles
  31. are released.
  32. Note that if this entity has handles open on objects
  33. (routes and nexthops) owned by another entity, then we
  34. have a case of a memory leak.
  35. ------------------------------------------------------*/
  36. //
  37. // Mark entity as deregistered to prevent more ops
  38. //
  39. try
  40. {
  41. Entity = GET_POINTER_FROM_HANDLE(RtmRegHandle);
  42. #if DBG_HDL
  43. if (Entity->ObjectHeader.TypeSign != ENTITY_ALLOC)
  44. {
  45. return ERROR_INVALID_HANDLE;
  46. }
  47. #endif
  48. // Block all new ops by flagging a deregister
  49. OldState = InterlockedExchangeAdd(&Entity->State,
  50. ENTITY_STATE_DEREGISTERED);
  51. if (OldState >= ENTITY_STATE_DEREGISTERED)
  52. {
  53. // We have already de-registered here
  54. InterlockedExchangeAdd(&Entity->State,
  55. (-1) * ENTITY_STATE_DEREGISTERED);
  56. return ERROR_INVALID_HANDLE;
  57. }
  58. }
  59. except(EXCEPTION_EXECUTE_HANDLER)
  60. {
  61. return ERROR_INVALID_HANDLE;
  62. }
  63. //
  64. // Block while waiting for active ops to finish
  65. //
  66. while (Entity->State != ENTITY_STATE_DEREGISTERED)
  67. {
  68. Sleep(0);
  69. }
  70. and
  71. Code for validating handle in other functions -
  72. try
  73. {
  74. Entity = GET_POINTER_FROM_HANDLE(RtmRegHandle);
  75. #if DBG_HDL
  76. if (Entity->ObjectHeader.TypeSign != ENTITY_ALLOC)
  77. {
  78. return ERROR_INVALID_HANDLE;
  79. }
  80. #endif
  81. if (InterlockedIncrement(&Entity->State) >= ENTITY_STATE_DEREGISTERED)
  82. {
  83. // We have already de-registered here
  84. InterlockedDecrement(&Entity->State);
  85. return ERROR_INVALID_HANDLE;
  86. }
  87. }
  88. except(EXCEPTION_EXECUTE_HANDLER)
  89. {
  90. return ERROR_INVALID_HANDLE;
  91. }
  92. //------------------------------------------------------
  93. 4) In case you wanted to use Interlocked Ops on lists -
  94. //
  95. // Single Link List manipulation using Interlocked Ops
  96. //
  97. #define InterlockedPushEntryList(ListHead, Entry) \
  98. while (TRUE) \
  99. { \
  100. (Entry)->Next = (ListHead)->Next; \
  101. if (InterlockedCompareExchangePointer(&((ListHead)->Next),\
  102. (Entry), \
  103. (Entry)->Next) \
  104. == (Entry)->Next) \
  105. { \
  106. break; \
  107. } \
  108. } \
  109. #define InterlockedPopEntryList(ListHead, Entry) \
  110. while (TRUE) \
  111. { \
  112. Entry = (ListHead)->Next; \
  113. if (Entry == NULL) \
  114. { \
  115. break; \
  116. } \
  117. \
  118. if (InterlockedCompareExchangePointer(&((ListHead)->Next),\
  119. ((Entry)->Next), \
  120. (Entry) \
  121. != (Entry)) \
  122. { \
  123. continue; \
  124. } \
  125. }