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.

123 lines
2.3 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. // FILE
  4. //
  5. // ldapcache.cpp
  6. //
  7. // SYNOPSIS
  8. //
  9. // Defines the class LDAPCache.
  10. //
  11. // MODIFICATION HISTORY
  12. //
  13. // 05/08/1998 Original version.
  14. //
  15. ///////////////////////////////////////////////////////////////////////////////
  16. #include <ias.h>
  17. #include <ldapcache.h>
  18. //////////
  19. // Utility function for getting the current system time as a 64-bit integer.
  20. //////////
  21. inline DWORDLONG GetSystemTimeAsDWORDLONG() throw ()
  22. {
  23. ULARGE_INTEGER ft;
  24. GetSystemTimeAsFileTime((LPFILETIME)&ft);
  25. return ft.QuadPart;
  26. }
  27. LDAPCache::~LDAPCache()
  28. {
  29. clear();
  30. }
  31. void LDAPCache::clear() throw ()
  32. {
  33. Lock();
  34. // Release all the servers.
  35. for (ServerTable::iterator i = cache.begin(); i.more(); ++i)
  36. {
  37. (*i)->Release();
  38. }
  39. // Clear the hash table.
  40. cache.clear();
  41. Unlock();
  42. }
  43. DWORD LDAPCache::getServer(PCWSTR hostname, LDAPServer** server) throw ()
  44. {
  45. _ASSERT(server != NULL);
  46. DWORD status = NO_ERROR;
  47. Lock();
  48. // Check if we already have an entry for this hostname.
  49. LDAPServer* const* existing = cache.find(hostname);
  50. if (existing)
  51. {
  52. (*server = *existing)->AddRef();
  53. }
  54. // Otherwise, create a new entry.
  55. else if (*server = LDAPServer::createInstance(hostname))
  56. {
  57. // Periodically evict expired entries. We can be very lazy about this
  58. // since there is no harm in returning an expired entry.
  59. if (cache.size() % 4 == 0)
  60. {
  61. evict();
  62. }
  63. try
  64. {
  65. cache.multi_insert(*server);
  66. // The insert succeeded so AddRef the entry.
  67. (*server)->AddRef();
  68. }
  69. catch (...)
  70. {
  71. // We don't really care that the insert failed since we still have a
  72. // valid server object to return to the client.
  73. }
  74. }
  75. else
  76. {
  77. status = ERROR_NOT_ENOUGH_MEMORY;
  78. }
  79. Unlock();
  80. return status;
  81. }
  82. void LDAPCache::evict() throw ()
  83. {
  84. //////////
  85. // Note: This method is not serialized.
  86. //////////
  87. DWORDLONG now = GetSystemTimeAsDWORDLONG();
  88. ServerTable::iterator i = cache.begin();
  89. while (i.more())
  90. {
  91. if ((*i)->getExpiry() >= now)
  92. {
  93. // The entry has expired, so release and erase.
  94. (*i)->Release();
  95. cache.erase(i);
  96. }
  97. else
  98. {
  99. ++i;
  100. }
  101. }
  102. }