@@ -162,6 +162,27 @@ struct modded_request
162162 http_request* dhr;
163163 http_response_ptr dhrs;
164164 bool second;
165+
166+ modded_request ():
167+ pp (0x0 ),
168+ complete_uri (0x0 ),
169+ ws (0x0 ),
170+ dhr (0x0 ),
171+ dhrs (0x0 ),
172+ second (false )
173+ {
174+ }
175+ ~modded_request ()
176+ {
177+ if (NULL != pp)
178+ {
179+ MHD_destroy_post_processor (pp);
180+ }
181+ if (second)
182+ delete dhr; // TODO: verify. It could be an error
183+ delete complete_uri;
184+ }
185+
165186};
166187
167188}
@@ -173,12 +194,11 @@ struct cache_entry
173194 details::http_response_ptr response;
174195 pthread_rwlock_t elem_guard;
175196 pthread_mutex_t lock_guard;
176- bool locked ;
197+ set< pthread_t > lockers ;
177198
178199 cache_entry ():
179200 ts (-1 ),
180- validity (-1 ),
181- locked (false )
201+ validity (-1 )
182202 {
183203 pthread_rwlock_init (&elem_guard, NULL );
184204 pthread_mutex_init (&lock_guard, NULL );
@@ -195,8 +215,7 @@ struct cache_entry
195215 validity (b.validity),
196216 response (b.response),
197217 elem_guard (b.elem_guard),
198- lock_guard (b.lock_guard),
199- locked (b.locked)
218+ lock_guard (b.lock_guard)
200219 {
201220 }
202221
@@ -208,14 +227,12 @@ struct cache_entry
208227 pthread_rwlock_destroy (&elem_guard);
209228 pthread_mutex_destroy (&lock_guard);
210229 elem_guard = b.elem_guard ;
211- locked = b.locked ;
212230 }
213231
214232 cache_entry (details::http_response_ptr response, long ts = -1 , int validity = -1 ):
215233 ts (ts),
216234 validity (validity),
217- response (response),
218- locked (false )
235+ response (response)
219236 {
220237 pthread_rwlock_init (&elem_guard, NULL );
221238 pthread_mutex_init (&lock_guard, NULL );
@@ -224,24 +241,32 @@ struct cache_entry
224241 void lock (bool write = false )
225242 {
226243 pthread_mutex_lock (&lock_guard);
227- if (!locked )
244+ if (!lockers. count ( pthread_self ()) )
228245 {
229246 if (write)
247+ {
248+ lockers.insert (pthread_self ());
249+ pthread_mutex_unlock (&lock_guard);
230250 pthread_rwlock_wrlock (&elem_guard);
251+ }
231252 else
253+ {
254+ lockers.insert (pthread_self ());
255+ pthread_mutex_unlock (&lock_guard);
232256 pthread_rwlock_rdlock (&elem_guard);
233- locked = true ;
257+ }
234258 }
235- pthread_mutex_unlock (&lock_guard);
259+ else
260+ pthread_mutex_unlock (&lock_guard);
236261 }
237262
238263 void unlock ()
239264 {
240265 pthread_mutex_lock (&lock_guard);
241- if (locked )
266+ if (lockers. count ( pthread_self ()) )
242267 {
268+ lockers.erase (pthread_self ());
243269 pthread_rwlock_unlock (&elem_guard);
244- locked = false ;
245270 }
246271 pthread_mutex_unlock (&lock_guard);
247272 }
@@ -260,9 +285,9 @@ void lock_cache_entry(cache_entry* ce)
260285 ce->lock ();
261286}
262287
263- http_response* get_response (cache_entry* ce)
288+ void get_response (cache_entry* ce, http_response** res )
264289{
265- return ce->response .ptr ();
290+ *res = ce->response .ptr ();
266291}
267292
268293};
@@ -509,7 +534,6 @@ webserver& webserver::operator=(const webserver& b)
509534 method_not_allowed_resource = b.method_not_allowed_resource ;
510535 method_not_acceptable_resource = b.method_not_acceptable_resource ;
511536 internal_error_resource = b.internal_error_resource ;
512- response_cache = b.response_cache ;
513537 return *this ;
514538}
515539
@@ -558,23 +582,12 @@ void webserver::sweet_kill()
558582void webserver::request_completed (void *cls, struct MHD_Connection *connection, void **con_cls, enum MHD_RequestTerminationCode toe)
559583{
560584 details::modded_request* mr = (struct details ::modded_request*) *con_cls;
561- if (mr != 0x0 && mr-> dhrs . res != 0x0 )
585+ if ( 0x0 == mr)
562586 {
563- if (mr->dhrs ->ca != 0x0 )
587+ if (mr->dhrs . res != 0x0 && mr-> dhrs ->ca != 0x0 )
564588 mr->dhrs ->ca ->do_action ();
589+ delete mr;
565590 }
566- if (NULL == mr)
567- {
568- return ;
569- }
570- if (NULL != mr->pp )
571- {
572- MHD_destroy_post_processor (mr->pp );
573- }
574- if (mr->second )
575- delete mr->dhr ; // TODO: verify. It could be an error
576- delete mr->complete_uri ;
577- delete mr;
578591}
579592
580593void webserver::schedule_fd (int fd, fd_set* schedule_list, int * max)
@@ -1443,6 +1456,7 @@ int webserver::finalize_answer(MHD_Connection* connection, struct details::modde
14431456 catch (...)
14441457 {
14451458 internal_error_page (&dhrs, mr, true );
1459+ dhrs->get_raw_response (&raw_response, this );
14461460 }
14471461 dhrs->decorate_response (raw_response);
14481462 to_ret = dhrs->enqueue_response (connection, raw_response);
@@ -1782,8 +1796,18 @@ void webserver::lock_cache_element(const std::string& key, bool write)
17821796 pthread_rwlock_rdlock (&cache_guard);
17831797 map<string, cache_entry*>::iterator it (response_cache.find (key));
17841798 if (it != response_cache.end ())
1799+ {
1800+ pthread_rwlock_unlock (&cache_guard);
17851801 (*it).second ->lock (write);
1786- pthread_rwlock_unlock (&cache_guard);
1802+ }
1803+ else
1804+ pthread_rwlock_unlock (&cache_guard);
1805+ }
1806+
1807+ void webserver::lock_cache_element (cache_entry* ce, bool write)
1808+ {
1809+ if (ce)
1810+ ce->lock (write);
17871811}
17881812
17891813void webserver::unlock_cache_element (const std::string& key)
@@ -1795,6 +1819,12 @@ void webserver::unlock_cache_element(const std::string& key)
17951819 pthread_rwlock_unlock (&cache_guard);
17961820}
17971821
1822+ void webserver::unlock_cache_element (cache_entry* ce)
1823+ {
1824+ if (ce)
1825+ ce->unlock ();
1826+ }
1827+
17981828cache_entry* webserver::put_in_cache (const std::string& key, http_response* value, bool * new_elem, bool lock, bool write, int validity)
17991829{
18001830 pthread_rwlock_wrlock (&cache_guard);
0 commit comments