I've been playing a bit with the Master provider and i noticed that the providers selection algorithm is still unimplemented. Currently, if i've understood the code, the first available provider is always selected:
/* TODO: currently returning even providers that are worse than
priv->min_accuracy, if nothing else is available */
if (gc_master_provider_get_status (provider) ==GEOCLUE_STATUS_AVAILABLE)
{
/* unsubscribe from all providers worse than this */
gc_master_client_unsubscribe_providers (client,l->next,iface);
return provider;
}
I think this shouldn't be a problem, but if im not wrong, it always
selects the manual provider, which is always available. I guess it would
depend on the order of the providers list reading operation, but i've
experimented that most of times the manual provider is selected, even if
the Localnet, for instance, is also available.
I've implemented a patch, not very tested yet, trying to face this
problem. I would like to get some feedback about this issue, since i
guess is a well known problem and perhaps you already had some
alternative approaches.
Greetings,
--
Javi
commit db53c08da3249081e9df6e629841ff29ba03891c Author: Javier Fernandez <[email protected]> Date: Thu May 20 18:05:52 2010 +0000 Implements a provider selection algorithm, based on the user requirements and accuracy comparison. diff --git a/src/client.c b/src/client.c index d4650e8..ab00979 100644 --- a/src/client.c +++ b/src/client.c @@ -327,11 +327,18 @@ gc_master_client_get_best_provider (GcMasterClient *client, GList **provider_list, GcInterfaceFlags iface) { + GcMasterClientPrivate *priv = GET_PRIVATE (client); + GcMasterProvider *best_provider = NULL; + GcInterfaceAccuracy *min_accuracy = NULL; GList *l = *provider_list; /* TODO: should maybe choose a acquiring provider if better ones are are not available */ g_debug ("client: choosing best provider"); + min_accuracy = g_new0(GcInterfaceAccuracy, 1); + min_accuracy->interface = iface; + min_accuracy->accuracy_level = priv->min_accuracy; + while (l) { GcMasterProvider *provider = l->data; @@ -348,20 +355,58 @@ gc_master_client_get_best_provider (GcMasterClient *client, continue; } /* provider did not need to be started */ - - /* TODO: currently returning even providers that are worse than priv->min_accuracy, - * if nothing else is available */ - if (gc_master_provider_get_status (provider) == GEOCLUE_STATUS_AVAILABLE) { - /* unsubscribe from all providers worse than this */ - gc_master_client_unsubscribe_providers (client, l->next, iface); - return provider; - } - l = l->next; - } - - /* no provider found */ - gc_master_client_unsubscribe_providers (client, *provider_list, iface); - return NULL; + + /* Avoid evaluating twice the same provider. */ + if (best_provider == provider) { + l = l->next; + continue; + } + + /* Check if provider is available. */ + if (!gc_master_provider_get_status (provider) == GEOCLUE_STATUS_AVAILABLE) { + goto continue_searching; + } + + /* Check if provider mets the requirements. */ + if (!gc_master_provider_is_good (provider, iface, priv->min_accuracy, + priv->require_updates, priv->allowed_resources)) { + + /* There is already a provider which mets the requirements. */ + if (best_provider != NULL) { + goto continue_searching; + } else { + g_warning ("The provider is available but " + "it does not met the requirements.\n" + "Still considered as candidate if " + "there is no better choice."); + } + } + + if (best_provider == NULL) { + best_provider = provider; + l = l->next; + continue; + } + + /* Check if its the best provider. */ + if (0 < gc_master_provider_compare (provider, best_provider, min_accuracy)) { + gc_master_provider_unsubscribe (best_provider, client, iface); + best_provider = provider; + l = l->next; + continue; + } else { + goto continue_searching; + } + + continue_searching: + gc_master_provider_unsubscribe (provider, client, iface); + l = l->next; + } + + /* Free */ + g_free (min_accuracy); + + return best_provider; } static void diff --git a/src/master-provider.c b/src/master-provider.c index 790c043..6a70bf4 100644 --- a/src/master-provider.c +++ b/src/master-provider.c @@ -1301,13 +1301,13 @@ gc_master_provider_compare (GcMasterProvider *a, * providers meet the minimum accuracy requirement */ if ((level_b >= min_level) && (level_a >= min_level)) { - diff = priv_a->required_resources - priv_b->required_resources; + diff = priv_b->required_resources - priv_b->required_resources; if (diff != 0 ) { return diff; } - return level_b - level_a; + return level_a - level_b; } /* one or both do not meet req's, sort by accuracy */ - return level_b - level_a; + return level_a - level_b; }
signature.asc
Description: This is a digitally signed message part
_______________________________________________ GeoClue mailing list [email protected] http://lists.freedesktop.org/mailman/listinfo/geoclue
