#define DBUS_REPLY_TIMEOUT (-1)
#define SIGNAL_VIBRATOR_INITIATED "InitiateVibrator"
+#define DBUS_MAXIMUM_NAME_LENGTH 255
struct pending_call_data {
dbus_pending_cb func;
void *data;
};
+struct proxy_node {
+ GDBusProxy *proxy;
+ char *dest;
+ char *path;
+ char *interface;
+};
+
static guint haptic_id = 0;
+static GList *proxy_pool;
+static pthread_mutex_t dmutex = PTHREAD_MUTEX_INITIALIZER;
+static int bus_init;
//LCOV_EXCL_START System Error
static int g_dbus_error_to_errno(int code)
return g_variant_builder_end(&builder);
}
-int dbus_method_sync(const char *dest, const char *path,
- const char *interface, const char *method,
- const char *sig, char *param[])
+static struct proxy_node *find_matched_proxy_node(const char *dest,
+ const char *path,
+ const char *interface)
+{
+ GList *elem;
+ struct proxy_node *node;
+ int plen;
+
+ if (!dest || !path || !interface)
+ return NULL;
+
+ plen = strlen(path) + 1;
+
+ /* find matched proxy object */
+ for (elem = proxy_pool; elem; elem = elem->next) {
+ node = elem->data;
+ if (!node)
+ continue;
+ if (!strncmp(node->dest, dest, DBUS_MAXIMUM_NAME_LENGTH) &&
+ !strncmp(node->path, path, plen) &&
+ !strncmp(node->interface, interface,
+ DBUS_MAXIMUM_NAME_LENGTH))
+ return node;
+ }
+
+ return NULL;
+}
+
+static void on_name_vanished(GDBusConnection *connection,
+ const gchar *name,
+ gpointer user_data)
+{
+ GList *elem;
+ GList *next;
+ struct proxy_node *node;
+
+ pthread_mutex_lock(&dmutex);
+ for (elem = proxy_pool, next = g_list_next(elem); elem;
+ elem = next, next = g_list_next(elem)) {
+ node = elem->data;
+ if (!node)
+ continue;
+ proxy_pool = g_list_delete_link(proxy_pool, elem);
+ g_object_unref(node->proxy);
+ free(node->dest);
+ free(node->path);
+ free(node->interface);
+ free(node);
+ }
+ pthread_mutex_unlock(&dmutex);
+}
+
+static GDBusProxy *get_proxy_from_proxy_pool(const char *dest,
+ const char *path,
+ const char *interface,
+ GError **err)
{
GDBusConnection *conn;
GDBusProxy *proxy;
- GError *err = NULL;
- GVariant *output;
- int result;
+ struct proxy_node *node;
-#if !GLIB_CHECK_VERSION(2, 35, 0)
- g_type_init();
-#endif
+ if (!dest || !path || !interface) {
+ if (err)
+ g_set_error(err, G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ "Cannot determine destination address");
+ return NULL;
+ }
- conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (!conn) {
-//LCOV_EXCL_START System Error
- _E("g_bus_get_sync error : %s-%s (%d-%s)",
- interface, method, err->code, err->message);
- result = g_dbus_error_to_errno(err->code);
- g_clear_error(&err);
- return result;
-//LCOV_EXCL_STOP
+ /* find matched proxy node in proxy pool */
+ node = find_matched_proxy_node(dest, path, interface);
+ if (node)
+ return node->proxy;
+
+ conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, err);
+ if (!conn)
+ return NULL;
+
+ if (!bus_init) {
+ bus_init++;
+ g_bus_watch_name_on_connection(conn,
+ DEVICED_BUS_NAME,
+ G_BUS_NAME_WATCHER_FLAGS_NONE,
+ NULL,
+ on_name_vanished,
+ NULL,
+ NULL);
}
proxy = g_dbus_proxy_new_sync(conn,
path, /* object path */
interface, /* interface name */
NULL, /* GCancellable */
- &err);
+ err);
+ if (!proxy)
+ return NULL;
+
+ node = malloc(sizeof(struct proxy_node));
+ if (!node) {
+ g_object_unref(proxy);
+ if (err)
+ g_set_error(err, G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ "Cannot allocate proxy_node memory");
+ return NULL;
+ }
+
+ node->proxy = proxy;
+ node->dest = strdup(dest);
+ node->path = strdup(path);
+ node->interface = strdup(interface);
+
+ proxy_pool = g_list_append(proxy_pool, node);
+
+ return proxy;
+}
+
+int dbus_method_sync(const char *dest, const char *path,
+ const char *interface, const char *method,
+ const char *sig, char *param[])
+{
+ GDBusProxy *proxy;
+ GError *err = NULL;
+ GVariant *output;
+ int result;
+
+#if !GLIB_CHECK_VERSION(2, 35, 0)
+ g_type_init();
+#endif
+
+ pthread_mutex_lock(&dmutex);
+ proxy = get_proxy_from_proxy_pool(dest, path, interface, &err);
if (!proxy) {
//LCOV_EXCL_START System Error
- _E("g_dbus_proxy_new_sync error : %s-%s (%d-%s)",
+ pthread_mutex_unlock(&dmutex);
+ _E("fail to get proxy from proxy pool : %s-%s (%d-%s)",
interface, method, err->code, err->message);
result = g_dbus_error_to_errno(err->code);
g_clear_error(&err);
DBUS_REPLY_TIMEOUT, /* timeout */
NULL, /* GCancellable */
&err);
+ pthread_mutex_unlock(&dmutex);
+
if (!output) {
//LCOV_EXCL_START System Error
if (!err) {
_E("g_dbus_proxy_call_sync error : %s-%s",
interface, method);
- g_object_unref(proxy);
return -EPERM;
}
_E("g_dbus_proxy_call_sync error : %s-%s (%d-%s)",
interface, method, err->code, err->message);
result = g_dbus_error_to_errno(err->code);
g_clear_error(&err);
- g_object_unref(proxy);
return result;
//LCOV_EXCL_STOP
}
g_variant_get(output, "(i)", &result);
g_variant_unref(output);
- g_object_unref(proxy);
return result;
}
const char *method, const char *sig,
char *param[], GVariant **info)
{
- GDBusConnection *conn;
GDBusProxy *proxy;
GError *err = NULL;
GVariant *output;
g_type_init();
#endif
- conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (!conn) {
-//LCOV_EXCL_START System Error
- _E("g_bus_get_sync error : %s-%s (%d-%s)",
- interface, method, err->code, err->message);
- result = g_dbus_error_to_errno(err->code);
- g_clear_error(&err);
- return result;
-//LCOV_EXCL_STOP
- }
-
- proxy = g_dbus_proxy_new_sync(conn,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL, /* GDBusinterfaceinfo */
- dest, /* bus name */
- path, /* object path */
- interface, /* interface name */
- NULL, /* GCancellable */
- &err);
+ pthread_mutex_lock(&dmutex);
+ proxy = get_proxy_from_proxy_pool(dest, path, interface, &err);
if (!proxy) {
//LCOV_EXCL_START System Error
- _E("g_dbus_proxy_new_sync error : %s-%s (%d-%s)",
+ pthread_mutex_unlock(&dmutex);
+ _E("fail to get proxy from proxy pool : %s-%s (%d-%s)",
interface, method, err->code, err->message);
result = g_dbus_error_to_errno(err->code);
g_clear_error(&err);
DBUS_REPLY_TIMEOUT, /* timeout */
NULL, /* GCancellable */
&err);
+ pthread_mutex_unlock(&dmutex);
if (!output) {
if (!err) {
//LCOV_EXCL_START System Error
_E("g_dbus_proxy_call_sync error : %s-%s",
interface, method);
- g_object_unref(proxy);
return -EPERM;
}
_E("g_dbus_proxy_call_sync error : %s-%s (%d-%s)",
interface, method, err->code, err->message);
result = g_dbus_error_to_errno(err->code);
g_clear_error(&err);
- g_object_unref(proxy);
return result;
//LCOV_EXCL_STOP
}
- g_object_unref(proxy);
-
*info = output;
return DEVICE_ERROR_NONE;
}
//LCOV_EXCL_STOP
if (output)
g_variant_unref(output);
- g_object_unref(proxy);
}
int dbus_method_async_with_reply(const char *dest, const char *path,
const char *sig, char *param[],
dbus_pending_cb cb, int timeout, void *data)
{
- GDBusConnection *conn;
GDBusProxy *proxy;
GError *err = NULL;
struct pending_call_data *pdata;
g_type_init();
#endif
- conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
- if (!conn) {
-//LCOV_EXCL_START System Error
- _E("g_bus_get_sync error : %s-%s (%d-%s)",
- interface, method, err->code, err->message);
- result = g_dbus_error_to_errno(err->code);
- g_clear_error(&err);
- return result;
-//LCOV_EXCL_STOP
- }
-
- proxy = g_dbus_proxy_new_sync(conn,
- G_DBUS_PROXY_FLAGS_NONE,
- NULL, /* GDBusinterfaceinfo */
- dest, /* bus name */
- path, /* object path */
- interface, /* interface name */
- NULL, /* GCancellable */
- &err);
+ pthread_mutex_lock(&dmutex);
+ proxy = get_proxy_from_proxy_pool(dest, path, interface, &err);
if (!proxy) {
//LCOV_EXCL_START System Error
- _E("g_dbus_proxy_new_sync error : %s-%s (%d-%s)",
+ pthread_mutex_unlock(&dmutex);
+ _E("fail to get proxy from proxy pool : %s-%s (%d-%s)",
interface, method, err->code, err->message);
result = g_dbus_error_to_errno(err->code);
g_clear_error(&err);
pdata = malloc(sizeof(struct pending_call_data));
if (!pdata) {
+ pthread_mutex_unlock(&dmutex);
_E("malloc error : %s-%s", //LCOV_EXCL_LINE
interface, method);
return -ENOMEM;
NULL, /* GCancellable */
(GAsyncReadyCallback)cb_pending, /* GAsyncReadyCallback */
pdata); /* user data */
+ pthread_mutex_unlock(&dmutex);
return 0;
}