/**
* Statistics handle
*/
-
struct GNUNET_STATISTICS_Handle *stats;
/**
- * Total number of addresses for solver
+ * Bandwidth changed callback
*/
- unsigned int total_addresses;
+ GAS_bandwidth_changed_cb bw_changed;
/**
- * Number of active addresses for solver
+ * Bandwidth changed callback cls
*/
- unsigned int active_addresses;
+ void *bw_changed_cls;
/**
- * Networks array
+ * ATS function to get preferences
*/
- struct Network *network_entries;
+ GAS_get_preferences get_preferences;
/**
- * Number of networks
+ * Closure for ATS function to get preferences
*/
- unsigned int networks;
+ void *get_preferences_cls;
/**
- * Callback
+ * Bulk lock
*/
- GAS_bandwidth_changed_cb bw_changed;
+ int bulk_lock;
/**
- * Callback cls
+ * Number of changes while solver was locked
*/
- void *bw_changed_cls;
+ int bulk_requests;
+
/**
- * ATS function to get preferences
+ * Total number of addresses for solver
*/
- GAS_get_preferences get_preferences;
+ unsigned int total_addresses;
/**
- * Closure for ATS function to get preferences
+ * Number of active addresses for solver
*/
- void *get_preferences_cls;
+ unsigned int active_addresses;
- struct GNUNET_CONTAINER_MultiHashMap *prefs;
+ /**
+ * Networks array
+ */
+ struct Network *network_entries;
+
+ /**
+ * Number of networks
+ */
+ unsigned int networks;
- struct PreferenceClient *pc_head;
- struct PreferenceClient *pc_tail;
};
static int
is_bandwidth_available_in_network (struct Network *net)
{
+ GNUNET_assert (NULL != net);
unsigned int na = net->active_addresses + 1;
uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
if (((net->total_quota_in / na) > min_bw) &&
unsigned long long assigned_quota_out = 0;
struct AddressWrapper *cur;
+
+ if (GNUNET_YES == s->bulk_lock)
+ {
+ s->bulk_requests++;
+ return;
+ }
+
LOG (GNUNET_ERROR_TYPE_DEBUG,
"Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
net->desc, net->active_addresses, net->total_quota_in, net->total_quota_in);
distribute_bandwidth_in_all_networks (struct GAS_PROPORTIONAL_Handle *s)
{
int i;
+
for (i = 0; i < s->networks; i++)
distribute_bandwidth_in_network (s, &s->network_entries[i], NULL);
{
if (s->network_entries[c].type == type)
return &s->network_entries[c];
+
}
return NULL;
}
struct GAS_PROPORTIONAL_Handle *s = solver;
GNUNET_assert (NULL != solver);
GNUNET_assert (NULL != peer);
- distribute_bandwidth_in_all_networks (s);
+
+ distribute_bandwidth_in_all_networks (s);
}
/**
(GNUNET_NO == cur->active) ? "inactive" : "active",
cur, GNUNET_i2s (peer));
net_cur = (struct Network *) cur->solver_information;
+ if (NULL == cur)
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR, "Trying to suggesting unknown address peer `%s'\n",
+ GNUNET_i2s (peer));
+ GNUNET_break (0);
+ return NULL;
+ }
if (GNUNET_YES == cur->active)
{
/* This address was selected previously, so no need to update quotas */
s->bw_changed (s->bw_changed_cls, prev); /* notify about bw change, REQUIRED? */
if (GNUNET_SYSERR == addresse_decrement (s, net_prev, GNUNET_NO, GNUNET_YES))
GNUNET_break (0);
- distribute_bandwidth_in_network (s, net_prev, NULL);
+ distribute_bandwidth_in_network (s, net_prev, NULL);
}
if (GNUNET_NO == (is_bandwidth_available_in_network (cur->solver_information)))
cur->active = GNUNET_YES;
addresse_increment(s, net_cur, GNUNET_NO, GNUNET_YES);
distribute_bandwidth_in_network (s, net_cur, cur);
-
return cur;
}
}
+/**
+ * Start a bulk operation
+ *
+ * @param solver the solver
+ */
+void
+GAS_proportional_bulk_start (void *solver)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Locking solver for bulk operation ...\n");
+ struct GAS_PROPORTIONAL_Handle *s = (struct GAS_PROPORTIONAL_Handle *) solver;
+
+ GNUNET_assert (NULL != solver);
+ s->bulk_lock ++;
+}
+
+/**
+ * Bulk operation done
+ */
+void
+GAS_proportional_bulk_stop (void *solver)
+{
+ LOG (GNUNET_ERROR_TYPE_DEBUG, "Unlocking solver from bulk operation ...\n");
+
+ struct GAS_PROPORTIONAL_Handle *s = (struct GAS_PROPORTIONAL_Handle *) solver;
+ GNUNET_assert (NULL != solver);
+
+ if (s->bulk_lock < 1)
+ {
+ GNUNET_break (0);
+ return;
+ }
+ s->bulk_lock --;
+ if ((0 == s->bulk_lock) && (0 < s->bulk_requests))
+ {
+ LOG (GNUNET_ERROR_TYPE_ERROR, "No lock pending, recalculating\n");
+ distribute_bandwidth_in_all_networks (s);
+ s->bulk_requests = 0;
+ }
+}
+
+
/**
* Add a new single address to a network
*
/* set new network type */
new_net = get_network (solver, addr_net);
+ if (NULL == new_net)
+ {
+ /* Address changed to invalid network... */
+ LOG (GNUNET_ERROR_TYPE_ERROR, _("Cannot find network of type `%u' %s\n"),
+ addr_net, GNUNET_ATS_print_network_type (addr_net));
+ address->assigned_bw_in = GNUNET_BANDWIDTH_value_init (0);
+ address->assigned_bw_out = GNUNET_BANDWIDTH_value_init (0);
+ s->bw_changed (s->bw_changed_cls, address);
+ return;
+ }
address->solver_information = new_net;
/* Add to new network and update*/
s->network_entries = GNUNET_malloc (dest_length * sizeof (struct Network));
s->active_addresses = 0;
s->total_addresses = 0;
- s->prefs = GNUNET_CONTAINER_multihashmap_create (10, GNUNET_NO);
+ s->bulk_lock = GNUNET_NO;
for (c = 0; c < dest_length; c++)
{