[vlc-commits] power: use non-blocking DBusPendingCall instead of short timeout
Rémi Denis-Courmont
git at videolan.org
Fri Dec 7 21:12:07 CET 2012
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Dec 7 22:11:27 2012 +0200| [1e1f01298b1032e22087e9fefeef9fb272860724] | committer: Rémi Denis-Courmont
power: use non-blocking DBusPendingCall instead of short timeout
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=1e1f01298b1032e22087e9fefeef9fb272860724
---
modules/misc/inhibit/power.c | 93 +++++++++++++++++++++++++++---------------
1 file changed, 60 insertions(+), 33 deletions(-)
diff --git a/modules/misc/inhibit/power.c b/modules/misc/inhibit/power.c
index c885bff..0a4e307 100644
--- a/modules/misc/inhibit/power.c
+++ b/modules/misc/inhibit/power.c
@@ -28,10 +28,13 @@
# include <config.h>
#endif
+#include <assert.h>
+
+#include <dbus/dbus.h>
+
#include <vlc_common.h>
#include <vlc_plugin.h>
#include <vlc_inhibit.h>
-#include <dbus/dbus.h>
enum vlc_inhibit_api
{
@@ -68,6 +71,7 @@ static const char dbus_method_uninhibit[][10] =
struct vlc_inhibit_sys
{
DBusConnection *conn;
+ DBusPendingCall *pending;
dbus_uint32_t cookie;
enum vlc_inhibit_api api;
};
@@ -75,9 +79,39 @@ struct vlc_inhibit_sys
static void Inhibit(vlc_inhibit_t *ih, unsigned flags)
{
vlc_inhibit_sys_t *sys = ih->p_sys;
- DBusConnection *conn = sys->conn;
enum vlc_inhibit_api type = sys->api;
+ /* Receive reply from previous request, possibly hours later ;-) */
+ if (sys->pending != NULL)
+ {
+ DBusMessage *reply;
+
+ /* NOTE: Unfortunately, the pending reply cannot simply be cancelled.
+ * Otherwise, the cookie would be lost and inhibition would remain on
+ * (until complete disconnection from the bus). */
+ dbus_pending_call_block(sys->pending);
+ reply = dbus_pending_call_steal_reply(sys->pending);
+ dbus_pending_call_unref(sys->pending);
+ sys->pending = NULL;
+
+ if (reply != NULL)
+ {
+ if (!dbus_message_get_args(reply, NULL,
+ DBUS_TYPE_UINT32, &sys->cookie,
+ DBUS_TYPE_INVALID))
+ sys->cookie = 0;
+ dbus_message_unref(reply);
+ }
+ msg_Dbg(ih, "got cookie %"PRIu32, (uint32_t)sys->cookie);
+ }
+
+ /* FIXME: This check is incorrect if flags change from one non-zero value
+ * to another one. But the D-Bus API cannot currently inhibit suspend
+ * independently from the screensaver. */
+ if (!sys->cookie == !flags)
+ return; /* nothing to do */
+
+ /* Send request */
const char *method = flags ? "Inhibit" : dbus_method_uninhibit[type];
dbus_bool_t ret;
@@ -86,10 +120,13 @@ static void Inhibit(vlc_inhibit_t *ih, unsigned flags)
if (unlikely(msg == NULL))
return;
- if (flags) {
+ if (flags)
+ {
const char *app = PACKAGE;
const char *reason = _("Playing some media.");
+ assert(sys->cookie == 0);
+
switch (type)
{
case FREEDESKTOP:
@@ -100,9 +137,7 @@ static void Inhibit(vlc_inhibit_t *ih, unsigned flags)
case GNOME:
{
dbus_uint32_t xid = 0; // FIXME ?
- dbus_uint32_t gflags =
- ((flags & VLC_INHIBIT_SUSPEND) ? 8 : 0) |
- ((flags & VLC_INHIBIT_DISPLAY) ? 4 : 0);
+ dbus_uint32_t gflags = 0xC;
ret = dbus_message_append_args(msg, DBUS_TYPE_STRING, &app,
DBUS_TYPE_UINT32, &xid,
@@ -111,37 +146,23 @@ static void Inhibit(vlc_inhibit_t *ih, unsigned flags)
DBUS_TYPE_INVALID);
break;
}
+ default:
+ assert(0);
}
- } else {
- if (sys->cookie)
- ret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &sys->cookie,
- DBUS_TYPE_INVALID);
- else
- ret = false;
- }
-
- if (!ret)
- goto giveup;
-
- if (flags) { /* read reply */
- DBusMessage *reply = dbus_connection_send_with_reply_and_block(
- conn, msg, 50, NULL);
- if (unlikely(reply == NULL))
- goto giveup; /* no reponse?! */
-
- if (!dbus_message_get_args(reply, NULL,
- DBUS_TYPE_UINT32, &sys->cookie,
- DBUS_TYPE_INVALID))
- sys->cookie = 0;
- dbus_message_unref(reply);
- } else { /* just send and flush */
- if (dbus_connection_send (conn, msg, NULL)) {
+ if (!ret
+ || !dbus_connection_send_with_reply(sys->conn, msg, &sys->pending, -1))
+ sys->pending = NULL;
+ }
+ else
+ {
+ assert(sys->cookie != 0);
+ if (!dbus_message_append_args(msg, DBUS_TYPE_UINT32, &sys->cookie,
+ DBUS_TYPE_INVALID)
+ || !dbus_connection_send (sys->conn, msg, NULL))
sys->cookie = 0;
- dbus_connection_flush(conn);
- }
}
-giveup:
+ dbus_connection_flush(sys->conn);
dbus_message_unref(msg);
}
@@ -166,6 +187,7 @@ static int Open (vlc_object_t *obj)
return VLC_EGENERIC;
}
+ sys->pending = NULL;
sys->cookie = 0;
for (unsigned i = 0; i < MAX_API; i++)
@@ -193,6 +215,11 @@ static void Close (vlc_object_t *obj)
vlc_inhibit_t *ih = (vlc_inhibit_t *)obj;
vlc_inhibit_sys_t *sys = ih->p_sys;
+ if (sys->pending != NULL)
+ {
+ dbus_pending_call_cancel(sys->pending);
+ dbus_pending_call_unref(sys->pending);
+ }
dbus_connection_close (sys->conn);
dbus_connection_unref (sys->conn);
free (sys);
More information about the vlc-commits
mailing list