[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r25945 - gnunet/src/testbed
From: |
gnunet |
Subject: |
[GNUnet-SVN] r25945 - gnunet/src/testbed |
Date: |
Wed, 30 Jan 2013 16:06:52 +0100 |
Author: harsha
Date: 2013-01-30 16:06:52 +0100 (Wed, 30 Jan 2013)
New Revision: 25945
Modified:
gnunet/src/testbed/gnunet-service-testbed_hc.c
Log:
towards caching CORE handles
Modified: gnunet/src/testbed/gnunet-service-testbed_hc.c
===================================================================
--- gnunet/src/testbed/gnunet-service-testbed_hc.c 2013-01-30 13:38:49 UTC
(rev 25944)
+++ gnunet/src/testbed/gnunet-service-testbed_hc.c 2013-01-30 15:06:52 UTC
(rev 25945)
@@ -36,6 +36,26 @@
GNUNET_log_from (kind, "testbed-cache", __VA_ARGS__)
+/**
+ * Type of cache-get requests
+ */
+enum CacheGetType
+{
+ /**
+ * Get transport handle
+ */
+ CGT_TRANSPORT_HANDLE = 1,
+
+ /**
+ * Get core handle
+ */
+ CGT_CORE_HANDLE
+};
+
+
+/**
+ * The cache-get request handle
+ */
struct GSTCacheGetHandle;
@@ -78,28 +98,49 @@
};
-enum CacheGetType
-{
- CGT_TRANSPORT_HANDLE = 1
-};
-
-
+/**
+ * The cache-get request handle
+ */
struct GSTCacheGetHandle
{
+ /**
+ * The next ptr for the DLL. Used in struct CacheEntry
+ */
struct GSTCacheGetHandle *next;
+ /**
+ * The prev ptr for the DLL. Used in struct CacheEntry
+ */
struct GSTCacheGetHandle *prev;
+ /**
+ * The cache entry object this handle corresponds to
+ */
struct CacheEntry *entry;
+ /**
+ * The cache callback to call when a handle is available
+ */
GST_cache_callback cb;
+ /**
+ * The closure for the above callback
+ */
void *cb_cls;
+ /**
+ * The peer connect notify context created for this handle; can be NULL
+ */
struct ConnectNotifyContext *nctxt;
+ /**
+ * The type of this cache-get request
+ */
enum CacheGetType type;
+ /**
+ * Did we call the cache callback already?
+ */
int notify_called;
};
@@ -121,14 +162,24 @@
/**
* The transport handle to the peer corresponding to this entry; can be NULL
*/
- struct GNUNET_TRANSPORT_Handle *transport_handle;
+ struct GNUNET_TRANSPORT_Handle *transport_handle_;
/**
* The operation handle for transport handle
*/
- struct GNUNET_TESTBED_Operation *transport_op;
+ struct GNUNET_TESTBED_Operation *transport_op_;
/**
+ * The core handle to the peer corresponding to this entry; can be NULL
+ */
+ struct GNUNET_CORE_Handle *core_handle;
+
+ /**
+ * The operation handle for core handle
+ */
+ struct GNUNET_TESTBED_Operation *core_op;
+
+ /**
* The configuration of the peer. Should be not NULL as long as the
core_handle
* or transport_handle are valid
*/
@@ -239,16 +290,19 @@
static struct CacheEntry *
cache_lookup_handles (const struct GNUNET_HashCode *pid,
- struct GNUNET_TRANSPORT_Handle **th)
+ struct GNUNET_TRANSPORT_Handle **th,
+ struct GNUNET_CORE_Handle **ch)
{
struct CacheEntry *entry;
- GNUNET_assert (NULL != th);
+ GNUNET_assert ((NULL != th) || (NULL != ch));
entry = cache_lookup (pid);
if (NULL == entry)
return NULL;
- if (NULL != entry->transport_handle)
- *th = entry->transport_handle;
+ if ((NULL != entry->transport_handle_) && (NULL != th))
+ *th = entry->transport_handle_;
+ if ((NULL != entry->core_handle) && (NULL != ch))
+ *ch = entry->core_handle;
return entry;
}
@@ -256,18 +310,31 @@
static void
cache_remove (struct CacheEntry *entry)
{
+ struct ConnectNotifyContext *ctxt;
+
/* We keep the entry in the hash table so that the HELLO can still be found
in cache; we will however disconnect the core and transport handles */
GNUNET_assert (0 == entry->demand);
if ((NULL != entry->next) || (NULL != entry->prev))
GNUNET_CONTAINER_DLL_remove (lru_cache_head, lru_cache_tail, entry);
+ while (NULL != (ctxt = entry->nctxt_qhead))
+ {
+ GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt);
+ GNUNET_free (ctxt);
+ }
LOG_DEBUG ("Cleaning up handles from an entry in cache\n");
- if (NULL != entry->transport_handle)
+ if (NULL != entry->transport_handle_)
{
- GNUNET_assert (NULL != entry->transport_op);
- GNUNET_TESTBED_operation_done (entry->transport_op);
- entry->transport_op = NULL;
+ GNUNET_assert (NULL != entry->transport_op_);
+ GNUNET_TESTBED_operation_done (entry->transport_op_);
+ entry->transport_op_ = NULL;
}
+ if (NULL != entry->core_handle)
+ {
+ GNUNET_assert (NULL != entry->core_op);
+ GNUNET_TESTBED_operation_done (entry->core_op);
+ entry->core_op = NULL;
+ }
if (NULL != entry->cfg)
{
GNUNET_CONFIGURATION_destroy (entry->cfg);
@@ -311,8 +378,11 @@
switch (cgh->type)
{
case CGT_TRANSPORT_HANDLE:
- cgh->cb (cgh->cb_cls, NULL, entry->transport_handle);
+ cgh->cb (cgh->cb_cls, NULL, entry->transport_handle_);
break;
+ case CGT_CORE_HANDLE:
+ cgh->cb (cgh->cb_cls, entry->core_handle, NULL);
+ break;
}
}
@@ -361,17 +431,17 @@
GNUNET_assert (NULL != entry);
LOG_DEBUG ("Opening a transport connection to peer %u\n", entry->peer_id);
- entry->transport_handle = GNUNET_TRANSPORT_connect (entry->cfg,
+ entry->transport_handle_ = GNUNET_TRANSPORT_connect (entry->cfg,
NULL, entry,
NULL,
&peer_connect_notify_cb,
NULL);
- if (NULL == entry->transport_handle)
+ if (NULL == entry->transport_handle_)
{
GNUNET_break (0);
return;
}
- GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task);
+ //GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task);
if (0 == entry->demand)
return;
if (GNUNET_NO == entry->cgh_qhead->notify_called)
@@ -383,17 +453,97 @@
oprelease_get_handle_transport (void *cls)
{
struct CacheEntry *entry = cls;
- struct ConnectNotifyContext *ctxt;
- while (NULL != (ctxt = entry->nctxt_qhead))
+ if (NULL == entry->transport_handle_)
+ return;
+ GNUNET_TRANSPORT_disconnect (entry->transport_handle_);
+ entry->transport_handle_ = NULL;
+}
+
+
+/**
+ * Function called after GNUNET_CORE_connect has succeeded (or failed
+ * for good). Note that the private key of the peer is intentionally
+ * not exposed here; if you need it, your process should try to read
+ * the private key file directly (which should work if you are
+ * authorized...). Implementations of this function must not call
+ * GNUNET_CORE_disconnect (other than by scheduling a new task to
+ * do this later).
+ *
+ * @param cls closure
+ * @param server handle to the server, NULL if we failed
+ * @param my_identity ID of this peer, NULL if we failed
+ */
+static void core_startup_cb (void *cls,
+ struct GNUNET_CORE_Handle * server,
+ const struct GNUNET_PeerIdentity *
+ my_identity)
+{
+ GNUNET_break (0);
+}
+
+
+/**
+ * Method called whenever a given peer connects.
+ *
+ * @param cls closure
+ * @param peer peer identity this notification is about
+ * @param atsi performance data for the connection
+ * @param atsi_count number of records in 'atsi'
+ */
+static void
+core_peer_connect_cb (void *cls,
+ const struct GNUNET_PeerIdentity * peer,
+ const struct GNUNET_ATS_Information * atsi,
+ unsigned int atsi_count)
+{
+ struct CacheEntry *entry = cls;
+
+ if (0 == entry->demand)
+ return;
+ if (GNUNET_NO == entry->cgh_qhead->notify_called)
+ entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
+}
+
+
+static void
+opstart_get_handle_core (void *cls)
+{
+ struct CacheEntry *entry = cls;
+ const struct GNUNET_CORE_MessageHandler no_handlers[] = {
+ {NULL, 0, 0}
+ };
+
+ GNUNET_assert (NULL != entry);
+ LOG_DEBUG ("Opening a CORE connection to peer %u\n", entry->peer_id);
+ entry->core_handle = GNUNET_CORE_connect (entry->cfg,
+ entry,
+ &core_startup_cb,
+ &core_peer_connect_cb,
+ NULL, /* disconnect cb */
+ NULL, /* inbound notify */
+ GNUNET_NO,
+ NULL, /* outbound notify */
+ GNUNET_NO,
+ no_handlers);
+ if (NULL == entry->core_handle)
{
- GNUNET_CONTAINER_DLL_remove (entry->nctxt_qhead, entry->nctxt_qtail, ctxt);
- GNUNET_free (ctxt);
+ GNUNET_break (0);
+ return;
}
- if (NULL == entry->transport_handle)
+ //GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == entry->notify_task);
+}
+
+
+static void
+oprelease_get_handle_core (void *cls)
+{
+ struct CacheEntry *entry = cls;
+
+ if (NULL == entry->core_handle)
return;
- GNUNET_TRANSPORT_disconnect (entry->transport_handle);
- entry->transport_handle = NULL;
+ GNUNET_CORE_disconnect (entry->core_handle);
+ entry->core_handle = NULL;
}
@@ -409,6 +559,7 @@
void *handle;
struct CacheEntry *entry;
struct ConnectNotifyContext *ctxt;
+ struct GNUNET_TESTBED_Operation *op;
GNUNET_assert (0 != cgh->type);
GNUNET_CRYPTO_hash (&peer_id, sizeof (peer_id), &key);
@@ -417,8 +568,13 @@
switch (cgh->type)
{
case CGT_TRANSPORT_HANDLE:
- entry = cache_lookup_handles (&key, (struct GNUNET_TRANSPORT_Handle **)
&handle);
+ entry = cache_lookup_handles (&key, (struct GNUNET_TRANSPORT_Handle **)
+ &handle, NULL);
break;
+ case CGT_CORE_HANDLE:
+ entry = cache_lookup_handles (&key, NULL,
+ (struct GNUNET_CORE_Handle **) &handle);
+ break;
}
if (NULL != handle)
{
@@ -445,25 +601,31 @@
ctxt->cgh = cgh;
GNUNET_CONTAINER_DLL_insert_tail (entry->nctxt_qhead, entry->nctxt_qtail,
ctxt);
}
- if ((NULL != entry->transport_handle)
- && (GNUNET_SCHEDULER_NO_TASK == entry->notify_task))
+ if (NULL != handle)
{
- entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
+ if (GNUNET_SCHEDULER_NO_TASK == entry->notify_task)
+ entry->notify_task = GNUNET_SCHEDULER_add_now (&call_cgh_cb, entry);
return cgh;
}
- if (NULL != entry->transport_op)
- return cgh;
switch (cgh->type)
{
case CGT_TRANSPORT_HANDLE:
- GNUNET_assert (NULL == entry->transport_op);
- entry->transport_op = GNUNET_TESTBED_operation_create_ (entry,
&opstart_get_handle_transport,
-
&oprelease_get_handle_transport);
- GNUNET_TESTBED_operation_queue_insert_ (GST_opq_openfds,
- entry->transport_op);
- GNUNET_TESTBED_operation_begin_wait_ (entry->transport_op);
+ if (NULL != entry->transport_op_)
+ return cgh;
+ op = GNUNET_TESTBED_operation_create_ (entry,
&opstart_get_handle_transport,
+ &oprelease_get_handle_transport);
+ entry->transport_op_ = op;
break;
+ case CGT_CORE_HANDLE:
+ if (NULL != entry->core_op)
+ return cgh;
+ op = GNUNET_TESTBED_operation_create_ (entry, &opstart_get_handle_core,
+ &oprelease_get_handle_core);
+ entry->core_op = op;
+ break;
}
+ GNUNET_TESTBED_operation_queue_insert_ (GST_opq_openfds, op);
+ GNUNET_TESTBED_operation_begin_wait_ (op);
return cgh;
}
@@ -492,7 +654,10 @@
if (0 == entry->demand)
cache_remove (entry);
GNUNET_free_non_null (entry->hello);
- GNUNET_break (NULL == entry->transport_handle);
+ GNUNET_break (NULL == entry->transport_handle_);
+ GNUNET_break (NULL == entry->transport_op_);
+ GNUNET_break (NULL == entry->core_handle);
+ GNUNET_break (NULL == entry->core_op);
GNUNET_break (NULL == entry->cfg);
GNUNET_assert (NULL == entry->cgh_qhead);
GNUNET_assert (NULL == entry->cgh_qtail);
@@ -616,6 +781,46 @@
/**
+ * Get a transport handle with the given configuration. If the handle is
already
+ * cached before, it will be retured in the given callback; the peer_id is
used to lookup in the
+ * cache. If not a new operation is started to open the transport handle and
+ * will be given in the callback when it is available.
+ *
+ * @param peer_id the index of the peer
+ * @param cfg the configuration with which the transport handle has to be
+ * created if it was not present in the cache
+ * @param cb the callback to notify when the transport handle is available
+ * @param cb_cls the closure for the above callback
+ * @param target the peer identify of the peer whose connection to our
TRANSPORT
+ * subsystem will be notified through the connect_notify_cb. Can be
NULL
+ * @param connect_notify_cb the callback to call when the given target peer is
+ * connected. This callback will only be called once or never again
(in
+ * case the target peer cannot be connected). Can be NULL
+ * @param connect_notify_cb_cls the closure for the above callback
+ * @return the handle which can be used cancel or mark that the handle is no
+ * longer being used
+ */
+struct GSTCacheGetHandle *
+GST_cache_get_handle_core (unsigned int peer_id,
+ const struct GNUNET_CONFIGURATION_Handle *cfg,
+ GST_cache_callback cb,
+ void *cb_cls,
+ const struct GNUNET_PeerIdentity *target,
+ GST_cache_peer_connect_notify connect_notify_cb,
+ void *connect_notify_cb_cls)
+{
+ struct GSTCacheGetHandle *cgh;
+
+ cgh = GNUNET_malloc (sizeof (struct GSTCacheGetHandle));
+ cgh->cb = cb;
+ cgh->cb_cls = cb_cls;
+ cgh->type = CGT_CORE_HANDLE;
+ return cache_get_handle (peer_id, cgh, cfg,
+ target, connect_notify_cb, connect_notify_cb_cls);
+}
+
+
+/**
* Looks up in the hello cache and returns the HELLO of the given peer
*
* @param peer_id the index of the peer whose HELLO has to be looked up
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r25945 - gnunet/src/testbed,
gnunet <=