@@ -156,24 +156,31 @@ struct cache_entry
156156 int validity;
157157 details::http_response_ptr response;
158158 pthread_rwlock_t elem_guard;
159+ pthread_mutex_t lock_guard;
160+ bool locked;
159161
160162 cache_entry ():
161163 ts (-1 ),
162- validity (-1 )
164+ validity (-1 ),
165+ locked (false )
163166 {
164167 pthread_rwlock_init (&elem_guard, NULL );
168+ pthread_mutex_init (&lock_guard, NULL );
165169 }
166170
167171 ~cache_entry ()
168172 {
169173 pthread_rwlock_destroy (&elem_guard);
174+ pthread_mutex_destroy (&lock_guard);
170175 }
171176
172177 cache_entry (const cache_entry& b):
173178 ts (b.ts),
174179 validity (b.validity),
175180 response (b.response),
176- elem_guard (b.elem_guard)
181+ elem_guard (b.elem_guard),
182+ lock_guard (b.lock_guard),
183+ locked (b.locked)
177184 {
178185 }
179186
@@ -183,15 +190,44 @@ struct cache_entry
183190 validity = b.validity ;
184191 response = b.response ;
185192 pthread_rwlock_destroy (&elem_guard);
193+ pthread_mutex_destroy (&lock_guard);
186194 elem_guard = b.elem_guard ;
195+ locked = b.locked ;
187196 }
188197
189198 cache_entry (details::http_response_ptr response, long ts = -1 , int validity = -1 ):
190199 ts (ts),
191200 validity (validity),
192- response (response)
201+ response (response),
202+ locked (false )
193203 {
194204 pthread_rwlock_init (&elem_guard, NULL );
205+ pthread_mutex_init (&lock_guard, NULL );
206+ }
207+
208+ void lock (bool write = false )
209+ {
210+ pthread_mutex_lock (&lock_guard);
211+ if (!locked)
212+ {
213+ if (write)
214+ pthread_rwlock_wrlock (&elem_guard);
215+ else
216+ pthread_rwlock_rdlock (&elem_guard);
217+ locked = true ;
218+ }
219+ pthread_mutex_unlock (&lock_guard);
220+ }
221+
222+ void unlock ()
223+ {
224+ pthread_mutex_lock (&lock_guard);
225+ if (locked)
226+ {
227+ pthread_rwlock_unlock (&elem_guard);
228+ locked = false ;
229+ }
230+ pthread_mutex_unlock (&lock_guard);
195231 }
196232};
197233
@@ -200,7 +236,7 @@ namespace details
200236
201237void unlock_cache_entry (cache_entry* ce)
202238{
203- pthread_rwlock_unlock (& ce->elem_guard );
239+ ce->unlock ( );
204240}
205241
206242http_response* get_response (cache_entry* ce)
@@ -1518,12 +1554,7 @@ http_response* webserver::get_from_cache(const std::string& key, bool* valid, ca
15181554 if (it != cache_m->response_cache .end ())
15191555 {
15201556 if (lock)
1521- {
1522- if (write)
1523- pthread_rwlock_wrlock (&((*it).second .elem_guard ));
1524- else
1525- pthread_rwlock_rdlock (&((*it).second .elem_guard ));
1526- }
1557+ (*it).second .lock (write);
15271558 if ((*it).second .validity != -1 )
15281559 {
15291560 timeval now;
@@ -1574,12 +1605,7 @@ void webserver::lock_cache_element(const std::string& key, bool write)
15741605 pthread_rwlock_rdlock (&cache_guard);
15751606 map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
15761607 if (it != cache_m->response_cache .end ())
1577- {
1578- if (write)
1579- pthread_rwlock_wrlock (&((*it).second .elem_guard ));
1580- else
1581- pthread_rwlock_rdlock (&((*it).second .elem_guard ));
1582- }
1608+ (*it).second .lock (write);
15831609 pthread_rwlock_unlock (&cache_guard);
15841610}
15851611
@@ -1588,32 +1614,25 @@ void webserver::unlock_cache_element(const std::string& key)
15881614 pthread_rwlock_rdlock (&cache_guard);
15891615 map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
15901616 if (it != cache_m->response_cache .end ())
1591- pthread_rwlock_unlock (&(( *it).second .elem_guard ) );
1617+ ( *it).second .unlock ( );
15921618 pthread_rwlock_unlock (&cache_guard);
15931619}
15941620
15951621cache_entry* webserver::put_in_cache (const std::string& key, http_response* value, bool * new_elem, bool lock, bool write, int validity)
15961622{
15971623 pthread_rwlock_wrlock (&cache_guard);
15981624 map<string, cache_entry>::iterator it (cache_m->response_cache .find (key));
1599- bool unlock = false ;
16001625 cache_entry* to_ret;
1626+ bool unlock = false ;
16011627 if (it != cache_m->response_cache .end ())
16021628 {
1603- pthread_rwlock_wrlock (&(( *it).second .elem_guard ) );
1629+ ( *it).second .lock ( true );
16041630 unlock = true ;
16051631 }
16061632 if (validity == -1 )
16071633 {
16081634 pair<map<string, cache_entry>::iterator, bool > res = cache_m->response_cache .insert (pair<string, cache_entry>(key, cache_entry (value)));
16091635 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- }
16171636 *new_elem = res.second ;
16181637 }
16191638 else
@@ -1622,17 +1641,12 @@ cache_entry* webserver::put_in_cache(const std::string& key, http_response* valu
16221641 gettimeofday (&now, NULL );
16231642 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)));
16241643 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- }
16321644 *new_elem = res.second ;
16331645 }
16341646 if (unlock)
1635- pthread_rwlock_unlock (&((*it).second .elem_guard ));
1647+ (*it).second .unlock ();
1648+ if (lock)
1649+ to_ret->lock (write);
16361650 pthread_rwlock_unlock (&cache_guard);
16371651 return to_ret;
16381652}
0 commit comments