Author: daf
Update of /cvs/pkgs/rpms/telepathy-salut/OLPC-2
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv7221
Modified Files:
telepathy-salut.spec
Added Files:
salut-olpc-6310.patch
Log Message:
* Fri Feb 29 2008 Dafydd Harries <dafydd.harries(a)collabora.co.uk> - 0.2.2-5.olpc2
-
dev.laptop.org #6310: crash in clique multicast code
salut-olpc-6310.patch:
--- NEW FILE salut-olpc-6310.patch ---
Fri Feb 29 19:54:30 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* Fix some small coding style issues
Fri Feb 29 19:48:48 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticastSender: Don't assume that all packets between ->first_packet,
and ->next_output_paxket exist
Fri Feb 29 18:57:44 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticastSender: Fix repairing when the node has moved to pending_removal
Fri Feb 29 17:57:07 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticastSenderGroup: WHOIS_REQUEST senders should be looked up by
whois_request.sender_id in the packet
Fri Feb 29 17:28:11 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticastSenderGroup: Fixed a silly bug where the condition in the forloop woud
still true forever
Fri Feb 29 12:46:20 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticast: Don't keep pending removals in the main hash, but put them in a
seperate array. So we can start a new gathering session including them, while still being
able to react on repair requests
Thu Feb 28 17:40:05 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticastTransport: Ensure we wait for nodes to finish their failure process
before completeling the JOIN
Thu Feb 28 17:39:26 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticastTransport: reset the timeout to zero when the gathering phase has
stopped, not strictly necessary, but nice anyway
Thu Feb 28 16:47:31 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticastSender: Set the pending removal state before checking the queue length
as the lenght partially depends on the state
Thu Feb 28 12:16:35 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* If we're resetting because the join failed, return JOIN_FAILED immediately
Thu Feb 28 12:16:08 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* Better debugging of sender garbage collection
Thu Feb 28 10:55:32 CET 2008 Sjoerd Simons <sjoerd.simons(a)collabora.co.uk>
* GibberRMulticast: Add more clear debugging information
diff -rN -u old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-causal-transport.c
new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-causal-transport.c
--- old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-causal-transport.c 2008-02-29
21:09:11.000000000 +0100
+++ new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-causal-transport.c 2008-02-29
21:09:11.000000000 +0100
@@ -803,7 +803,6 @@
joined_multicast_receive (GibberRMulticastCausalTransport *self,
GibberRMulticastPacket *packet)
{
- GibberRMulticastSender *sender = NULL;
GibberRMulticastCausalTransportPrivate *priv =
GIBBER_R_MULTICAST_CAUSAL_TRANSPORT_GET_PRIVATE (self);
@@ -818,82 +817,58 @@
}
DEBUG_TRANSPORT (self, "New sender polling for a unique id");
+ /* Just try to push the packet once. If the id is known a whois reply
+ * will be scheduled otherwise it's dropped as should be */
+ gibber_r_multicast_sender_group_push_packet (priv->sender_group, packet);
+ return;
}
- else
- {
- /* All packets with non-zero sender fall go through here to start
- * detecting foreign packets as early as possible */
- sender = gibber_r_multicast_sender_group_lookup (priv->sender_group,
- packet->sender);
- if (sender == NULL ||
- (sender != priv->self &&
- sender->state == GIBBER_R_MULTICAST_SENDER_STATE_NEW))
- {
- DEBUG_TRANSPORT (self, "Foreign packet Received type: 0x%x from %x",
- packet->type, packet->sender);
- g_signal_emit (self, signals[RECEIVED_FOREIGN_PACKET], 0, packet);
- sender = gibber_r_multicast_sender_group_lookup (priv->sender_group,
- packet->sender);
- }
- }
+ if (packet->sender == self->sender_id)
+ /* Discard our own packets */
+ return;
- if (sender == NULL || sender == priv->self)
+ DEBUG_TRANSPORT (self, "Received packet type: 0x%x from %x",
+ packet->type, packet->sender);
+
+ if (!gibber_r_multicast_sender_group_push_packet (priv->sender_group,
+ packet))
{
- return;
+ /* No entries that could pick up the packet, signal a foreign message so
+ * the membership protocol can handle it if needed */
+ DEBUG_TRANSPORT (self, "Foreign packet Received type: 0x%x from %x",
+ packet->type, packet->sender);
+ g_signal_emit (self, signals[RECEIVED_FOREIGN_PACKET], 0, packet);
+
+ /* Retry the push. the signal handler might have added it */
+ if (!gibber_r_multicast_sender_group_push_packet (priv->sender_group,
+ packet))
+ return;
}
- DEBUG_TRANSPORT (self, "Received packet type: 0x%x from %x",
- packet->type, packet->sender);
+ /* The packet was picked up by one of the nodes, time for some
+ * postprocessing */
switch (packet->type)
{
- case PACKET_TYPE_WHOIS_REQUEST:
- sender = gibber_r_multicast_sender_group_lookup (priv->sender_group,
- packet->data.whois_request.sender_id);
- if (sender == NULL)
+ case PACKET_TYPE_WHOIS_REQUEST:
+ case PACKET_TYPE_WHOIS_REPLY:
+ case PACKET_TYPE_REPAIR_REQUEST:
+ /* No postprocessing needed */
+ break;
+ case PACKET_TYPE_SESSION:
+ handle_session_message (self, packet);
break;
- /* fallthrough */
- case PACKET_TYPE_WHOIS_REPLY:
- gibber_r_multicast_sender_whois_push (sender, packet);
- break;
- case PACKET_TYPE_REPAIR_REQUEST:
- {
- GibberRMulticastSender *rsender;
- guint32 sender_id;
-
- sender_id = packet->data.repair_request.sender_id;
- rsender = gibber_r_multicast_sender_group_lookup (priv->sender_group,
- sender_id);
-
- g_assert (sender_id != 0);
-
- if (rsender != NULL)
- {
- gibber_r_multicast_sender_repair_request (rsender,
- packet->data.repair_request.packet_id);
- }
- else
- {
- DEBUG ("Ignoring repair request for unknown original sender");
- }
- break;
- }
- case PACKET_TYPE_SESSION:
- handle_session_message (self, packet);
- break;
- default:
- if (GIBBER_R_MULTICAST_PACKET_IS_RELIABLE_PACKET (packet))
- {
- handle_packet_depends (self, packet);
- gibber_r_multicast_sender_push (sender, packet);
- }
- else
- {
- DEBUG_TRANSPORT (self, "Received unhandled packet type!!,
ignoring");
- }
- }
-
+ default:
+ if (GIBBER_R_MULTICAST_PACKET_IS_RELIABLE_PACKET (packet))
+ {
+ handle_packet_depends (self, packet);
+ }
+ else
+ {
+ DEBUG_TRANSPORT (self,
+ "Received unhandled packet type!!, ignoring");
+ }
+ }
}
/* Packet received while disconnecting. Only react on repair requests and
diff -rN -u old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.c
new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.c
--- old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.c 2008-02-29
21:09:11.000000000 +0100
+++ new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.c 2008-02-29
21:09:11.000000000 +0100
@@ -61,9 +61,50 @@
* fauly */
#define NAME_DISCOVERY_TIME 10000
+#define GIBBER_R_MULTICAST_SENDER_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GIBBER_TYPE_R_MULTICAST_SENDER, \
+ GibberRMulticastSenderPrivate))
+
+/* private structure */
+typedef struct _GibberRMulticastSenderPrivate GibberRMulticastSenderPrivate;
+
static void set_state (GibberRMulticastSender *sender,
GibberRMulticastSenderState state);
+struct _GibberRMulticastSenderPrivate
+{
+ gboolean dispose_has_run;
+ /* hash table with packets */
+ GHashTable *packet_cache;
+
+ /* Table with acks per sender
+ * guint32 * => owned AckInfo * */
+ GHashTable *acks;
+
+ /* Sendergroup to which we belong */
+ GibberRMulticastSenderGroup *group;
+
+ /* Very first packet number in the current window */
+ guint32 first_packet;
+
+ /* whois reply/request timer */
+ guint whois_timer;
+
+ /* timer untill which a failure even occurs */
+ guint fail_timer;
+
+ /* Whether we are holding back data currently */
+ gboolean holding_data;
+ guint32 holding_point;
+
+ /* Whether we went know the data starting point or not */
+ gboolean start_data;
+ guint32 start_point;
+
+ /* Endpoint is just there in case we are in failure mode */
+ guint32 end_point;
+};
+
typedef struct {
guint32 sender_id;
guint32 packet_id;
@@ -104,6 +145,7 @@
result->senders = g_hash_table_new_full (g_direct_hash, g_direct_equal,
NULL, g_object_unref);
result->pop_queue = g_queue_new();
+ result->pending_removal = g_ptr_array_new ();
return result;
}
@@ -111,10 +153,22 @@
gibber_r_multicast_sender_group_free (GibberRMulticastSenderGroup *group)
{
GHashTable *h;
+ int i;
+
g_assert (group->popping == FALSE);
+
h = group->senders;
group->senders = NULL;
g_hash_table_destroy (h);
+
+ for (i = 0; i < group->pending_removal->len ; i++)
+ {
+ g_object_unref (G_OBJECT (
+ g_ptr_array_index (group->pending_removal, i)));
+ }
+
+ g_ptr_array_free (group->pending_removal, TRUE);
+
g_queue_free (group->pop_queue);
g_slice_free (GibberRMulticastSenderGroup, group);
}
@@ -169,6 +223,39 @@
return g_hash_table_find (group->senders, find_by_name, (gpointer) name);
}
+static void
+cleanup_acks (gpointer key, gpointer value, gpointer user_data)
+{
+ GibberRMulticastSender *sender = GIBBER_R_MULTICAST_SENDER (value);
+ GibberRMulticastSenderPrivate *priv =
+ GIBBER_R_MULTICAST_SENDER_GET_PRIVATE (sender);
+
+ g_hash_table_remove (priv->acks, (guint32 *) user_data);
+}
+
+static void
+gibber_r_multicast_sender_group_gc_acks (GibberRMulticastSenderGroup *group,
+ guint32 sender_id)
+{
+ int i;
+ GibberRMulticastSender *s;
+ /* If there are no more senders for sender_id in the list, clean up the acks
+ */
+ if (g_hash_table_lookup (group->senders, GUINT_TO_POINTER (sender_id))
+ != NULL)
+ return;
+
+ for (i = 0; i < group->pending_removal->len ; i++)
+ {
+ s = GIBBER_R_MULTICAST_SENDER (
+ g_ptr_array_index (group->pending_removal, i));
+ if (s->id == sender_id)
+ return;
+ }
+
+ g_hash_table_foreach (group->senders, cleanup_acks, &sender_id);
+}
+
void
gibber_r_multicast_sender_group_remove (GibberRMulticastSenderGroup *group,
guint32 sender_id)
@@ -186,16 +273,20 @@
}
g_queue_remove (group->pop_queue, s);
+ set_state (s, GIBBER_R_MULTICAST_SENDER_STATE_PENDING_REMOVAL);
+
if (gibber_r_multicast_sender_packet_cache_size (s) > 0)
{
DEBUG ("Keeping %x in cache, %d items left", sender_id,
gibber_r_multicast_sender_packet_cache_size(s));
gibber_r_multicast_sender_stop (s);
- set_state (s, GIBBER_R_MULTICAST_SENDER_STATE_PENDING_REMOVAL);
+ g_hash_table_steal (group->senders, GUINT_TO_POINTER (sender_id));
+ g_ptr_array_add (group->pending_removal, s);
}
else
{
g_hash_table_remove (group->senders, GUINT_TO_POINTER(sender_id));
+ gibber_r_multicast_sender_group_gc_acks (group, sender_id);
}
}
@@ -315,20 +406,24 @@
}
static gboolean
-gc_failures (gpointer key, gpointer value, gpointer user_data)
+can_gc_sender (GibberRMulticastSenderGroup *group,
+ GibberRMulticastSender *sender)
{
- GibberRMulticastSender *sender = GIBBER_R_MULTICAST_SENDER (value);
- GibberRMulticastSenderGroup *group =
- (GibberRMulticastSenderGroup *) user_data;
struct _group_ht_data hd;
-
- if (sender->state < GIBBER_R_MULTICAST_SENDER_STATE_PENDING_REMOVAL)
- return FALSE;
+ GibberRMulticastSender *ret;
hd.group = group;
hd.target = sender;
- return g_hash_table_find (group->senders, failure_not_acked, &hd) == NULL;
+ ret = g_hash_table_find (group->senders, failure_not_acked, &hd);
+
+ if (ret == NULL)
+ DEBUG_SENDER (sender, "Removed by GC");
+ else
+ DEBUG_SENDER (sender, "Not removed by GC because of %s (%x)",
+ ret->name, ret->id);
+
+ return ret == NULL;
}
void
@@ -354,7 +449,141 @@
g_array_free (array, TRUE);
- g_hash_table_foreach_remove (group->senders, gc_failures, group);
+ /* Check if we can remove pending removals */
+ for (i = 0; i < group->pending_removal->len ; i++)
+ {
+ GibberRMulticastSender *s;
+
+ s = GIBBER_R_MULTICAST_SENDER (g_ptr_array_index (group->pending_removal,
+ i));
+ if (can_gc_sender (group, s));
+ {
+ g_ptr_array_remove_index_fast (group->pending_removal, i);
+ gibber_r_multicast_sender_group_gc_acks (group, s->id);
+ g_object_unref (s);
+ /* Last entry has replaced i, so force a retry of i */
+ i--;
+ }
+ }
+}
+
+gboolean
+gibber_r_multicast_sender_group_push_packet (
+ GibberRMulticastSenderGroup *group, GibberRMulticastPacket *packet)
+{
+ gboolean handled = FALSE;
+ GibberRMulticastSender *sender;
+ int i;
+
+ if (packet->type == PACKET_TYPE_WHOIS_REQUEST)
+ sender = gibber_r_multicast_sender_group_lookup (group,
+ packet->data.whois_request.sender_id);
+ else
+ sender = gibber_r_multicast_sender_group_lookup (group,
+ packet->sender);
+
+ switch (packet->type)
+ {
+ case PACKET_TYPE_WHOIS_REQUEST:
+ /* Pending removal nodes still reply to WHOIS_REQUEST to prevent new
+ * nodes from taking the same id */
+ if (sender == NULL)
+ {
+ GibberRMulticastSender *s;
+ for (i = 0; i < group->pending_removal->len ; i++)
+ {
+ s = GIBBER_R_MULTICAST_SENDER (
+ g_ptr_array_index (group->pending_removal, i));
+ if (s->id == packet->data.whois_request.sender_id)
+ {
+ sender = s;
+ break;
+ }
+ }
+ }
+ /* fallthrough */
+ case PACKET_TYPE_WHOIS_REPLY:
+ if (sender != NULL)
+ {
+ gibber_r_multicast_sender_whois_push (sender, packet);
+ handled = TRUE;
+ }
+ break;
+ case PACKET_TYPE_REPAIR_REQUEST:
+ {
+ GibberRMulticastSender *rsender;
+ guint32 sender_id = packet->data.repair_request.sender_id;
+ guint32 packet_id = packet->data.repair_request.packet_id;
+
+ rsender = gibber_r_multicast_sender_group_lookup (group, sender_id);
+
+ g_assert (sender_id != 0);
+
+ if (rsender != NULL &&
+ gibber_r_multicast_sender_repair_request (rsender, packet_id))
+ {
+ /* rsender took up the repair request. */
+ handled = TRUE;
+ break;
+ }
+
+ for (i = 0; i < group->pending_removal->len ; i++)
+ {
+ rsender = GIBBER_R_MULTICAST_SENDER (
+ g_ptr_array_index (group->pending_removal, i));
+ if (rsender->id == sender_id)
+ {
+ if (gibber_r_multicast_sender_repair_request (rsender,
+ packet_id))
+ {
+ handled = TRUE;
+ break;
+ }
+ }
+ }
+ DEBUG ("Ignoring repair request for unknown original sender");
+ break;
+ }
+ case PACKET_TYPE_SESSION:
+ /* Session message aren't handled by us. But if we know the sender it's
+ * at least not a foreign sender */
+ if (sender != NULL)
+ handled = TRUE;
+ break;
+ default:
+ if (GIBBER_R_MULTICAST_PACKET_IS_RELIABLE_PACKET (packet))
+ {
+ if (sender != NULL
+ && sender->state > GIBBER_R_MULTICAST_SENDER_STATE_NEW )
+ {
+ gibber_r_multicast_sender_push (sender, packet);
+ handled = TRUE;
+ }
+ else
+ {
+ for (i = 0; i < group->pending_removal->len ; i++)
+ {
+ sender = GIBBER_R_MULTICAST_SENDER (
+ g_ptr_array_index (group->pending_removal, i));
+ if (sender->id == packet->sender)
+ {
+ /* Say we have handled a reliable packet if there is any
+ * node to remove with the right sender id.. This means
+ * we handle packets for a removed sender longer than
+ * strictly needed, but this doesn't hurt */
+ handled = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ DEBUG ("Received unhandled packet type!!, ignoring");
+ }
+ }
+
+ return handled;
}
static void schedule_repair(GibberRMulticastSender *sender, guint32 id);
@@ -420,45 +649,6 @@
return result;
}
-/* private structure */
-typedef struct _GibberRMulticastSenderPrivate GibberRMulticastSenderPrivate;
-
-struct _GibberRMulticastSenderPrivate
-{
- gboolean dispose_has_run;
- /* hash table with packets */
- GHashTable *packet_cache;
-
- /* Table with acks per sender
- * guint32 * => owned AckInfo * */
- GHashTable *acks;
-
- /* Sendergroup to which we belong */
- GibberRMulticastSenderGroup *group;
-
- /* Very first packet number in the current window */
- guint32 first_packet;
-
- /* whois reply/request timer */
- guint whois_timer;
-
- /* timer untill which a failure even occurs */
- guint fail_timer;
-
- /* Whether we are holding back data currently */
- gboolean holding_data;
- guint32 holding_point;
-
- /* Whether we went know the data starting point or not */
- gboolean start_data;
- guint32 start_point;
-
- /* Endpoint is just there in case we are in failure mode */
- guint32 end_point;
-};
-
-#define GIBBER_R_MULTICAST_SENDER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o),
GIBBER_TYPE_R_MULTICAST_SENDER, GibberRMulticastSenderPrivate))
-
static void
gibber_r_multicast_sender_init (GibberRMulticastSender *obj)
{
@@ -592,17 +782,6 @@
param_spec);
}
-static void
-cleanup_acks (gpointer key, gpointer value, gpointer user_data)
-{
- GibberRMulticastSender *sender = GIBBER_R_MULTICAST_SENDER (value);
- GibberRMulticastSenderPrivate *priv =
- GIBBER_R_MULTICAST_SENDER_GET_PRIVATE (sender);
- GibberRMulticastSender *target = GIBBER_R_MULTICAST_SENDER (user_data);
-
- g_hash_table_remove (priv->acks, &target->id);
-}
-
void
gibber_r_multicast_sender_dispose (GObject *object)
{
@@ -617,9 +796,6 @@
priv->dispose_has_run = TRUE;
- if (priv->group->senders != NULL)
- g_hash_table_foreach (priv->group->senders, cleanup_acks, self);
-
g_hash_table_destroy(priv->packet_cache);
g_hash_table_destroy(priv->acks);
@@ -1519,9 +1695,9 @@
GibberRMulticastSenderPrivate *priv =
GIBBER_R_MULTICAST_SENDER_GET_PRIVATE (sender);
+ DEBUG_SENDER (sender, "Updating start to %x", packet_id);
g_assert (sender->state < GIBBER_R_MULTICAST_SENDER_STATE_FAILED);
- DEBUG_SENDER (sender, "Updating start to %x", packet_id);
if (sender->state == GIBBER_R_MULTICAST_SENDER_STATE_NEW) {
g_assert(g_hash_table_size(priv->packet_cache) == 0);
@@ -1643,32 +1819,32 @@
sender->next_output_packet, sender->next_input_packet);
}
-void
+gboolean
gibber_r_multicast_sender_repair_request(GibberRMulticastSender *sender,
guint32 id) {
GibberRMulticastSenderPrivate *priv =
GIBBER_R_MULTICAST_SENDER_GET_PRIVATE (sender);
gint diff;
+ PacketInfo *info;
if (sender->state < GIBBER_R_MULTICAST_SENDER_STATE_PREPARING) {
DEBUG_SENDER(sender, "ignore repair request");
- return;
+ return FALSE;
}
+ info = g_hash_table_lookup(priv->packet_cache, &id);
+ if (info != NULL && info->packet != NULL)
+ {
+ schedule_do_repair(sender, id);
+ return TRUE;
+ }
+
diff = gibber_r_multicast_packet_diff(sender->next_output_packet, id);
if (diff >= 0 && diff < PACKET_CACHE_SIZE) {
- PacketInfo *info = g_hash_table_lookup(priv->packet_cache, &id);
-
- if (info != NULL && info->packet != NULL)
- {
- schedule_do_repair(sender, id);
- return;
- }
-
if (sender->state >= GIBBER_R_MULTICAST_SENDER_STATE_STOPPED)
/* Beyond stopped state we only send out repairs for packets we have */
- return;
+ return FALSE;
if (info == NULL) {
guint32 i;
@@ -1686,16 +1862,14 @@
info->timeout = 0;
schedule_repair(sender, id);
}
- }
- if (diff < 0
- && gibber_r_multicast_packet_diff(priv->first_packet, id) >= 0) {
- schedule_do_repair(sender, id);
- return;
+ return TRUE;
}
DEBUG_SENDER(sender, "Repair request packet 0x%x out of range, ignoring",
id);
+
+ return FALSE;
}
gboolean
diff -rN -u old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.h
new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.h
--- old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.h 2008-02-29
21:09:11.000000000 +0100
+++ new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-sender.h 2008-02-29
21:09:11.000000000 +0100
@@ -36,8 +36,10 @@
/* <private> */
gboolean popping;
gboolean stopped;
- /* queue of GibberRMulticast GibberRMulticastSender * */
+ /* queue of GibberRMulticast GibberRMulticastSender */
GQueue *pop_queue;
+ /* GArray of pending removal GibberRMulticastSenders */
+ GPtrArray *pending_removal;
};
typedef struct _GibberRMulticastSender GibberRMulticastSender;
@@ -116,6 +118,8 @@
void gibber_r_multicast_sender_group_remove (
GibberRMulticastSenderGroup *group, guint32 sender_id);
+gboolean gibber_r_multicast_sender_group_push_packet (
+ GibberRMulticastSenderGroup *group, GibberRMulticastPacket *packet);
GibberRMulticastSender *gibber_r_multicast_sender_new (guint32 id,
const gchar *name, GibberRMulticastSenderGroup *group);
@@ -151,7 +155,7 @@
gboolean
gibber_r_multicast_sender_seen(GibberRMulticastSender *sender, guint32 id);
-void
+gboolean
gibber_r_multicast_sender_repair_request(GibberRMulticastSender *sender,
guint32 id);
diff -rN -u old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-transport.c
new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-transport.c
--- old-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-transport.c 2008-02-29
21:09:11.000000000 +0100
+++ new-telepathy-salut-0.2/lib/gibber/gibber-r-multicast-transport.c 2008-02-29
21:09:11.000000000 +0100
@@ -635,6 +635,7 @@
{
stop_send_attempt_join (self);
g_source_remove (priv->joining_timeout);
+ priv->joining_timeout = 0;
/* every member with state >= MEMBER_STATE_ATTEMPT_JOIN_REPEAT, will be
* in our join */
g_assert (priv->send_join == NULL);
@@ -1102,7 +1103,7 @@
return FALSE;
}
- DEBUG ("%x didn't fail %x on time", info->id, *id);
+ DEBUG ("At least %x didn't fail %x", info->id, *id);
return TRUE;
}
@@ -1214,6 +1215,8 @@
while ((tinfo = g_hash_table_find (priv->members, find_unfailed_member,
&info->id)) != NULL)
{
+ DEBUG ("Failing %x because it didn't fail %x in time", tinfo->id,
+ info->id);
fail_member (self, NULL, tinfo->id);
}
@@ -1346,6 +1349,7 @@
* the failures.. Should be handled earlier. but reset anyways */
DEBUG ("Join doesn't contain us, shouldn't happen, reset to be sure
:(");
gibber_r_multicast_transport_reset (self);
+ return JOIN_FAILED;
}
seen = 0;
@@ -1413,7 +1417,12 @@
if (info == NULL)
continue;
- if (info->state >= MEMBER_STATE_FAILING)
+ /* send_join only contains members we didn't consider as failures at the
+ * time of the join message. The failure process for those has to be
+ * completely done before we can discard them, as it might have send out
+ * a JOIN we just hadn't received just yet.. Only after their failing
+ * has finished the state gets set to MEMBER_STATE_INSTANT_FAILURE */
+ if (info->state >= MEMBER_STATE_INSTANT_FAILURE)
continue;
if (!info->agreed_join)
Index: telepathy-salut.spec
===================================================================
RCS file: /cvs/pkgs/rpms/telepathy-salut/OLPC-2/telepathy-salut.spec,v
retrieving revision 1.36
retrieving revision 1.37
diff -u -r1.36 -r1.37
--- telepathy-salut.spec 26 Feb 2008 23:41:48 -0000 1.36
+++ telepathy-salut.spec 29 Feb 2008 21:53:57 -0000 1.37
@@ -1,6 +1,6 @@
Name: telepathy-salut
Version: 0.2.2
-Release: 4%{?dist}
+Release: 5%{?dist}
Summary: Link-local XMPP telepathy connection manager
Group: Applications/Communications
@@ -11,6 +11,7 @@
Patch1: salut-chmod-unix-socket.patch
Patch2: salut-stream-tube-fix.patch
Patch3: salut-unknown-sender-crash.patch
+Patch4: salut-olpc-6310.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: dbus-devel >= 1.1.0
@@ -39,6 +40,7 @@
%patch1 -p1 -b .chmod-socket
%patch2 -p1 -b .stream-tube
%patch3 -p1 -b .unknown-sender
+%patch4 -p1 -b .6310
%build
@@ -64,6 +66,9 @@
%{_mandir}/man8/%{name}.8.gz
%changelog
+* Fri Feb 29 2008 Dafydd Harries <dafydd.harries(a)collabora.co.uk> - 0.2.2-5.olpc2
+-
dev.laptop.org #6310: crash in clique multicast code
+
* Tue Feb 26 2008 Dafydd Harries <dafydd.harries(a)collabora.co.uk> - 0.2.2-4.olpc2
-
dev.laptop.org #6390: crash when trying to remove unknown senders