DelayDeletingFunctionTable.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "CommonMemoryPch.h"
  6. #include "Memory/XDataAllocator.h"
  7. #if PDATA_ENABLED && defined(_WIN32)
  8. #include "Core/DelayLoadLibrary.h"
  9. #include <malloc.h>
  10. CriticalSection DelayDeletingFunctionTable::cs;
  11. PSLIST_HEADER DelayDeletingFunctionTable::Head = nullptr;
  12. DelayDeletingFunctionTable DelayDeletingFunctionTable::Instance;
  13. DelayDeletingFunctionTable::DelayDeletingFunctionTable()
  14. {
  15. Head = (PSLIST_HEADER)_aligned_malloc(sizeof(SLIST_HEADER), MEMORY_ALLOCATION_ALIGNMENT);
  16. if (Head)
  17. {
  18. InitializeSListHead(Head);
  19. }
  20. }
  21. DelayDeletingFunctionTable::~DelayDeletingFunctionTable()
  22. {
  23. Clear();
  24. if (Head)
  25. {
  26. DebugOnly(SLIST_ENTRY* entry = InterlockedPopEntrySList(Head));
  27. Assert(entry == nullptr);
  28. _aligned_free(Head);
  29. Head = nullptr;
  30. }
  31. }
  32. bool DelayDeletingFunctionTable::AddEntry(FunctionTableHandle ft)
  33. {
  34. if (Head)
  35. {
  36. FunctionTableNode* node = (FunctionTableNode*)_aligned_malloc(sizeof(FunctionTableNode), MEMORY_ALLOCATION_ALIGNMENT);
  37. if (node)
  38. {
  39. node->functionTable = ft;
  40. InterlockedPushEntrySList(Head, &(node->itemEntry));
  41. return true;
  42. }
  43. }
  44. return false;
  45. }
  46. void DelayDeletingFunctionTable::Clear()
  47. {
  48. if (Head)
  49. {
  50. // add lock here to prevent in case one thread popped the entry and before deleting
  51. // another thread is registering function table for the same address
  52. AutoCriticalSection autoCS(&cs);
  53. SLIST_ENTRY* entry = InterlockedPopEntrySList(Head);
  54. while (entry)
  55. {
  56. FunctionTableNode* list = (FunctionTableNode*)entry;
  57. DeleteFunctionTable(list->functionTable);
  58. _aligned_free(entry);
  59. entry = InterlockedPopEntrySList(Head);
  60. }
  61. }
  62. }
  63. bool DelayDeletingFunctionTable::IsEmpty()
  64. {
  65. return QueryDepthSList(Head) == 0;
  66. }
  67. void DelayDeletingFunctionTable::DeleteFunctionTable(void* functionTable)
  68. {
  69. NtdllLibrary::Instance->DeleteGrowableFunctionTable(functionTable);
  70. }
  71. #endif