Skip to content

Commit 6d943e9

Browse files
author
Sebastiano Merlino
committed
Solved some problem with cache management
1 parent 089f7c7 commit 6d943e9

File tree

3 files changed

+67
-52
lines changed

3 files changed

+67
-52
lines changed

src/httpserver/http_response.hpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ namespace details
5050

5151
using namespace http;
5252

53+
class bad_caching_attempt: public std::exception
54+
{
55+
virtual const char* what() const throw()
56+
{
57+
return "You cannot pass ce = 0x0 without key!";
58+
}
59+
};
60+
61+
5362
class closure_action
5463
{
5564
public:
@@ -636,6 +645,8 @@ class cache_response : public http_response
636645
ce(ce),
637646
locked_element(locked_element)
638647
{
648+
if(ce == 0x0)
649+
throw bad_caching_attempt();
639650
}
640651

641652
cache_response(const http_response& b) : http_response(b) { }

src/httpserver/webserver.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ namespace details
6464
struct cache_manager;
6565
struct daemon_item;
6666
void unlock_cache_entry(cache_entry*);
67+
void lock_cache_entry(cache_entry*);
6768
http_response* get_response(cache_entry*);
6869
}
6970

@@ -335,8 +336,8 @@ class webserver
335336

336337
std::map<details::http_endpoint, http_resource* > registered_resources;
337338

338-
details::cache_manager* cache_m;
339339
pthread_rwlock_t cache_guard;
340+
std::map<std::string, cache_entry*> response_cache;
340341
#ifdef USE_CPP_ZEROX
341342
std::unordered_set<ip_representation> bans;
342343
std::unordered_set<ip_representation> allowances;

src/webserver.cpp

Lines changed: 54 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,6 @@ struct daemon_item
7272
}
7373
};
7474

75-
struct cache_manager
76-
{
77-
std::map<std::string, cache_entry> response_cache;
78-
79-
cache_manager()
80-
{
81-
}
82-
};
83-
8475
struct http_response_ptr
8576
{
8677
public:
@@ -109,7 +100,10 @@ struct http_response_ptr
109100
if((*num_references) == 0)
110101
{
111102
if(res && res->autodelete)
103+
{
112104
delete res;
105+
res = 0x0;
106+
}
113107
delete num_references;
114108
}
115109
else
@@ -137,7 +131,10 @@ struct http_response_ptr
137131
if((*num_references) == 0)
138132
{
139133
if(res && res->autodelete)
134+
{
140135
delete res;
136+
res = 0x0;
137+
}
141138
delete num_references;
142139
}
143140
else
@@ -258,6 +255,11 @@ void unlock_cache_entry(cache_entry* ce)
258255
ce->unlock();
259256
}
260257

258+
void lock_cache_entry(cache_entry* ce)
259+
{
260+
ce->lock();
261+
}
262+
261263
http_response* get_response(cache_entry* ce)
262264
{
263265
return ce->response.ptr();
@@ -425,8 +427,7 @@ webserver::webserver
425427
not_found_resource(not_found_resource),
426428
method_not_allowed_resource(method_not_allowed_resource),
427429
method_not_acceptable_resource(method_not_acceptable_resource),
428-
internal_error_resource(internal_error_resource),
429-
cache_m(new details::cache_manager())
430+
internal_error_resource(internal_error_resource)
430431
{
431432
init(single_resource);
432433
}
@@ -466,8 +467,7 @@ webserver::webserver(const create_webserver& params):
466467
not_found_resource(params._not_found_resource),
467468
method_not_allowed_resource(params._method_not_allowed_resource),
468469
method_not_acceptable_resource(params._method_not_acceptable_resource),
469-
internal_error_resource(params._internal_error_resource),
470-
cache_m(new details::cache_manager())
470+
internal_error_resource(params._internal_error_resource)
471471
{
472472
init(params._single_resource);
473473
}
@@ -509,7 +509,7 @@ webserver& webserver::operator=(const webserver& b)
509509
method_not_allowed_resource = b.method_not_allowed_resource;
510510
method_not_acceptable_resource = b.method_not_acceptable_resource;
511511
internal_error_resource = b.internal_error_resource;
512-
cache_m->response_cache = b.cache_m->response_cache;
512+
response_cache = b.response_cache;
513513
return *this;
514514
}
515515

