void DBusThread::EventLoop() { dbus_connection_set_watch_functions(mConnection, AddWatch, RemoveWatch, ToggleWatch, this, NULL); dbus_connection_set_wakeup_main_function(mConnection, DBusWakeup, this, NULL); #ifdef DEBUG LOG("DBus Event Loop Starting\n"); #endif while (1) { poll(mPollData.Elements(), mPollData.Length(), -1); for (uint32_t i = 0; i < mPollData.Length(); i++) { if (!mPollData[i].revents) { continue; } if (mPollData[i].fd == mControlFdR.get()) { char data; while (recv(mControlFdR.get(), &data, sizeof(char), MSG_DONTWAIT) != -1) { switch (data) { case DBUS_EVENT_LOOP_EXIT: #ifdef DEBUG LOG("DBus Event Loop Exiting\n"); #endif dbus_connection_set_watch_functions(mConnection, NULL, NULL, NULL, NULL, NULL); return; case DBUS_EVENT_LOOP_ADD: HandleWatchAdd(this); break; case DBUS_EVENT_LOOP_REMOVE: HandleWatchRemove(this); break; case DBUS_EVENT_LOOP_WAKEUP: // noop break; } } } else { short events = mPollData[i].revents; unsigned int flags = UnixEventsToDBusFlags(events); dbus_watch_handle(mWatchData[i], flags); mPollData[i].revents = 0; // Break at this point since we don't know if the operation // was destructive break; } } while (dbus_connection_dispatch(mConnection) == DBUS_DISPATCH_DATA_REMAINS) {} } }
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; }
bool DBusWatcher::Poll() { int res = TEMP_FAILURE_RETRY(poll(mPollData.Elements(), mPollData.Length(), -1)); NS_ENSURE_TRUE(res > 0, false); bool continueThread = true; nsTArray<pollfd>::size_type i = 0; while (i < mPollData.Length()) { if (mPollData[i].revents == POLLIN) { if (mPollData[i].fd == mControlFdR.get()) { char data; res = TEMP_FAILURE_RETRY(read(mControlFdR.get(), &data, sizeof(data))); NS_ENSURE_TRUE(res > 0, false); switch (data) { case DBUS_EVENT_LOOP_EXIT: continueThread = false; break; case DBUS_EVENT_LOOP_ADD: HandleWatchAdd(); break; case DBUS_EVENT_LOOP_REMOVE: HandleWatchRemove(); // 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 = mPollData[i].revents; mPollData[i].revents = 0; dbus_watch_handle(mWatchData[i], UnixEventsToDBusFlags(events)); DBusDispatchStatus dbusDispatchStatus; do { dbusDispatchStatus = dbus_connection_dispatch(GetConnection()); } while (dbusDispatchStatus == DBUS_DISPATCH_DATA_REMAINS); // Break at this point since we don't know if the operation // was destructive break; } } ++i; } return continueThread; }