Browse Source

Improved error reporting in device reservation code

rd_acquire() error handling is adjusted to match libdbus error
handling convention:
 * Initialize error before calling rd_acquire()
 * Free dbus error on rd_acquire() failures
 * Always set dbus error on rd_acquire failures, except for
   detected programming errors that now cause taboo assert.
tags/1.9.9.5^2
Nedko Arnaudov 12 years ago
parent
commit
6414cd9dbf
3 changed files with 68 additions and 18 deletions
  1. +3
    -0
      dbus/audio_reserve.c
  2. +3
    -0
      dbus/controller.c
  3. +62
    -18
      dbus/reserve.c

+ 3
- 0
dbus/audio_reserve.c View File

@@ -76,6 +76,8 @@ SERVER_EXPORT bool audio_acquire(const char * device_name)


assert(gReserveCount < DEVICE_MAX); assert(gReserveCount < DEVICE_MAX);


dbus_error_init(&error);

if ((ret= rd_acquire( if ((ret= rd_acquire(
&gReservedDevice[gReserveCount].reserved_device, &gReservedDevice[gReserveCount].reserved_device,
gConnection, gConnection,
@@ -86,6 +88,7 @@ SERVER_EXPORT bool audio_acquire(const char * device_name)
&error)) < 0) { &error)) < 0) {


jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret))); jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret)));
dbus_error_free(&error);
return false; return false;
} }




+ 3
- 0
dbus/controller.c View File

@@ -377,6 +377,8 @@ on_device_acquire(const char * device_name)
int ret; int ret;
DBusError error; DBusError error;


dbus_error_init(&error);

ret = rd_acquire( ret = rd_acquire(
&g_reserved_device[g_device_count].reserved_device, &g_reserved_device[g_device_count].reserved_device,
g_connection, g_connection,
@@ -388,6 +390,7 @@ on_device_acquire(const char * device_name)
if (ret < 0) if (ret < 0)
{ {
jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret))); jack_error("Failed to acquire device name : %s error : %s", device_name, (error.message ? error.message : strerror(-ret)));
dbus_error_free(&error);
return false; return false;
} }




+ 62
- 18
dbus/reserve.c View File

@@ -31,6 +31,11 @@
#include <stdint.h> #include <stdint.h>


#include "reserve.h" #include "reserve.h"
#include "jack/control.h"

#define RESERVE_ERROR_NO_MEMORY "org.freedesktop.ReserveDevice1.Error.NoMemory"
#define RESERVE_ERROR_PROTOCOL_VIOLATION "org.freedesktop.ReserveDevice1.Error.Protocol"
#define RESERVE_ERROR_RELEASE_DENIED "org.freedesktop.ReserveDevice1.Error.ReleaseDenied"