@@ -546,7 +546,6 @@ webserver::~webserver()
546546
pthread_mutex_destroy(&cleanmux);
547547
pthread_cond_destroy(&cleancond);
548548
#endif //USE_COMET
549-
delete cache_m;
550549
for(vector<details::daemon_item*>::const_iterator it = daemons.begin(); it != daemons.end(); ++it)
551550
delete *it;
552551
}
@@ -1715,29 +1714,29 @@ bool webserver::pop_signaled(int consumer)
17151714

17161715
http_response* webserver::get_from_cache(const std::string& key, bool* valid, bool lock, bool write)
17171716
{
1718-
cache_entry* ce;
1717+
cache_entry* ce = 0x0;
17191718
return get_from_cache(key, valid, &ce, lock, write);
17201719
}
17211720

17221721
http_response* webserver::get_from_cache(const std::string& key, bool* valid, cache_entry** ce, bool lock, bool write)
17231722
{
17241723
pthread_rwlock_rdlock(&cache_guard);
17251724
*valid = true;
1726-
map<string, cache_entry>::iterator it(cache_m->response_cache.find(key));
1727-
if(it != cache_m->response_cache.end())
1725+
map<string, cache_entry*>::iterator it(response_cache.find(key));
1726+
if(it != response_cache.end())
17281727
{
17291728
if(lock)
1730-
(*it).second.lock(write);
1731-
if((*it).second.validity != -1)
1729+
(*it).second->lock(write);
1730+
if((*it).second->validity != -1)
17321731
{
17331732
timeval now;
17341733
gettimeofday(&now, NULL);
1735-
if( now.tv_sec - (*it).second.ts > (*it).second.validity)
1734+
if( now.tv_sec - (*it).second->ts > (*it).second->validity)
17361735
*valid = false;
17371736
}
1738-
*ce = &((*it).second);
1737+
*ce = (*it).second;
17391738
pthread_rwlock_unlock(&cache_guard);
1740-
return (*it).second.response.ptr();
1739+
return (*it).second->response.ptr();
17411740
}
17421741
else
17431742
{
@@ -1750,14 +1749,14 @@ http_response* webserver::get_from_cache(const std::string& key, bool* valid, ca
17501749
bool webserver::is_valid(const std::string& key)
17511750
{
17521751
pthread_rwlock_rdlock(&cache_guard);
1753-
map<string, cache_entry>::iterator it(cache_m->response_cache.find(key));
1754-
if(it != cache_m->response_cache.end())
1752+
map<string, cache_entry*>::iterator it(response_cache.find(key));
1753+
if(it != response_cache.end())
17551754
{
1756-
if((*it).second.validity != -1)
1755+
if((*it).second->validity != -1)
17571756
{
17581757
timeval now;
17591758
gettimeofday(&now, NULL);
1760-
if( now.tv_sec - (*it).second.ts > (*it).second.validity)
1759+
if( now.tv_sec - (*it).second->ts > (*it).second->validity)
17611760
{
17621761
pthread_rwlock_unlock(&cache_guard);
17631762
return false;
@@ -1781,44 +1780,44 @@ bool webserver::is_valid(const std::string& key)
17811780
void webserver::lock_cache_element(const std::string& key, bool write)
17821781
{
17831782
pthread_rwlock_rdlock(&cache_guard);
1784-
map<string, cache_entry>::iterator it(cache_m->response_cache.find(key));
1785-
if(it != cache_m->response_cache.end())
1786-
(*it).second.lock(write);
1783+
map<string, cache_entry*>::iterator it(response_cache.find(key));
1784+
if(it != response_cache.end())
1785+
(*it).second->lock(write);
17871786
pthread_rwlock_unlock(&cache_guard);
17881787
}
17891788

17901789
void webserver::unlock_cache_element(const std::string& key)
17911790
{
17921791
pthread_rwlock_rdlock(&cache_guard);
1793-
map<string, cache_entry>::iterator it(cache_m->response_cache.find(key));
1794-
if(it != cache_m->response_cache.end())
1795-
(*it).second.unlock();
1792+
map<string, cache_entry*>::iterator it(response_cache.find(key));
1793+
if(it != response_cache.end())
1794+
(*it).second->unlock();
17961795
pthread_rwlock_unlock(&cache_guard);
17971796
}
17981797

17991798
cache_entry* webserver::put_in_cache(const std::string& key, http_response* value, bool* new_elem, bool lock, bool write, int validity)
18001799
{
18011800
pthread_rwlock_wrlock(&cache_guard);
1802-
map<string, cache_entry>::iterator it(cache_m->response_cache.find(key));
1801+
map<string, cache_entry*>::iterator it(response_cache.find(key));
18031802
cache_entry* to_ret;
18041803
bool already_in = false;
1805-
if(it != cache_m->response_cache.end())
1804+
if(it != response_cache.end())
18061805
{
1807-
(*it).second.lock(true);
1806+
(*it).second->lock(true);
18081807
already_in = true;
18091808
}
18101809
if(validity == -1)
18111810
{
18121811
if(already_in)
18131812
{
1814-
(*it).second.response = value;
1815-
to_ret = &(*it).second;
1813+
(*it).second->response = value;
1814+
to_ret = (*it).second;
18161815
*new_elem = false;
18171816
}
18181817
else
18191818
{
1820-
pair<map<string, cache_entry>::iterator, bool> res = cache_m->response_cache.insert(pair<string, cache_entry>(key, cache_entry(value)));
1821-
to_ret = &((*res.first).second);
1819+
pair<map<string, cache_entry*>::iterator, bool> res = response_cache.insert(pair<string, cache_entry*>(key, new cache_entry(value)));
1820+
to_ret = (*res.first).second;
18221821
*new_elem = res.second;
18231822
}
18241823
}
@@ -1828,21 +1827,21 @@ cache_entry* webserver::put_in_cache(const std::string& key, http_response* valu
18281827
gettimeofday(&now, NULL);
18291828
if(already_in)
18301829
{
1831-
(*it).second.response = value;
1832-
(*it).second.ts = now.tv_sec;
1833-
(*it).second.validity = validity;
1834-
to_ret = &(*it).second;
1830+
(*it).second->response = value;
1831+
(*it).second->ts = now.tv_sec;
1832+
(*it).second->validity = validity;
1833+
to_ret = (*it).second;
18351834
*new_elem = false;
18361835
}
18371836
else
18381837
{
1839-
pair<map<string, cache_entry>::iterator, bool> res = cache_m->response_cache.insert(pair<string, cache_entry>(key, cache_entry(value, now.tv_sec, validity)));
1840-
to_ret = &((*res.first).second);
1838+
pair<map<string, cache_entry*>::iterator, bool> res = response_cache.insert(pair<string, cache_entry*>(key, new cache_entry(value, now.tv_sec, validity)));
1839+
to_ret = (*res.first).second;
18411840
*new_elem = res.second;
18421841
}
18431842
}
18441843
if(already_in)
1845-
(*it).second.unlock();
1844+
(*it).second->unlock();
18461845
if(lock)
18471846
to_ret->lock(write);
18481847
pthread_rwlock_unlock(&cache_guard);
@@ -1852,16 +1851,20 @@ cache_entry* webserver::put_in_cache(const std::string& key, http_response* valu
18521851
void webserver::remove_from_cache(const std::string& key)
18531852
{
18541853
pthread_rwlock_wrlock(&cache_guard);
1855-
map<string, cache_entry>::iterator it(cache_m->response_cache.find(key));
1856-
if(it != cache_m->response_cache.end())
1857-
cache_m->response_cache.erase(it);
1854+
map<string, cache_entry*>::iterator it(response_cache.find(key));
1855+
if(it != response_cache.end())
1856+
{
1857+
cache_entry* ce = (*it).second;
1858+
response_cache.erase(it);
1859+
delete ce;
1860+
}
18581861
pthread_rwlock_unlock(&cache_guard);
18591862
}
18601863

18611864
void webserver::clean_cache()
18621865
{
18631866
pthread_rwlock_wrlock(&cache_guard);
1864-
cache_m->response_cache.clear();
1867+
response_cache.clear(); //manage this because obviously causes leaks
18651868
pthread_rwlock_unlock(&cache_guard);
18661869
}
18671870

0 commit comments

Comments
 (0)