Bug 830290: Added dispatch function for DBus thread r=bent,qdot

The new function allows to schedule nsRunnables to an existing DBus
thread. This intercepts the running instance of DBusPollTask and
makes the DBus thread process the dispatched runnable. The intercepted
poll task automatically continues polling once all pending runnables
have been processed.
This commit is contained in:
Thomas Zimmermann 2013-01-14 11:50:27 +01:00
parent 6cb8692c1d
commit 09ba3f9b43
2 changed files with 59 additions and 11 deletions

View File

@ -46,6 +46,7 @@
#include "base/message_loop.h"
#include "nsTArray.h"
#include "nsDataHashtable.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/NullPtr.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/Monitor.h"
@ -117,6 +118,8 @@ struct DBusThread : public RawDBusConnection
bool Initialize();
void CleanUp();
void WakeUp();
// Information about the sockets we're polling. Socket counts
// increase/decrease depending on how many add/remove watch signals
// we're received via the control sockets.
@ -271,11 +274,9 @@ HandleWatchRemove(DBusThread* aDbt)
static
void DBusWakeup(void* aData)
{
DBusThread *dbt = (DBusThread *)aData;
char control = DBUS_EVENT_LOOP_WAKEUP;
if (write(dbt->mControlFdW.get(), &control, sizeof(char)) < 0) {
NS_WARNING("Cannot write wakeup bit to DBus controller!");
}
MOZ_ASSERT(aData);
DBusThread* dbusThread = static_cast<DBusThread*>(aData);
dbusThread->WakeUp();
}
// DBus Thread Implementation
@ -384,6 +385,28 @@ DBusThread::CleanUp()
mWatchData.Clear();
}
void
DBusThread::WakeUp()
{
static const char control = DBUS_EVENT_LOOP_WAKEUP;
struct pollfd fds = {
mControlFdW.get(),
POLLOUT,
0
};
int nfds = TEMP_FAILURE_RETRY(poll(&fds, 1, 0));
NS_ENSURE_TRUE_VOID(nfds == 1);
NS_ENSURE_TRUE_VOID(fds.revents == POLLOUT);
ssize_t rv = TEMP_FAILURE_RETRY(write(mControlFdW.get(), &control, sizeof(control)));
if (rv < 0) {
NS_WARNING("Cannot write wakeup bit to DBus controller!");
}
}
// Main task for polling the DBus system
class DBusPollTask : public nsRunnable
@ -537,5 +560,19 @@ StopDBus()
return true;
}
nsresult
DispatchToDBusThread(nsIRunnable* event)
{
MOZ_ASSERT(gDBusServiceThread);
MOZ_ASSERT(gDBusThread);
nsresult rv = gDBusServiceThread->Dispatch(event, NS_DISPATCH_NORMAL);
NS_ENSURE_SUCCESS(rv, rv);
gDBusThread->WakeUp();
return NS_OK;
}
}
}

View File

@ -7,12 +7,14 @@
#ifndef mozilla_ipc_dbus_gonk_dbusthread_h__
#define mozilla_ipc_dbus_gonk_dbusthread_h__
struct DBusMessage;
#include "nscore.h"
class nsIRunnable;
namespace mozilla {
namespace ipc {
/**
/**
* Starts the DBus thread, which handles returning signals to objects
* that call asynchronous functions. This should be called from the
* main thread at startup.
@ -21,7 +23,7 @@ namespace ipc {
*/
bool StartDBus();
/**
/**
* Stop the DBus thread, assuming it's currently running. Should be
* called from main thread.
*
@ -29,7 +31,16 @@ bool StartDBus();
*/
bool StopDBus();
}
}
#endif
/**
* Dispatch an event to the DBus thread
*
* @param event An nsIRunnable to run in the DBus thread
* @return NS_OK on success, or an error code otherwise
*/
nsresult
DispatchToDBusThread(nsIRunnable* event);
}
}
#endif