+#define TUNNEL_DESTROY_EMPTY_TIME GNUNET_TIME_UNIT_MILLISECONDS
+
+/**
+ * Tunnel is empty: destroy it.
+ *
+ * @param cls Closure (Tunnel).
+ * @param tc TaskContext.
+ */
+static void
+tunnel_destroy_empty_delayed (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+ struct MeshTunnel *t = cls;
+
+ t->delayed_destroy = GNUNET_SCHEDULER_NO_TASK;
+ if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+ return;
+
+ if (0 != t->nclients ||
+ 0 != tree_count_children (t->tree))
+ return;
+
+ #if MESH_DEBUG
+ {
+ struct GNUNET_PeerIdentity id;
+
+ GNUNET_PEER_resolve (t->id.oid, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "executing destruction of empty tunnel %s [%X]\n",
+ GNUNET_i2s (&id), t->id.tid);
+ }
+ #endif
+
+ tunnel_destroy (t);
+}
+
+
+/**
+ * Schedule tunnel destruction if is empty and no new traffic comes in a time.
+ *
+ * @param t Tunnel to destroy if empty.
+ */
+static void
+tunnel_destroy_empty (struct MeshTunnel *t)
+{
+ if (GNUNET_SCHEDULER_NO_TASK != t->delayed_destroy ||
+ 0 != t->nclients ||
+ 0 != tree_count_children (t->tree))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "%u %u %u\n",
+ t->delayed_destroy, t->nclients, tree_count_children(t->tree));
+ return;
+ }
+
+ #if MESH_DEBUG
+ {
+ struct GNUNET_PeerIdentity id;
+
+ GNUNET_PEER_resolve (t->id.oid, &id);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
+ "scheduling destruction of empty tunnel %s [%X]\n",
+ GNUNET_i2s (&id), t->id.tid);
+ }
+ #endif
+
+ t->delayed_destroy =
+ GNUNET_SCHEDULER_add_delayed (TUNNEL_DESTROY_EMPTY_TIME,
+ &tunnel_destroy_empty_delayed,
+ t);
+}
+