mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-10 03:45:46 +00:00
Bug 768306 - Patch 1: Fix error handling in unpacking DBus replies, set up DBus blocking call handling thread; r=mrbkap
This commit is contained in:
parent
894868aa63
commit
11d7f94bbe
@ -22,34 +22,37 @@ using namespace mozilla;
|
||||
|
||||
USING_BLUETOOTH_NAMESPACE
|
||||
|
||||
nsRefPtr<BluetoothService> gBluetoothService;
|
||||
nsCOMPtr<nsIThread> gToggleBtThread;
|
||||
int gPendingInitCount = 0;
|
||||
bool gInShutdown = false;
|
||||
static nsRefPtr<BluetoothService> gBluetoothService;
|
||||
static bool gInShutdown = false;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(BluetoothService, nsIObserver)
|
||||
|
||||
class ToggleBtAck : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ToggleBtAck(bool aEnabled) :
|
||||
mEnabled(aEnabled)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
gPendingInitCount--;
|
||||
|
||||
if (gPendingInitCount) {
|
||||
return NS_OK;
|
||||
|
||||
if (!mEnabled || gInShutdown) {
|
||||
nsCOMPtr<nsIThread> t;
|
||||
gBluetoothService->mBluetoothCommandThread.swap(t);
|
||||
t->Shutdown();
|
||||
}
|
||||
|
||||
if (gInShutdown) {
|
||||
gBluetoothService = nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIThread> t;
|
||||
gToggleBtThread.swap(t);
|
||||
t->Shutdown();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool mEnabled;
|
||||
};
|
||||
|
||||
class ToggleBtTask : public nsRunnable
|
||||
@ -82,7 +85,7 @@ public:
|
||||
// Always has to be called since this is where we take care of our reference
|
||||
// count for runnables. If there's an error, replyError won't be empty, so
|
||||
// consider our status flipped.
|
||||
nsCOMPtr<nsIRunnable> ackTask = new ToggleBtAck();
|
||||
nsCOMPtr<nsIRunnable> ackTask = new ToggleBtAck(mEnabled);
|
||||
if (NS_FAILED(NS_DispatchToMainThread(ackTask))) {
|
||||
NS_WARNING("Failed to dispatch to main thread!");
|
||||
}
|
||||
@ -168,17 +171,16 @@ BluetoothService::StartStopBluetooth(BluetoothReplyRunnable* aResultRunnable,
|
||||
NS_ERROR("Start called while in shutdown!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!gToggleBtThread) {
|
||||
nsresult rv = NS_NewNamedThread("BluetoothCtrl",
|
||||
getter_AddRefs(gToggleBtThread));
|
||||
if (!mBluetoothCommandThread) {
|
||||
nsresult rv = NS_NewNamedThread("BluetoothCmd",
|
||||
getter_AddRefs(mBluetoothCommandThread));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsCOMPtr<nsIRunnable> r = new ToggleBtTask(aStart, aResultRunnable);
|
||||
if (NS_FAILED(gToggleBtThread->Dispatch(r, NS_DISPATCH_NORMAL))) {
|
||||
if (NS_FAILED(mBluetoothCommandThread->Dispatch(r, NS_DISPATCH_NORMAL))) {
|
||||
NS_WARNING("Cannot dispatch firmware loading task!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
gPendingInitCount++;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -192,6 +192,19 @@ public:
|
||||
const nsAString& aPattern,
|
||||
int aAttributeId) = 0;
|
||||
|
||||
/**
|
||||
* Due to the fact that some operations require multiple calls, a
|
||||
* CommandThread is created that can run blocking, platform-specific calls
|
||||
* where either no asynchronous equivilent exists, or else where multiple
|
||||
* asynchronous calls would require excessive runnable bouncing between main
|
||||
* thread and IO thread.
|
||||
*
|
||||
* For instance, when we retrieve an Adapter object, we would like it to come
|
||||
* with all of its properties filled in and registered as an agent, which
|
||||
* requires a minimum of 3 calls to platform specific code on some platforms.
|
||||
*
|
||||
*/
|
||||
nsCOMPtr<nsIThread> mBluetoothCommandThread;
|
||||
protected:
|
||||
BluetoothService()
|
||||
{
|
||||
|
@ -149,8 +149,14 @@ public:
|
||||
};
|
||||
|
||||
bool
|
||||
IsDBusMessageError(DBusMessage* aMsg, nsAString& aError)
|
||||
IsDBusMessageError(DBusMessage* aMsg, DBusError* aErr, nsAString& aErrorStr)
|
||||
{
|
||||
if(aErr && dbus_error_is_set(aErr)) {
|
||||
aErrorStr = NS_ConvertUTF8toUTF16(aErr->message);
|
||||
LOG_AND_FREE_DBUS_ERROR(aErr);
|
||||
return true;
|
||||
}
|
||||
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_ERROR) {
|
||||
@ -159,12 +165,15 @@ IsDBusMessageError(DBusMessage* aMsg, nsAString& aError)
|
||||
&error_msg, DBUS_TYPE_INVALID) ||
|
||||
!error_msg) {
|
||||
if (dbus_error_is_set(&err)) {
|
||||
aError = NS_ConvertUTF8toUTF16(err.message);
|
||||
aErrorStr = NS_ConvertUTF8toUTF16(err.message);
|
||||
LOG_AND_FREE_DBUS_ERROR(&err);
|
||||
return true;
|
||||
} else {
|
||||
aErrorStr.AssignLiteral("Unknown Error");
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
aError = NS_ConvertUTF8toUTF16(error_msg);
|
||||
aErrorStr = NS_ConvertUTF8toUTF16(error_msg);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -173,15 +182,14 @@ IsDBusMessageError(DBusMessage* aMsg, nsAString& aError)
|
||||
|
||||
void
|
||||
DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
const BluetoothValue& aValue, const nsAString& aError)
|
||||
const BluetoothValue& aValue, const nsAString& aErrorStr)
|
||||
{
|
||||
// Reply will be deleted by the runnable after running on main thread
|
||||
BluetoothReply* reply;
|
||||
if (!aError.IsEmpty()) {
|
||||
nsString err(aError);
|
||||
if (!aErrorStr.IsEmpty()) {
|
||||
nsString err(aErrorStr);
|
||||
reply = new BluetoothReply(BluetoothReplyError(err));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
reply = new BluetoothReply(BluetoothReplySuccess(aValue));
|
||||
}
|
||||
|
||||
@ -192,12 +200,12 @@ DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
|
||||
}
|
||||
|
||||
void
|
||||
UnpackObjectPathMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
UnpackObjectPathMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue, nsAString& aErrorStr)
|
||||
{
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (!IsDBusMessageError(aMsg, aErrorStr)) {
|
||||
if (!IsDBusMessageError(aMsg, aErr, aErrorStr)) {
|
||||
NS_ASSERTION(dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN,
|
||||
"Got dbus callback that's not a METHOD_RETURN!");
|
||||
const char* object_path;
|
||||
@ -214,7 +222,7 @@ UnpackObjectPathMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
}
|
||||
}
|
||||
|
||||
typedef void (*UnpackFunc)(DBusMessage*, BluetoothValue&, nsAString&);
|
||||
typedef void (*UnpackFunc)(DBusMessage*, DBusError*, BluetoothValue&, nsAString&);
|
||||
|
||||
void
|
||||
RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
|
||||
@ -228,23 +236,24 @@ RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
|
||||
|
||||
nsString replyError;
|
||||
BluetoothValue v;
|
||||
aFunc(aMsg, v, replyError);
|
||||
aFunc(aMsg, nsnull, v, replyError);
|
||||
DispatchBluetoothReply(replyRunnable, v, replyError);
|
||||
}
|
||||
|
||||
void
|
||||
GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackObjectPathMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackObjectPathMessage);
|
||||
}
|
||||
|
||||
void
|
||||
UnpackVoidMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
UnpackVoidMessage(DBusMessage* aMsg, DBusError* aErr, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
DBusError err;
|
||||
dbus_error_init(&err);
|
||||
if (!IsDBusMessageError(aMsg, aErrorStr) &&
|
||||
if (!IsDBusMessageError(aMsg, aErr, aErrorStr) &&
|
||||
dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN &&
|
||||
!dbus_message_get_args(aMsg, &err, DBUS_TYPE_INVALID)) {
|
||||
if (dbus_error_is_set(&err)) {
|
||||
@ -257,7 +266,8 @@ UnpackVoidMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
void
|
||||
GetVoidCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackVoidMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackVoidMessage);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -381,11 +391,13 @@ ParseProperties(DBusMessageIter* aIter,
|
||||
aValue = props;
|
||||
}
|
||||
|
||||
void UnpackPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr, Properties* aPropertyTypes,
|
||||
const int aPropertyTypeLen)
|
||||
void
|
||||
UnpackPropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue, nsAString& aErrorStr,
|
||||
Properties* aPropertyTypes,
|
||||
const int aPropertyTypeLen)
|
||||
{
|
||||
if (!IsDBusMessageError(aMsg, aErrorStr) &&
|
||||
if (!IsDBusMessageError(aMsg, aErr, aErrorStr) &&
|
||||
dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
|
||||
DBusMessageIter iter;
|
||||
if (!dbus_message_iter_init(aMsg, &iter)) {
|
||||
@ -397,26 +409,32 @@ void UnpackPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
}
|
||||
}
|
||||
|
||||
void UnpackAdapterPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
void
|
||||
UnpackAdapterPropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
|
||||
UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr,
|
||||
sAdapterProperties,
|
||||
ArrayLength(sAdapterProperties));
|
||||
}
|
||||
|
||||
void UnpackDevicePropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
void
|
||||
UnpackDevicePropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
|
||||
UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr,
|
||||
sDeviceProperties,
|
||||
ArrayLength(sDeviceProperties));
|
||||
}
|
||||
|
||||
void UnpackManagerPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
void
|
||||
UnpackManagerPropertiesMessage(DBusMessage* aMsg, DBusError* aErr,
|
||||
BluetoothValue& aValue,
|
||||
nsAString& aErrorStr)
|
||||
{
|
||||
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
|
||||
UnpackPropertiesMessage(aMsg, aErr, aValue, aErrorStr,
|
||||
sManagerProperties,
|
||||
ArrayLength(sManagerProperties));
|
||||
}
|
||||
@ -424,19 +442,22 @@ void UnpackManagerPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
|
||||
void
|
||||
GetManagerPropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackManagerPropertiesMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackManagerPropertiesMessage);
|
||||
}
|
||||
|
||||
void
|
||||
GetAdapterPropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackAdapterPropertiesMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackAdapterPropertiesMessage);
|
||||
}
|
||||
|
||||
void
|
||||
GetDevicePropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
|
||||
{
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackDevicePropertiesMessage);
|
||||
RunDBusCallback(aMsg, aBluetoothReplyRunnable,
|
||||
UnpackDevicePropertiesMessage);
|
||||
}
|
||||
|
||||
static DBusCallback sBluetoothDBusPropCallbacks[] =
|
||||
@ -611,7 +632,6 @@ BluetoothDBusService::StartInternal()
|
||||
}
|
||||
|
||||
if (NS_FAILED(EstablishDBusConnection())) {
|
||||
NS_WARNING("Cannot start DBus connection!");
|
||||
StopDBus();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ DBusMessage * dbus_func_args_timeout_valist(DBusConnection *conn,
|
||||
/* Make the call. */
|
||||
reply = dbus_connection_send_with_reply_and_block(conn, msg, timeout_ms, err);
|
||||
if (!return_error && dbus_error_is_set(err)) {
|
||||
//LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg);
|
||||
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(err, msg);
|
||||
}
|
||||
|
||||
done:
|
||||
@ -212,6 +212,7 @@ done:
|
||||
|
||||
DBusMessage * dbus_func_args_timeout(DBusConnection *conn,
|
||||
int timeout_ms,
|
||||
DBusError* err,
|
||||
const char *path,
|
||||
const char *ifc,
|
||||
const char *func,
|
||||
@ -220,7 +221,7 @@ DBusMessage * dbus_func_args_timeout(DBusConnection *conn,
|
||||
DBusMessage *ret;
|
||||
va_list lst;
|
||||
va_start(lst, first_arg_type);
|
||||
ret = dbus_func_args_timeout_valist(conn, timeout_ms, NULL,
|
||||
ret = dbus_func_args_timeout_valist(conn, timeout_ms, err,
|
||||
path, ifc, func,
|
||||
first_arg_type, lst);
|
||||
va_end(lst);
|
||||
|
@ -90,6 +90,7 @@ DBusMessage* dbus_func_args_error(DBusConnection* conn,
|
||||
|
||||
DBusMessage* dbus_func_args_timeout(DBusConnection* conn,
|
||||
int timeout_ms,
|
||||
DBusError* err,
|
||||
const char* path,
|
||||
const char* ifc,
|
||||
const char* func,
|
||||
|
@ -31,6 +31,10 @@ public:
|
||||
RawDBusConnection();
|
||||
~RawDBusConnection();
|
||||
nsresult EstablishDBusConnection();
|
||||
DBusConnection* GetConnection() {
|
||||
return mConnection;
|
||||
}
|
||||
protected:
|
||||
Scoped<ScopedDBusConnectionPtrTraits> mConnection;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user