232
232
* _before_ dropping the swarm name because gdbus currently does a
233
233
* sync dbus call to release the name which makes us race against
234
234
* getting a NameOwnerChanged */
235
/* The removal of the filter rules also has to be done in dispose,
236
* not finalize, cause the filter callback can ref this object and
237
* therefore postpone finalization, although that shouldn't happen,
238
* as this uses locking and the call will not return until all current
239
* invocations of the filter callback finish. */
235
240
g_dbus_connection_remove_filter (priv->connection, priv->filter_id);
237
242
for (match_iter = priv->match_rules;
253
258
g_object_unref (priv->connection);
254
259
priv->connection = NULL;
262
if (priv->match_rules)
264
g_slist_free (priv->match_rules);
265
priv->match_rules = NULL;
257
268
/* Stop trying to own the swarm name.
258
269
* See implementation note above */
269
280
priv->name_watcher_id = 0;
283
G_OBJECT_CLASS (dee_peer_parent_class)->dispose (object);
287
dee_peer_finalize (GObject *object)
289
DeePeerPrivate *priv;
291
priv = DEE_PEER (object)->priv;
272
293
if (priv->list_cancellable != NULL)
274
295
g_cancellable_cancel (priv->list_cancellable);
288
309
priv->swarm_path = NULL;
290
311
if (priv->swarm_leader)
292
g_free (priv->swarm_leader);
293
priv->swarm_leader = NULL;
313
g_free (priv->swarm_leader);
314
priv->swarm_leader = NULL;
297
318
g_hash_table_destroy (priv->peers);
298
319
priv->peers = NULL;
300
if (priv->match_rules)
302
g_slist_free (priv->match_rules);
303
priv->match_rules = NULL;
305
321
if (priv->lock != NULL)
307
323
#if GLIB_CHECK_VERSION(2, 31, 16)
421
437
GObjectClass *obj_class = G_OBJECT_CLASS (klass);
422
438
GParamSpec *pspec;
440
obj_class->dispose = dee_peer_dispose;
424
441
obj_class->finalize = dee_peer_finalize;
425
442
obj_class->set_property = dee_peer_set_property;
426
443
obj_class->get_property = dee_peer_get_property;
980
dispose_weak_ref (gpointer data)
982
GWeakRef *weak_ref = (GWeakRef*) data;
983
g_weak_ref_clear (weak_ref);
962
987
/* Called when we get the bus connection the first time. */
964
989
on_bus_acquired (GDBusConnection *connection,
978
1005
g_signal_emit (self, _peer_signals[CONNECTION_ACQUIRED], 0, priv->connection);
1007
/* Using GPtrArray as a ref-count container for the weak ref */
1008
weak_ref = (GWeakRef*) g_new (GWeakRef, 1);
1009
g_weak_ref_init (weak_ref, self);
1010
ptr_array = g_ptr_array_new_full (1, dispose_weak_ref);
1011
g_ptr_array_add (ptr_array, weak_ref);
980
1013
priv->filter_id = g_dbus_connection_add_filter (priv->connection,
981
1014
gdbus_message_filter,
1016
(GDestroyNotify) g_ptr_array_unref);
985
1018
/* Detect when someone joins the swarm */
986
1019
install_match_rule (self,
1508
1541
static gboolean
1509
1542
transfer_to_mainloop (gpointer *args)
1544
GPtrArray *ptr_array;
1511
1547
GFunc cb = (GFunc) args[0];
1513
cb (args[1], args[2]);
1514
g_object_unref (args[1]);
1549
ptr_array = (GPtrArray*) args[1];
1550
weak_ref = (GWeakRef*) g_ptr_array_index (ptr_array, 0);
1552
object = (GObject*) g_weak_ref_get (weak_ref);
1555
cb (object, args[2]);
1556
g_object_unref (object);
1559
g_ptr_array_unref (ptr_array);
1515
1560
g_free (args[2]);
1527
1572
gdbus_message_filter (GDBusConnection *connection,
1528
1573
GDBusMessage *msg,
1529
1574
gboolean incoming,
1533
1578
DeePeerPrivate *priv;
1534
1579
GVariant *body;
1535
1580
GDBusMessageType msg_type;
1536
gchar *swarm_name = NULL;
1537
gchar *peer_address = NULL;
1538
1581
const gchar *sender_address;
1539
1582
gpointer *data;
1541
g_return_val_if_fail (DEE_IS_PEER (user_data), msg);
1543
self = DEE_PEER (user_data);
1583
GPtrArray *ptr_array;
1586
ptr_array = (GPtrArray*) user_data;
1587
weak_ref = (GWeakRef*) g_ptr_array_index (ptr_array, 0);
1545
1588
body = g_dbus_message_get_body (msg);
1546
1589
sender_address = g_dbus_message_get_sender (msg);
1547
1590
msg_type = g_dbus_message_get_message_type (msg);
1569
1612
g_strcmp0 (sender_address, g_dbus_connection_get_unique_name (connection)) != 0 &&
1617
self = (DeePeer*) g_weak_ref_get (weak_ref);
1618
if (self == NULL) return msg;
1572
1621
g_variant_get (body, "(su)", &swarm_name, NULL);
1573
1622
if (g_strcmp0 (swarm_name, priv->swarm_name) == 0)
1575
1624
/* Call on_join_received() in the main loop */
1576
data = g_new (gpointer, 2);
1625
data = g_new (gpointer, 3);
1577
1626
data[0] = on_join_received;
1578
data[1] = g_object_ref (self);
1627
data[1] = g_ptr_array_ref (ptr_array);
1579
1628
data[2] = g_strdup (sender_address);
1580
1629
g_idle_add ((GSourceFunc) transfer_to_mainloop, data);
1632
g_object_unref (self);
1633
g_free (swarm_name);
1583
1635
else if (check_signal (msg, "org.freedesktop.DBus", "NameOwnerChanged", NULL) && body != NULL)
1585
gchar *old_address, *new_address;
1637
gchar *old_address, *new_address, *peer_address;
1586
1638
gboolean should_emit_bye;
1640
self = (DeePeer*) g_weak_ref_get (weak_ref);
1641
if (self == NULL) return msg;
1588
1644
g_variant_get (body, "(sss)", &peer_address, &old_address, &new_address);
1590
1646
/* Check if a known peer dropped off the bus and emit the Bye signal
1603
1659
if (should_emit_bye)
1605
1661
/* Call emit_bye() in the main loop */
1606
data = g_new (gpointer, 2);
1662
data = g_new (gpointer, 3);
1607
1663
data[0] = emit_bye;
1608
data[1] = g_object_ref (self);
1664
data[1] = g_ptr_array_ref (ptr_array);
1609
1665
data[2] = peer_address; // own
1610
1666
g_idle_add ((GSourceFunc) transfer_to_mainloop, data);
1611
1667
peer_address = NULL;
1669
g_object_unref (self);
1613
1670
g_free (old_address);
1614
1671
g_free (new_address);
1672
g_free (peer_address);
1616
else if (check_method (msg, DEE_PEER_DBUS_IFACE, "List", priv->swarm_path))
1618
/* We don't want to go through the whole GDBus interface/introspection
1619
* setup just to export the List method. We just handle this particular
1621
GDBusMessage *reply;
1622
reply = g_dbus_message_new_method_reply (msg);
1623
g_dbus_message_set_body (reply, build_peer_list (self));
1624
g_dbus_connection_send_message (connection,
1626
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
1627
NULL, /* out serial */
1629
g_object_unref (reply);
1631
/* Convince GDBus that we handled this message by returning NULL */
1676
self = (DeePeer*) g_weak_ref_get (weak_ref);
1677
if (self == NULL) return msg;
1680
if (check_method (msg, DEE_PEER_DBUS_IFACE, "List", priv->swarm_path))
1682
/* We don't want to go through the whole GDBus
1683
* interface/introspection setup just to export the List method.
1684
* We just handle this particular method inline */
1685
GDBusMessage *reply;
1686
reply = g_dbus_message_new_method_reply (msg);
1687
g_dbus_message_set_body (reply, build_peer_list (self));
1688
g_dbus_connection_send_message (connection,
1690
G_DBUS_SEND_MESSAGE_FLAGS_NONE,
1691
NULL, /* out serial */
1693
g_object_unref (reply);
1695
g_object_unref (self);
1696
/* Convince GDBus that we handled this message by returning NULL */
1699
g_object_unref (self);
1635
g_free (swarm_name);
1636
g_free (peer_address);