struct rd_device { struct rd_device {
int ref; int ref;
@@ -371,34 +376,51 @@ int rd_acquire(
dbus_bool_t good; dbus_bool_t good;
vtable.message_function = object_handler; vtable.message_function = object_handler;


if (!error)
if (!error) {
error = &_error; error = &_error;
dbus_error_init(error);
}


dbus_error_init(error);

if (!_d)
return -EINVAL;
if (!_d) {
assert(0);
r = -EINVAL;
goto fail;
}


if (!connection)
return -EINVAL;
if (!connection) {
assert(0);
r = -EINVAL;
goto fail;
}


if (!device_name)
return -EINVAL;
if (!device_name) {
assert(0);
r = -EINVAL;
goto fail;
}


if (!request_cb && priority != INT32_MAX)
return -EINVAL;
if (!request_cb && priority != INT32_MAX) {
assert(0);
r = -EINVAL;
goto fail;
}


if (!(d = (rd_device *)calloc(sizeof(rd_device), 1)))
return -ENOMEM;
if (!(d = (rd_device *)calloc(sizeof(rd_device), 1))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for rd_device struct");
r = -ENOMEM;
goto fail;
}


d->ref = 1; d->ref = 1;


if (!(d->device_name = strdup(device_name))) { if (!(d->device_name = strdup(device_name))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot duplicate device name string");
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }


if (!(d->application_name = strdup(application_name))) { if (!(d->application_name = strdup(application_name))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot duplicate application name string");
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }
@@ -408,12 +430,14 @@ int rd_acquire(
d->request_cb = request_cb; d->request_cb = request_cb;


if (!(d->service_name = (char*)malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) { if (!(d->service_name = (char*)malloc(sizeof(SERVICE_PREFIX) + strlen(device_name)))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for service name string");
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }
sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name); sprintf(d->service_name, SERVICE_PREFIX "%s", d->device_name);


if (!(d->object_path = (char*)malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) { if (!(d->object_path = (char*)malloc(sizeof(OBJECT_PREFIX) + strlen(device_name)))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for object path string");
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }
@@ -425,20 +449,28 @@ int rd_acquire(
DBUS_NAME_FLAG_DO_NOT_QUEUE| DBUS_NAME_FLAG_DO_NOT_QUEUE|
(priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0), (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0),
error)) < 0) { error)) < 0) {
jack_error("dbus_bus_request_name() failed. (1)");
r = -EIO; r = -EIO;
goto fail; goto fail;
} }


if (k == DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER || k == DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER)
switch (k) {
case DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER:
case DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER:
goto success; goto success;

if (k != DBUS_REQUEST_NAME_REPLY_EXISTS) {
case DBUS_REQUEST_NAME_REPLY_EXISTS:
break;
case DBUS_REQUEST_NAME_REPLY_IN_QUEUE : /* DBUS_NAME_FLAG_DO_NOT_QUEUE was specified */
default: /* unknown reply returned */
jack_error("request name reply with unexpected value %d.", k);
assert(0);
r = -EIO; r = -EIO;
goto fail; goto fail;
} }


if (priority <= INT32_MIN) { if (priority <= INT32_MIN) {
r = -EBUSY; r = -EBUSY;
dbus_set_error(error, RESERVE_ERROR_RELEASE_DENIED, "Device reservation request with priority %"PRIi32" denied for \"%s\"", priority, device_name);
goto fail; goto fail;
} }


@@ -447,6 +479,7 @@ int rd_acquire(
d->object_path, d->object_path,
"org.freedesktop.ReserveDevice1", "org.freedesktop.ReserveDevice1",
"RequestRelease"))) { "RequestRelease"))) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot allocate memory for RequestRelease method call");
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }
@@ -455,6 +488,7 @@ int rd_acquire(
m, m,
DBUS_TYPE_INT32, &d->priority, DBUS_TYPE_INT32, &d->priority,
DBUS_TYPE_INVALID)) { DBUS_TYPE_INVALID)) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot append args for RequestRelease method call");
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }
@@ -469,10 +503,12 @@ int rd_acquire(
dbus_error_has_name(error, DBUS_ERROR_UNKNOWN_METHOD) || dbus_error_has_name(error, DBUS_ERROR_UNKNOWN_METHOD) ||
dbus_error_has_name(error, DBUS_ERROR_NO_REPLY)) { dbus_error_has_name(error, DBUS_ERROR_NO_REPLY)) {
/* This must be treated as denied. */ /* This must be treated as denied. */
jack_info("Device reservation request with priority %"PRIi32" denied for \"%s\": %s (%s)", priority, device_name, error->name, error->message);
r = -EBUSY; r = -EBUSY;
goto fail; goto fail;
} }


jack_error("dbus_connection_send_with_reply_and_block(RequestRelease) failed.");
r = -EIO; r = -EIO;
goto fail; goto fail;
} }
@@ -482,11 +518,13 @@ int rd_acquire(
error, error,
DBUS_TYPE_BOOLEAN, &good, DBUS_TYPE_BOOLEAN, &good,
DBUS_TYPE_INVALID)) { DBUS_TYPE_INVALID)) {
jack_error("RequestRelease() reply is invalid.");
r = -EIO; r = -EIO;
goto fail; goto fail;
} }


if (!good) { if (!good) {
dbus_set_error(error, RESERVE_ERROR_RELEASE_DENIED, "Device reservation request with priority %"PRIi32" denied for \"%s\" via RequestRelease()", priority, device_name);
r = -EBUSY; r = -EBUSY;
goto fail; goto fail;
} }
@@ -498,11 +536,14 @@ int rd_acquire(
(priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0)| (priority < INT32_MAX ? DBUS_NAME_FLAG_ALLOW_REPLACEMENT : 0)|
DBUS_NAME_FLAG_REPLACE_EXISTING, DBUS_NAME_FLAG_REPLACE_EXISTING,
error)) < 0) { error)) < 0) {
jack_error("dbus_bus_request_name() failed. (2)");
r = -EIO; r = -EIO;
goto fail; goto fail;
} }


if (k != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { if (k != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
/* this is racy, another contender may have acquired the device */
dbus_set_error(error, RESERVE_ERROR_PROTOCOL_VIOLATION, "request name reply is not DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER but %d.", k);
r = -EIO; r = -EIO;
goto fail; goto fail;
} }
@@ -510,11 +551,13 @@ int rd_acquire(
success: success:
d->owning = 1; d->owning = 1;


if (!(dbus_connection_register_object_path(
if (!(dbus_connection_try_register_object_path(
d->connection, d->connection,
d->object_path, d->object_path,
&vtable, &vtable,
d))) {
d,
error))) {
jack_error("cannot register object path \"%s\": %s", d->object_path, error->message);
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }
@@ -526,6 +569,7 @@ success:
filter_handler, filter_handler,
d, d,
NULL)) { NULL)) {
dbus_set_error(error, RESERVE_ERROR_NO_MEMORY, "Cannot add filter");
r = -ENOMEM; r = -ENOMEM;
goto fail; goto fail;
} }


Loading…
Cancel
Save