X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gio%2Fgsrvtarget.c;h=232da5a345d100aa33e136b1090e69a5570115f7;hb=2e5bd8cf47f9e1559ccc44823a2f321b8ff8c1ea;hp=2e3ee90523c702f205fa70aa43e0405dfac57471;hpb=a28215fa909ef315e596ebd0b41132730aef909d;p=platform%2Fupstream%2Fglib.git
diff --git a/gio/gsrvtarget.c b/gio/gsrvtarget.c
index 2e3ee90..232da5a 100644
--- a/gio/gsrvtarget.c
+++ b/gio/gsrvtarget.c
@@ -15,9 +15,7 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see .
*/
#include "config.h"
@@ -29,7 +27,6 @@
#include
#include
-#include "gioalias.h"
/**
* SECTION:gsrvtarget
@@ -45,12 +42,12 @@
* then connect to whatever host was pointed to by that record.
*
* You can use g_resolver_lookup_service() or
- * g_resolver_lookup_service_async() to find the #GSrvTargets
+ * g_resolver_lookup_service_async() to find the #GSrvTargets
* for a given service. However, if you are simply planning to connect
* to the remote service, you can use #GNetworkService's
* #GSocketConnectable interface and not need to worry about
* #GSrvTarget at all.
- **/
+ */
struct _GSrvTarget {
gchar *hostname;
@@ -66,21 +63,8 @@ struct _GSrvTarget {
* A single target host/port that a network service is running on.
*/
-GType
-g_srv_target_get_type (void)
-{
- static volatile gsize type_volatile = 0;
-
- if (g_once_init_enter (&type_volatile))
- {
- GType type = g_boxed_type_register_static (
- g_intern_static_string ("GSrvTarget"),
- (GBoxedCopyFunc) g_srv_target_copy,
- (GBoxedFreeFunc) g_srv_target_free);
- g_once_init_leave (&type_volatile, type);
- }
- return type_volatile;
-}
+G_DEFINE_BOXED_TYPE (GSrvTarget, g_srv_target,
+ g_srv_target_copy, g_srv_target_free)
/**
* g_srv_target_new:
@@ -91,10 +75,10 @@ g_srv_target_get_type (void)
*
* Creates a new #GSrvTarget with the given parameters.
*
- * You should not need to use this; normally #GSrvTargets are
+ * You should not need to use this; normally #GSrvTargets are
* created by #GResolver.
*
- * Return value: a new #GSrvTarget.
+ * Returns: a new #GSrvTarget.
*
* Since: 2.22
*/
@@ -120,7 +104,7 @@ g_srv_target_new (const gchar *hostname,
*
* Copies @target
*
- * Return value: a copy of @target
+ * Returns: a copy of @target
*
* Since: 2.22
*/
@@ -155,7 +139,7 @@ g_srv_target_free (GSrvTarget *target)
* check if it contains encoded Unicode segments, and use
* g_hostname_to_unicode() to convert it if it does.)
*
- * Return value: @target's hostname
+ * Returns: @target's hostname
*
* Since: 2.22
*/
@@ -171,7 +155,7 @@ g_srv_target_get_hostname (GSrvTarget *target)
*
* Gets @target's port
*
- * Return value: @target's port
+ * Returns: @target's port
*
* Since: 2.22
*/
@@ -189,7 +173,7 @@ g_srv_target_get_port (GSrvTarget *target)
* #GResolver already sorts the targets according to the algorithm in
* RFC 2782.
*
- * Return value: @target's priority
+ * Returns: @target's priority
*
* Since: 2.22
*/
@@ -207,7 +191,7 @@ g_srv_target_get_priority (GSrvTarget *target)
* #GResolver already sorts the targets according to the algorithm in
* RFC 2782.
*
- * Return value: @target's weight
+ * Returns: @target's weight
*
* Since: 2.22
*/
@@ -217,7 +201,7 @@ g_srv_target_get_weight (GSrvTarget *target)
return target->weight;
}
-gint
+static gint
compare_target (gconstpointer a, gconstpointer b)
{
GSrvTarget *ta = (GSrvTarget *)a;
@@ -229,34 +213,28 @@ compare_target (gconstpointer a, gconstpointer b)
* that all those with weight 0 are placed at the beginning of
* the list"
*/
- if (ta->weight == 0)
- return -1;
- else if (tb->weight == 0)
- return 1;
- else
- return g_random_int_range (-1, 1);
+ return ta->weight - tb->weight;
}
else
return ta->priority - tb->priority;
}
/**
- * g_srv_target_list_sort:
+ * g_srv_target_list_sort: (skip)
* @targets: a #GList of #GSrvTarget
*
* Sorts @targets in place according to the algorithm in RFC 2782.
*
- * Return value: the head of the sorted list.
+ * Returns: (transfer full): the head of the sorted list.
*
* Since: 2.22
- */
+ */
GList *
g_srv_target_list_sort (GList *targets)
{
- gint sum, val, priority, weight;
- GList *first, *last, *n;
+ gint sum, num, val, priority, weight;
+ GList *t, *out, *tail;
GSrvTarget *target;
- gpointer tmp;
if (!targets)
return NULL;
@@ -275,63 +253,60 @@ g_srv_target_list_sort (GList *targets)
}
}
- /* Sort by priority, and partly by weight */
+ /* Sort input list by priority, and put the 0-weight targets first
+ * in each priority group. Initialize output list to %NULL.
+ */
targets = g_list_sort (targets, compare_target);
+ out = tail = NULL;
- /* For each group of targets with the same priority, rebalance them
- * according to weight.
+ /* For each group of targets with the same priority, remove them
+ * from @targets and append them to @out in a valid order.
*/
- for (first = targets; first; first = last->next)
+ while (targets)
{
- /* Skip @first to a non-0-weight target. */
- while (first && ((GSrvTarget *)first->data)->weight == 0)
- first = first->next;
- if (!first)
- break;
-
- /* Skip @last to the last target of the same priority. */
- priority = ((GSrvTarget *)first->data)->priority;
- last = first;
- while (last->next &&
- ((GSrvTarget *)last->next->data)->priority == priority)
- last = last->next;
-
- /* If there's only one non-0 weight target at this priority,
- * we can move on to the next priority level.
- */
- if (last == first)
- continue;
-
- /* Randomly reorder the non-0 weight targets, giving precedence
- * to the ones with higher weight. RFC 2782 describes this in
- * terms of assigning a running sum to each target and building
- * a new list. We do things slightly differently, but should get
- * the same result.
+ priority = ((GSrvTarget *)targets->data)->priority;
+
+ /* Count the number of targets at this priority level, and
+ * compute the sum of their weights.
*/
- for (n = first, sum = 0; n != last->next; n = n->next)
- sum += ((GSrvTarget *)n->data)->weight;
- while (first != last)
+ sum = num = 0;
+ for (t = targets; t; t = t->next)
+ {
+ target = (GSrvTarget *)t->data;
+ if (target->priority != priority)
+ break;
+ sum += target->weight;
+ num++;
+ }
+
+ /* While there are still targets at this priority level... */
+ while (num)
{
- val = g_random_int_range (0, sum);
- for (n = first; n != last; n = n->next)
+ /* Randomly select from the targets at this priority level,
+ * giving precedence to the ones with higher weight,
+ * according to the rules from RFC 2782.
+ */
+ val = g_random_int_range (0, sum + 1);
+ for (t = targets; ; t = t->next)
{
- weight = ((GSrvTarget *)n->data)->weight;
- if (val < weight)
+ weight = ((GSrvTarget *)t->data)->weight;
+ if (weight >= val)
break;
val -= weight;
}
- tmp = first->data;
- first->data = n->data;
- n->data = tmp;
+ targets = g_list_remove_link (targets, t);
+
+ if (!out)
+ out = t;
+ else
+ tail->next = t;
+ tail = t;
sum -= weight;
- first = first->next;
+ num--;
}
}
- return targets;
+ return out;
}
-
-#define __G_SRV_TARGET_C__
-#include "gioaliasdef.c"