Modify CacheMap to avoid race conditions

This commit is contained in:
an-tao 2018-10-09 01:22:17 +08:00
parent f10ccb6e03
commit b87276f4e4
4 changed files with 62 additions and 10 deletions

View File

@ -110,11 +110,7 @@ public:
};
~CacheMap(){
_loop->invalidateTimer(_timerId);
std::lock_guard<std::mutex> lock(bucketMutex_);
for(auto & queue : _wheels)
{
queue.clear();
}
LOG_TRACE<<"CacheMap destruct!";
}
typedef struct MapValue
{
@ -209,7 +205,7 @@ private:
size_t _bucketsNumPerWheel;
void inertEntry(size_t delay,CallbackEntryPtr entryPtr)
void insertEntry(size_t delay,CallbackEntryPtr entryPtr)
{
//protected by bucketMutex;
if(delay<=0)
@ -256,7 +252,7 @@ private:
if(entryPtr)
{
std::lock_guard<std::mutex> lock(bucketMutex_);
inertEntry(delay,entryPtr);
insertEntry(delay,entryPtr);
}
else
{
@ -265,7 +261,10 @@ private:
if(_map.find(key)!=_map.end())
{
auto & value=_map[key];
if(value.timeout>0)
auto entryPtr=value._weakEntryPtr.lock();
//entryPtr is used to avoid race conditions
if(value.timeout>0&&
!entryPtr)
{
if(value._timeoutCallback)
{
@ -282,7 +281,7 @@ private:
{
std::lock_guard<std::mutex> lock(bucketMutex_);
inertEntry(delay,entryPtr);
insertEntry(delay,entryPtr);
}
}
}

View File

@ -3,6 +3,7 @@ if(OpenSSL_FOUND)
link_libraries(ssl crypto)
endif()
add_executable(cache_map_test CacheMapTest.cc)
add_executable(cache_map_test2 CacheMapTest2.cc)
add_executable(cookies_test CookiesTest.cc)
add_executable(class_name_test ClassNameTest.cc)
add_executable(sha1_test Sha1Test.cc)

52
tests/CacheMapTest2.cc Executable file
View File

@ -0,0 +1,52 @@
#include <drogon/CacheMap.h>
#include <trantor/utils/Logger.h>
#include <trantor/net/EventLoopThread.h>
#include <drogon/utils/Utilities.h>
#include <unistd.h>
#include <string>
#include <thread>
#include <iostream>
#include <memory>
int main()
{
trantor::Logger::setLogLevel(trantor::Logger::TRACE);
trantor::EventLoopThread loopThread;
loopThread.run();
auto loop=loopThread.getLoop();
std::shared_ptr<drogon::CacheMap<std::string,std::string>> main_cachePtr;
auto now=trantor::Date::date();
loop->runAt(now.after(1).roundSecond(),[=,&main_cachePtr]()
{
std::shared_ptr<drogon::CacheMap<std::string,std::string>> cachePtr
=std::make_shared<drogon::CacheMap<std::string,std::string>>
(loop,1,3,3);
main_cachePtr=cachePtr;
LOG_DEBUG<<"insert :usecount="<<main_cachePtr.use_count();
cachePtr->insert("1","1",3,[=](){
LOG_DEBUG<<"timeout!erase 1!";
});
cachePtr->insert("2","2",10,[](){
LOG_DEBUG<<"2 timeout";
});
});
trantor::EventLoop mainLoop;
mainLoop.runAt(now.after(3).roundSecond().after(0.0013),[&](){
if(main_cachePtr->find("1"))
{
LOG_DEBUG<<"find item 1";
}
else
{
LOG_DEBUG<<"can't find item 1";
}
});
mainLoop.runAfter(8,[&](){
mainLoop.quit();
});
mainLoop.loop();
}

@ -1 +1 @@
Subproject commit 17ad9d0c8bcb69b357443f42a976c9530acbc283
Subproject commit 9fe1163f535ec8a229a8a37cc059e1b500bde51c