diff options
author | Sree Harsha Totakura <totakura@in.tum.de> | 2013-01-29 13:55:14 +0000 |
---|---|---|
committer | Sree Harsha Totakura <totakura@in.tum.de> | 2013-01-29 13:55:14 +0000 |
commit | 5750bc7ad4ae2b31041d44b1b5211f62462e66ec (patch) | |
tree | df96e0352c2176375ee6a851ae38f81331c41e64 /src | |
parent | 13010a7ad8f3756733bbc67242cf1c90e60641cd (diff) | |
download | gnunet-5750bc7ad4ae2b31041d44b1b5211f62462e66ec.tar.gz gnunet-5750bc7ad4ae2b31041d44b1b5211f62462e66ec.zip |
- queue requests for accessing handles from cache
Diffstat (limited to 'src')
-rw-r--r-- | src/testbed/gnunet-service-testbed_hc.c | 128 |
1 files changed, 78 insertions, 50 deletions
diff --git a/src/testbed/gnunet-service-testbed_hc.c b/src/testbed/gnunet-service-testbed_hc.c index de35c91e0..fdbff1192 100644 --- a/src/testbed/gnunet-service-testbed_hc.c +++ b/src/testbed/gnunet-service-testbed_hc.c | |||
@@ -46,22 +46,16 @@ enum CacheGetType | |||
46 | 46 | ||
47 | struct GSTCacheGetHandle | 47 | struct GSTCacheGetHandle |
48 | { | 48 | { |
49 | struct GNUNET_TESTBED_Operation *op; | 49 | struct GSTCacheGetHandle *next; |
50 | |||
51 | struct CacheEntry *entry; | ||
52 | |||
53 | struct GNUNET_CORE_Handle *ch; | ||
54 | 50 | ||
55 | struct GNUNET_TRANSPORT_Handle *th; | 51 | struct GSTCacheGetHandle *prev; |
56 | |||
57 | void *handle; | ||
58 | 52 | ||
53 | struct CacheEntry *entry; | ||
54 | |||
59 | GST_cache_callback cb; | 55 | GST_cache_callback cb; |
60 | 56 | ||
61 | void *cb_cls; | 57 | void *cb_cls; |
62 | 58 | ||
63 | GNUNET_SCHEDULER_TaskIdentifier notify_task; | ||
64 | |||
65 | enum CacheGetType type; | 59 | enum CacheGetType type; |
66 | 60 | ||
67 | int notify_called; | 61 | int notify_called; |
@@ -99,13 +93,6 @@ struct CacheEntry | |||
99 | struct GNUNET_CONFIGURATION_Handle *cfg; | 93 | struct GNUNET_CONFIGURATION_Handle *cfg; |
100 | 94 | ||
101 | /** | 95 | /** |
102 | * The cache get handle which created this entry. Will be NULL after the | ||
103 | * operation for creating a core or transport handler is started, i.e. in the | ||
104 | * function opstart_get_handle_transport | ||
105 | */ | ||
106 | struct GSTCacheGetHandle *cgh; | ||
107 | |||
108 | /** | ||
109 | * The key for this entry | 96 | * The key for this entry |
110 | */ | 97 | */ |
111 | struct GNUNET_HashCode key; | 98 | struct GNUNET_HashCode key; |
@@ -116,6 +103,21 @@ struct CacheEntry | |||
116 | struct GNUNET_MessageHeader *hello; | 103 | struct GNUNET_MessageHeader *hello; |
117 | 104 | ||
118 | /** | 105 | /** |
106 | * the head of the CacheGetHandle queue | ||
107 | */ | ||
108 | struct GSTCacheGetHandle *cghq_head; | ||
109 | |||
110 | /** | ||
111 | * the tail of the CacheGetHandle queue | ||
112 | */ | ||
113 | struct GSTCacheGetHandle *cghq_tail; | ||
114 | |||
115 | /** | ||
116 | * The task that calls the cache callback | ||
117 | */ | ||
118 | GNUNET_SCHEDULER_TaskIdentifier notify_task; | ||
119 | |||
120 | /** | ||
119 | * Number of operations this cache entry is being used | 121 | * Number of operations this cache entry is being used |
120 | */ | 122 | */ |
121 | unsigned int demand; | 123 | unsigned int demand; |
@@ -152,6 +154,11 @@ static unsigned int lru_cache_size; | |||
152 | */ | 154 | */ |
153 | static unsigned int lru_cache_threshold_size; | 155 | static unsigned int lru_cache_threshold_size; |
154 | 156 | ||
157 | /** | ||
158 | * The total number of elements in cache | ||
159 | */ | ||
160 | static unsigned int cache_size; | ||
161 | |||
155 | 162 | ||
156 | /** | 163 | /** |
157 | * Looks up in the cache and returns the entry | 164 | * Looks up in the cache and returns the entry |
@@ -219,24 +226,30 @@ add_entry (const struct GNUNET_HashCode *key) | |||
219 | GNUNET_CONTAINER_multihashmap_put (cache, &entry->key, | 226 | GNUNET_CONTAINER_multihashmap_put (cache, &entry->key, |
220 | entry, | 227 | entry, |
221 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); | 228 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); |
229 | cache_size++; | ||
222 | return entry; | 230 | return entry; |
223 | } | 231 | } |
224 | 232 | ||
225 | 233 | ||
226 | static void | 234 | static void |
227 | cache_notify_callback (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 235 | call_cgh_cb (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
228 | { | 236 | { |
229 | struct GSTCacheGetHandle *cgh = cls; | 237 | struct CacheEntry *entry = cls; |
230 | 238 | struct GSTCacheGetHandle *cgh; | |
231 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cgh->notify_task); | 239 | |
232 | cgh->notify_task = GNUNET_SCHEDULER_NO_TASK; | 240 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != entry->notify_task); |
233 | GNUNET_assert (NULL != cgh->entry); | 241 | entry->notify_task = GNUNET_SCHEDULER_NO_TASK; |
234 | cgh->entry->demand++; | 242 | cgh = entry->cghq_head; |
243 | GNUNET_assert (GNUNET_NO == cgh->notify_called); | ||
244 | GNUNET_CONTAINER_DLL_remove (entry->cghq_head, entry->cghq_tail, cgh); | ||
235 | cgh->notify_called = GNUNET_YES; | 245 | cgh->notify_called = GNUNET_YES; |
246 | GNUNET_CONTAINER_DLL_insert_tail (entry->cghq_head, entry->cghq_tail, cgh); | ||
247 | if (GNUNET_NO == entry->cghq_head->notify_called) | ||
248 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
236 | switch (cgh->type) | 249 | switch (cgh->type) |
237 | { | 250 | { |
238 | case CGT_TRANSPORT_HANDLE: | 251 | case CGT_TRANSPORT_HANDLE: |
239 | cgh->cb (cgh->cb_cls, NULL, cgh->handle); | 252 | cgh->cb (cgh->cb_cls, NULL, entry->transport_handle); |
240 | break; | 253 | break; |
241 | } | 254 | } |
242 | } | 255 | } |
@@ -246,13 +259,9 @@ static void | |||
246 | opstart_get_handle_transport (void *cls) | 259 | opstart_get_handle_transport (void *cls) |
247 | { | 260 | { |
248 | struct CacheEntry *entry = cls; | 261 | struct CacheEntry *entry = cls; |
249 | struct GSTCacheGetHandle *cgh = entry->cgh; | ||
250 | 262 | ||
251 | GNUNET_assert (NULL != entry); | 263 | GNUNET_assert (NULL != entry); |
252 | GNUNET_assert (NULL != cgh); | ||
253 | GNUNET_assert (NULL != entry->cfg); | ||
254 | LOG_DEBUG ("Opening a transport connection\n"); | 264 | LOG_DEBUG ("Opening a transport connection\n"); |
255 | entry->cgh = NULL; | ||
256 | entry->transport_handle = GNUNET_TRANSPORT_connect (entry->cfg, | 265 | entry->transport_handle = GNUNET_TRANSPORT_connect (entry->cfg, |
257 | NULL, NULL, | 266 | NULL, NULL, |
258 | NULL, | 267 | NULL, |
@@ -263,9 +272,11 @@ opstart_get_handle_transport (void *cls) | |||
263 | GNUNET_break (0); | 272 | GNUNET_break (0); |
264 | return; | 273 | return; |
265 | } | 274 | } |
266 | cgh->handle = entry->transport_handle; | 275 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task); |
267 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == cgh->notify_task); | 276 | if (0 == entry->demand) |
268 | cgh->notify_task = GNUNET_SCHEDULER_add_now (&cache_notify_callback, cgh); | 277 | return; |
278 | if (GNUNET_NO == entry->cghq_head->notify_called) | ||
279 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
269 | } | 280 | } |
270 | 281 | ||
271 | 282 | ||
@@ -287,13 +298,11 @@ cache_get_handle (unsigned int peer_id, | |||
287 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 298 | const struct GNUNET_CONFIGURATION_Handle *cfg) |
288 | { | 299 | { |
289 | struct GNUNET_HashCode key; | 300 | struct GNUNET_HashCode key; |
290 | struct GNUNET_CORE_Handle *ch; | ||
291 | void *handle; | 301 | void *handle; |
292 | struct CacheEntry *entry; | 302 | struct CacheEntry *entry; |
293 | 303 | ||
294 | GNUNET_assert (0 != cgh->type); | 304 | GNUNET_assert (0 != cgh->type); |
295 | GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); | 305 | GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); |
296 | ch = NULL; | ||
297 | handle = NULL; | 306 | handle = NULL; |
298 | entry = NULL; | 307 | entry = NULL; |
299 | switch (cgh->type) | 308 | switch (cgh->type) |
@@ -306,18 +315,20 @@ cache_get_handle (unsigned int peer_id, | |||
306 | { | 315 | { |
307 | GNUNET_assert (NULL != entry); | 316 | GNUNET_assert (NULL != entry); |
308 | LOG_DEBUG ("Found existing transport handle in cache\n"); | 317 | LOG_DEBUG ("Found existing transport handle in cache\n"); |
309 | cgh->entry = entry; | ||
310 | cgh->ch = ch; | ||
311 | cgh->handle = handle; | ||
312 | cgh->notify_task = GNUNET_SCHEDULER_add_now (&cache_notify_callback, cgh); | ||
313 | return cgh; | ||
314 | } | 318 | } |
315 | if (NULL == entry) | 319 | if (NULL == entry) |
316 | entry = add_entry (&key); | 320 | entry = add_entry (&key); |
317 | if (NULL == entry->cfg) | 321 | if (NULL == entry->cfg) |
318 | entry->cfg = GNUNET_CONFIGURATION_dup (cfg); | 322 | entry->cfg = GNUNET_CONFIGURATION_dup (cfg); |
323 | entry->demand++; | ||
319 | cgh->entry = entry; | 324 | cgh->entry = entry; |
320 | entry->cgh = cgh; | 325 | GNUNET_CONTAINER_DLL_insert (entry->cghq_head, entry->cghq_tail, cgh); |
326 | if (NULL != handle) | ||
327 | { | ||
328 | if (GNUNET_SCHEDULER_NO_TASK == entry->notify_task) | ||
329 | entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry); | ||
330 | return cgh; | ||
331 | } | ||
321 | switch (cgh->type) | 332 | switch (cgh->type) |
322 | { | 333 | { |
323 | case CGT_TRANSPORT_HANDLE: | 334 | case CGT_TRANSPORT_HANDLE: |
@@ -349,11 +360,15 @@ cache_clear_iterator (void *cls, | |||
349 | void *value) | 360 | void *value) |
350 | { | 361 | { |
351 | struct CacheEntry *entry = value; | 362 | struct CacheEntry *entry = value; |
363 | static unsigned int ncleared; | ||
352 | 364 | ||
353 | GNUNET_assert (NULL != entry); | 365 | GNUNET_assert (NULL != entry); |
366 | GNUNET_break (0 == entry->demand); | ||
367 | LOG_DEBUG ("Clearing entry %u of %u\n", ++ncleared, cache_size); | ||
354 | GNUNET_CONTAINER_multihashmap_remove (cache, key, value); | 368 | GNUNET_CONTAINER_multihashmap_remove (cache, key, value); |
355 | GNUNET_free_non_null (entry->hello); | 369 | GNUNET_free_non_null (entry->hello); |
356 | GNUNET_break (NULL == entry->transport_handle); | 370 | GNUNET_break (NULL == entry->transport_handle); |
371 | GNUNET_break (NULL == entry->cfg); | ||
357 | GNUNET_free (entry); | 372 | GNUNET_free (entry); |
358 | return GNUNET_YES; | 373 | return GNUNET_YES; |
359 | } | 374 | } |
@@ -397,17 +412,28 @@ GST_cache_init (unsigned int size) | |||
397 | void | 412 | void |
398 | GST_cache_get_handle_done (struct GSTCacheGetHandle *cgh) | 413 | GST_cache_get_handle_done (struct GSTCacheGetHandle *cgh) |
399 | { | 414 | { |
400 | if (GNUNET_SCHEDULER_NO_TASK != cgh->notify_task) | 415 | GNUNET_assert (NULL != cgh->entry); |
401 | GNUNET_SCHEDULER_cancel (cgh->notify_task); | 416 | cgh->entry->demand--; |
402 | if (GNUNET_YES == cgh->notify_called) | 417 | if (GNUNET_NO == cgh->entry->cghq_head->notify_called) |
418 | GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != cgh->entry->notify_task); | ||
419 | if (GNUNET_SCHEDULER_NO_TASK != cgh->entry->notify_task) | ||
420 | { | ||
421 | GNUNET_SCHEDULER_cancel (cgh->entry->notify_task); | ||
422 | cgh->entry->notify_task = GNUNET_SCHEDULER_NO_TASK; | ||
423 | } | ||
424 | GNUNET_CONTAINER_DLL_remove (cgh->entry->cghq_head, | ||
425 | cgh->entry->cghq_tail, | ||
426 | cgh); | ||
427 | if (0 == cgh->entry->demand) | ||
428 | { | ||
429 | GNUNET_CONTAINER_DLL_insert_tail (lru_cache_head, lru_cache_tail, cgh->entry); | ||
430 | if (lru_cache_size > lru_cache_threshold_size) | ||
431 | cache_remove (lru_cache_head); | ||
432 | } | ||
433 | else | ||
403 | { | 434 | { |
404 | cgh->entry->demand--; | 435 | if (GNUNET_NO == cgh->entry->cghq_head->notify_called) |
405 | if (0 == cgh->entry->demand) | 436 | cgh->entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, cgh->entry); |
406 | { | ||
407 | GNUNET_CONTAINER_DLL_insert_tail (lru_cache_head, lru_cache_tail, cgh->entry); | ||
408 | if (lru_cache_size > lru_cache_threshold_size) | ||
409 | cache_remove (lru_cache_head); | ||
410 | } | ||
411 | } | 437 | } |
412 | GNUNET_free (cgh); | 438 | GNUNET_free (cgh); |
413 | } | 439 | } |
@@ -455,10 +481,12 @@ GST_cache_lookup_hello (const unsigned int peer_id) | |||
455 | struct CacheEntry *entry; | 481 | struct CacheEntry *entry; |
456 | struct GNUNET_HashCode key; | 482 | struct GNUNET_HashCode key; |
457 | 483 | ||
484 | LOG_DEBUG ("Looking up HELLO for peer %u\n", peer_id); | ||
458 | GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); | 485 | GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key); |
459 | entry = cache_lookup (&key); | 486 | entry = cache_lookup (&key); |
460 | if (NULL == entry) | 487 | if (NULL == entry) |
461 | return NULL; | 488 | return NULL; |
489 | LOG_DEBUG ("HELLO found for peer %u\n", peer_id); | ||
462 | return entry->hello; | 490 | return entry->hello; |
463 | } | 491 | } |
464 | 492 | ||