@@ -58,7 +58,7 @@ namespace details
5858
5959struct cache_manager
6060{
61- std::map<std::string, details:: cache_entry> response_cache;
61+ std::map<std::string, cache_entry> response_cache;
6262
6363 cache_manager ()
6464 {
@@ -148,11 +148,13 @@ struct modded_request
148148 bool second;
149149};
150150
151+ }
152+
151153struct cache_entry
152154{
153155 long ts;
154156 int validity;
155- http_response_ptr response;
157+ details:: http_response_ptr response;
156158 pthread_rwlock_t elem_guard;
157159
158160 cache_entry ():
@@ -184,7 +186,7 @@ struct cache_entry
184186 elem_guard = b.elem_guard ;
185187 }
186188
187- cache_entry (http_response_ptr response, long ts = -1 , int validity = -1 ):
189+ cache_entry (details:: http_response_ptr response, long ts = -1 , int validity = -1 ):
188190 ts (ts),
189191 validity (validity),
190192 response (response)
@@ -193,8 +195,21 @@ struct cache_entry
193195 }
194196};
195197
198+ namespace details
199+ {
200+
201+ void unlock_cache_entry (cache_entry* ce)
202+ {
203+ pthread_rwlock_unlock (&ce->elem_guard );
196204}
197205
206+ http_response* get_response (cache_entry* ce)
207+ {
208+ return ce->response .ptr ();
209+ }
210+
211+ };
212+
198213using namespace http ;
199214
200215int policy_callback (void *, const struct sockaddr *, socklen_t );
@@ -487,6 +502,8 @@ void webserver::sweet_kill()
487502void webserver::request_completed (void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
488503{
489504 details::modded_request* mr = (struct details ::modded_request*) *con_cls;
505+ if (mr->dhrs ->ca != 0x0 )
506+ mr->dhrs ->ca ->do_action ();
490507 if (NULL == mr)
491508 {
492509 return ;
@@ -1488,10 +1505,16 @@ bool webserver::pop_signaled(int consumer)
14881505}
14891506
14901507http_response* webserver::get_from_cache (const std::string& key, bool * valid, bool lock, bool write)
1508+ {
1509+ cache_entry* ce;
1510+ return get_from_cache (key, valid, &ce, lock, write);
1511+ }
1512+
1513+ http_response* webserver::get_from_cache (const std::string& key, bool * valid, cache_entry** ce, bool lock, bool write)
14911514{
14921515 pthread_rwlock_rdlock (&cache_guard);
14931516 *valid = true ;
1494- map<string, details:: cache_entry>::iterator it (cache_m->response_cache .find (key));
1517+ map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
14951518 if (it != cache_m->response_cache .end ())
14961519 {
14971520 if (lock)
@@ -1508,6 +1531,7 @@ http_response* webserver::get_from_cache(const std::string& key, bool* valid, bo
15081531 if ( now.tv_sec - (*it).second .ts > (*it).second .validity )
15091532 *valid = false ;
15101533 }
1534+ *ce = &((*it).second );
15111535 pthread_rwlock_unlock (&cache_guard);
15121536 return (*it).second .response .ptr ();
15131537 }
@@ -1522,7 +1546,7 @@ http_response* webserver::get_from_cache(const std::string& key, bool* valid, bo
15221546bool webserver::is_valid (const std::string& key)
15231547{
15241548 pthread_rwlock_rdlock (&cache_guard);
1525- map<string, details:: cache_entry>::iterator it (cache_m->response_cache .find (key));
1549+ map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
15261550 if (it != cache_m->response_cache .end ())
15271551 {
15281552 if ((*it).second .validity != -1 )
@@ -1548,7 +1572,7 @@ bool webserver::is_valid(const std::string& key)
15481572void webserver::lock_cache_element (const std::string& key, bool write)
15491573{
15501574 pthread_rwlock_rdlock (&cache_guard);
1551- map<string, details:: cache_entry>::iterator it (cache_m->response_cache .find (key));
1575+ map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
15521576 if (it != cache_m->response_cache .end ())
15531577 {
15541578 if (write)
@@ -1562,33 +1586,61 @@ void webserver::lock_cache_element(const std::string& key, bool write)
15621586void webserver::unlock_cache_element (const std::string& key)
15631587{
15641588 pthread_rwlock_rdlock (&cache_guard);
1565- map<string, details:: cache_entry>::iterator it (cache_m->response_cache .find (key));
1589+ map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
15661590 if (it != cache_m->response_cache .end ())
15671591 pthread_rwlock_unlock (&((*it).second .elem_guard ));
15681592 pthread_rwlock_unlock (&cache_guard);
15691593}
15701594
1571- void webserver::put_in_cache (const std::string& key, http_response* value, int validity)
1595+ cache_entry* webserver::put_in_cache (const std::string& key, http_response* value, bool * new_elem, bool lock, bool write , int validity)
15721596{
1597+ pthread_rwlock_wrlock (&cache_guard);
1598+ map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
1599+ bool unlock = false ;
1600+ cache_entry* to_ret;
1601+ if (it != cache_m->response_cache .end ())
1602+ {
1603+ pthread_rwlock_wrlock (&((*it).second .elem_guard ));
1604+ unlock = true ;
1605+ }
15731606 if (validity == -1 )
15741607 {
1575- pthread_rwlock_wrlock (&cache_guard);
1576- cache_m->response_cache .insert (pair<string, details::cache_entry>(key, details::cache_entry (value)));
1608+ pair<map<string, cache_entry>::iterator, bool > res = cache_m->response_cache .insert (pair<string, cache_entry>(key, cache_entry (value)));
1609+ to_ret = &((*res.first ).second );
1610+ if (lock)
1611+ {
1612+ if (write)
1613+ pthread_rwlock_wrlock (&to_ret->elem_guard );
1614+ else
1615+ pthread_rwlock_rdlock (&to_ret->elem_guard );
1616+ }
1617+ *new_elem = res.second ;
15771618 }
15781619 else
15791620 {
1580- pthread_rwlock_wrlock (&cache_guard);
15811621 timeval now;
15821622 gettimeofday (&now, NULL );
1583- cache_m->response_cache .insert (pair<string, details::cache_entry>(key, details::cache_entry (value, now.tv_sec , validity)));
1623+ 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)));
1624+ to_ret = &((*res.first ).second );
1625+ if (lock)
1626+ {
1627+ if (write)
1628+ pthread_rwlock_wrlock (&to_ret->elem_guard );
1629+ else
1630+ pthread_rwlock_rdlock (&to_ret->elem_guard );
1631+ }
1632+ *new_elem = res.second ;
15841633 }
1634+ if (unlock)
1635+ pthread_rwlock_unlock (&((*it).second .elem_guard ));
15851636 pthread_rwlock_unlock (&cache_guard);
1637+ return to_ret;
15861638}
15871639
15881640void webserver::remove_from_cache (const std::string& key)
15891641{
15901642 pthread_rwlock_wrlock (&cache_guard);
1591- map<string, details:: cache_entry>::iterator it (cache_m->response_cache .find (key));
1643+ map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
15921644 if (it != cache_m->response_cache .end ())
15931645 cache_m->response_cache .erase (it);
15941646 pthread_rwlock_unlock (&cache_guard);
0 commit comments