aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSree Harsha Totakura <totakura@in.tum.de>2013-01-29 13:55:14 +0000
committerSree Harsha Totakura <totakura@in.tum.de>2013-01-29 13:55:14 +0000
commit5750bc7ad4ae2b31041d44b1b5211f62462e66ec (patch)
treedf96e0352c2176375ee6a851ae38f81331c41e64 /src
parent13010a7ad8f3756733bbc67242cf1c90e60641cd (diff)
downloadgnunet-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.c128
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
47struct GSTCacheGetHandle 47struct 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 */
153static unsigned int lru_cache_threshold_size; 155static unsigned int lru_cache_threshold_size;
154 156
157/**
158 * The total number of elements in cache
159 */
160static 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
226static void 234static void
227cache_notify_callback (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 235call_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
246opstart_get_handle_transport (void *cls) 259opstart_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)
397void 412void
398GST_cache_get_handle_done (struct GSTCacheGetHandle *cgh) 413GST_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