VirtualBox

source: vbox/trunk/src/VBox/Main/src-server/linux/HostPowerLinux.cpp@ 56035

Last change on this file since 56035 was 55651, checked in by vboxsync, 10 years ago

Main/HostPowerLinux: avoid gcc warning.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.7 KB
Line 
1/** @file
2 *
3 * VirtualBox interface to host's power notification service
4 */
5
6/*
7 * Copyright (C) 2015 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18#include "HostPower.h"
19#include "Logging.h"
20
21#include <iprt/asm.h>
22#include <iprt/power.h>
23#include <iprt/time.h>
24
25static bool checkDBusError(DBusError *pError, DBusConnection *pConnection)
26{
27 if (dbus_error_is_set(pError))
28 {
29 LogRel(("HostPowerServiceLinux: DBus connection Error (%s)\n", pError->message));
30 dbus_error_free(pError);
31 /* Close the socket or whatever underlying the connection. */
32 dbus_connection_close(pConnection);
33 /* Free in-process resources used for the now-closed connection. */
34 dbus_connection_unref(pConnection);
35 return true;
36 }
37 return false;
38}
39
40HostPowerServiceLinux::HostPowerServiceLinux(VirtualBox *aVirtualBox)
41 : HostPowerService(aVirtualBox)
42 , mThread(NULL)
43 , mpConnection(NULL)
44{
45 DBusError error;
46 int rc;
47
48 rc = RTDBusLoadLib();
49 if (RT_FAILURE(rc))
50 {
51 LogRel(("HostPowerServiceLinux: DBus library not found. Service not available.\n"));
52 return;
53 }
54 dbus_error_init(&error);
55 /* Connect to the DBus. The connection will be not shared with any other
56 * in-process callers of dbus_bus_get(). This is considered wasteful (see
57 * API documentation) but simplifies our code, specifically shutting down.
58 * The session bus allows up to 100000 connections per user as it "is just
59 * running as the user anyway" (see session.conf.in in the DBus sources). */
60 mpConnection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
61 if (checkDBusError(&error, mpConnection))
62 return;
63 /* We do not want to exit(1) if the connection is broken. */
64 dbus_connection_set_exit_on_disconnect(mpConnection, FALSE);
65 /* Tell the bus to wait for the sleep signal(s). */
66 /* The current systemd-logind interface. */
67 dbus_bus_add_match(mpConnection, "type='signal',interface='org.freedesktop.login1.Manager'", &error);
68 /* The previous UPower interfaces (2010 - ca 2013). */
69 dbus_bus_add_match(mpConnection, "type='signal',interface='org.freedesktop.UPower'", &error);
70 dbus_connection_flush(mpConnection);
71 if (checkDBusError(&error, mpConnection))
72 return;
73 /* Create the new worker thread. */
74 rc = RTThreadCreate(&mThread, HostPowerServiceLinux::powerChangeNotificationThread, this, 0 /* cbStack */,
75 RTTHREADTYPE_MSG_PUMP, RTTHREADFLAGS_WAITABLE, "MainPower");
76 if (RT_FAILURE(rc))
77 LogRel(("HostPowerServiceLinux: RTThreadCreate failed with %Rrc\n", rc));
78}
79
80
81HostPowerServiceLinux::~HostPowerServiceLinux()
82{
83 /* Closing the connection should cause the event loop to exit. */
84 LogFunc((": Stopping thread\n"));
85 dbus_connection_close(mpConnection);
86
87 RTThreadWait(mThread, 5000, NULL);
88 mThread = NIL_RTTHREAD;
89}
90
91
92DECLCALLBACK(int) HostPowerServiceLinux::powerChangeNotificationThread(RTTHREAD hThreadSelf, void *pInstance)
93{
94 NOREF(hThreadSelf);
95 HostPowerServiceLinux *pPowerObj = static_cast<HostPowerServiceLinux *>(pInstance);
96
97 Log(("HostPowerServiceLinux: Thread started\n"));
98 while (dbus_connection_read_write(pPowerObj->mpConnection, -1))
99 {
100 DBusMessage *pMessage = NULL;
101
102 for (;;)
103 {
104 DBusMessageIter args;
105 dbus_bool_t fSuspend;
106
107 pMessage = dbus_connection_pop_message(pPowerObj->mpConnection);
108 if (pMessage == NULL)
109 break;
110 /* The systemd-logind interface notification. */
111 if ( dbus_message_is_signal(pMessage, "org.freedesktop.login1.Manager", "PrepareForSleep")
112 && dbus_message_iter_init(pMessage, &args)
113 && dbus_message_iter_get_arg_type(&args) == DBUS_TYPE_BOOLEAN)
114 {
115 dbus_message_iter_get_basic(&args, &fSuspend);
116 /* Trinary operator does not work here as Reason_... is an
117 * anonymous enum. */
118 if (fSuspend)
119 pPowerObj->notify(Reason_HostSuspend);
120 else
121 pPowerObj->notify(Reason_HostResume);
122 }
123 /* The UPowerd interface notifications. Sleeping is the older one,
124 * NotifySleep the newer. This gives us one second grace before the
125 * suspend triggers. */
126 if ( dbus_message_is_signal(pMessage, "org.freedesktop.UPower", "Sleeping")
127 || dbus_message_is_signal(pMessage, "org.freedesktop.UPower", "NotifySleep"))
128 pPowerObj->notify(Reason_HostSuspend);
129 if ( dbus_message_is_signal(pMessage, "org.freedesktop.UPower", "Resuming")
130 || dbus_message_is_signal(pMessage, "org.freedesktop.UPower", "NotifyResume"))
131 pPowerObj->notify(Reason_HostResume);
132 /* Free local resources held for the message. */
133 dbus_message_unref(pMessage);
134 }
135 }
136 /* Close the socket or whatever underlying the connection. */
137 dbus_connection_close(pPowerObj->mpConnection);
138 /* Free in-process resources used for the now-closed connection. */
139 dbus_connection_unref(pPowerObj->mpConnection);
140 pPowerObj->mpConnection = NULL;
141 Log(("HostPowerServiceLinux: Exiting thread\n"));
142 return VINF_SUCCESS;
143}
144
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette