Bug 830290: Added DBusPollTask r=bent,qdot

This patch adds class DBusPollTask. The DBusPollTask class is an
nsRunnable for receiving DBus messages. It is intended to run in
a separate thread that is dedicated to DBus only.

The Run function of the poll task resembles the DBus EventLoop
function, but allows to intercept execution in favor of other
nsRunnables. Afterwards the DBusPollTask continues.
This commit is contained in:
Thomas Zimmermann 2013-01-14 11:50:21 +01:00
parent 3d599f37c3
commit 605a0ae152

View File

@ -479,6 +479,85 @@ DBusThread::StopEventLoop()
return true;
}
// Main task for polling the DBus system
class DBusPollTask : public nsRunnable
{
public:
DBusPollTask(DBusThread* aConnection)
: mConnection(aConnection)
{ }
NS_IMETHOD Run()
{
MOZ_ASSERT(!NS_IsMainThread());
bool exitThread = false;
while (!exitThread) {
int res = TEMP_FAILURE_RETRY(poll(mConnection->mPollData.Elements(),
mConnection->mPollData.Length(),
-1));
NS_ENSURE_TRUE(res > 0, NS_OK);
nsTArray<pollfd>::size_type i = 0;
while (i < mConnection->mPollData.Length()) {
if (mConnection->mPollData[i].revents == POLLIN) {
if (mConnection->mPollData[i].fd == mConnection->mControlFdR.get()) {
char data;
res = TEMP_FAILURE_RETRY(read(mConnection->mControlFdR.get(), &data, sizeof(data)));
NS_ENSURE_TRUE(res > 0, NS_OK);
switch (data) {
case DBUS_EVENT_LOOP_EXIT:
exitThread = true;
break;
case DBUS_EVENT_LOOP_ADD:
HandleWatchAdd(mConnection);
break;
case DBUS_EVENT_LOOP_REMOVE:
HandleWatchRemove(mConnection);
// don't increment i, or we'll skip one element
continue;
case DBUS_EVENT_LOOP_WAKEUP:
NS_ProcessPendingEvents(NS_GetCurrentThread(),
PR_INTERVAL_NO_TIMEOUT);
break;
default:
#if DEBUG
nsCString warning("unknown command ");
warning.AppendInt(data);
NS_WARNING(warning.get());
#endif
break;
}
} else {
short events = mConnection->mPollData[i].revents;
unsigned int flags = UnixEventsToDBusFlags(events);
dbus_watch_handle(mConnection->mWatchData[i], flags);
mConnection->mPollData[i].revents = 0;
// Break at this point since we don't know if the operation
// was destructive
break;
}
while (dbus_connection_dispatch(mConnection->GetConnection()) ==
DBUS_DISPATCH_DATA_REMAINS)
{}
}
++i;
}
}
return NS_OK;
}
private:
DBusThread* mConnection;
};
// Startup/Shutdown utility functions
bool