Bug 544190 - QCore version needed to replace message_pump_glib.cc. r=dougt

This commit is contained in:
Oleg Romashin 2010-02-18 23:48:50 +02:00
Родитель 08adb94c35
Коммит 5291f401f2
5 изменённых файлов: 248 добавлений и 1 удалений

Просмотреть файл

@ -1408,6 +1408,10 @@ host_%.$(OBJ_SUFFIX): %.mm $(GLOBAL_DEPS)
moc_%.cpp: %.h $(GLOBAL_DEPS)
$(MOC) $< $(OUTOPTION)$@
moc_%.cc: %.cc $(GLOBAL_DEPS)
$(REPORT_BUILD)
$(ELOG) $(MOC) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@
ifdef ASFILES
# The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept
# a '-c' flag.

Просмотреть файл

@ -246,11 +246,27 @@ CPPSRCS += \
file_util_linux.cc \
file_version_info_linux.cc \
idle_timer_none.cc \
message_pump_glib.cc \
process_util_linux.cc \
time_posix.cc \
$(NULL)
ifdef MOZ_ENABLE_GTK2
CPPSRCS += \
message_pump_glib.cc \
$(NULL)
endif
ifdef MOZ_ENABLE_QT
MOCSRCS = \
moc_message_pump_qt.cc \
$(NULL)
CPPSRCS += \
$(MOCSRCS) \
message_pump_qt.cc \
$(NULL)
endif
endif # } OS_LINUX
# libevent

Просмотреть файл

@ -20,8 +20,13 @@
#include "base/message_pump_libevent.h"
#endif
#if defined(OS_LINUX)
#ifdef MOZ_WIDGET_GTK2
#include "base/message_pump_glib.h"
#endif
#ifdef MOZ_WIDGET_QT
#include "base/message_pump_qt.h"
#endif
#endif
#ifdef CHROMIUM_MOZILLA_BUILD
#include "MessagePump.h"

Просмотреть файл

@ -0,0 +1,142 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/message_pump_qt.h"
#include <qabstracteventdispatcher.h>
#include <qevent.h>
#include <qapplication.h>
#include <fcntl.h>
#include <math.h>
#include "base/eintr_wrapper.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/platform_thread.h"
namespace {
// Cached QEvent user type, registered for our event system
static int sPokeEvent;
} // namespace
namespace base {
MessagePumpForUI::MessagePumpForUI()
: qt_pump(*this)
{
}
MessagePumpForUI::~MessagePumpForUI() {
}
MessagePumpQt::MessagePumpQt(MessagePumpForUI &aPump)
: pump(aPump)
{
// Register our custom event type, to use in qApp event loop
#if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
sPokeEvent = QEvent::registerEventType();
#else
sPokeEvent = QEvent::User+5000;
#endif
}
MessagePumpQt::~MessagePumpQt()
{
}
bool
MessagePumpQt::event(QEvent *e)
{
if (e->type() == sPokeEvent) {
pump.HandleDispatch();
return true;
}
return false;
}
void MessagePumpForUI::Run(Delegate* delegate) {
RunState state;
state.delegate = delegate;
state.should_quit = false;
state.run_depth = state_ ? state_->run_depth + 1 : 1;
// We really only do a single task for each iteration of the loop. If we
// have done something, assume there is likely something more to do. This
// will mean that we don't block on the message pump until there was nothing
// more to do. We also set this to true to make sure not to block on the
// first iteration of the loop, so RunAllPending() works correctly.
state.more_work_is_plausible = true;
RunState* previous_state = state_;
state_ = &state;
// We run our own loop instead of using g_main_loop_quit in one of the
// callbacks. This is so we only quit our own loops, and we don't quit
// nested loops run by others. TODO(deanm): Is this what we want?
while (!state_->should_quit) {
QAbstractEventDispatcher *dispatcher = QAbstractEventDispatcher::instance(qApp->thread());
if (!dispatcher)
return;
dispatcher->processEvents(QEventLoop::AllEvents | QEventLoop::WaitForMoreEvents);
}
state_ = previous_state;
}
void MessagePumpForUI::HandleDispatch() {
// We should only ever have a single message on the wakeup pipe, since we
// are only signaled when the queue went from empty to non-empty. The qApp
// poll will tell us whether there was data, so this read shouldn't block.
if (state_->should_quit)
return;
state_->more_work_is_plausible = false;
if (state_->delegate->DoWork())
state_->more_work_is_plausible = true;
if (state_->should_quit)
return;
if (state_->delegate->DoDelayedWork(&delayed_work_time_))
state_->more_work_is_plausible = true;
if (state_->should_quit)
return;
// Don't do idle work if we think there are more important things
// that we could be doing.
if (state_->more_work_is_plausible)
return;
if (state_->delegate->DoIdleWork())
state_->more_work_is_plausible = true;
if (state_->should_quit)
return;
}
void MessagePumpForUI::Quit() {
if (state_) {
state_->should_quit = true;
} else {
NOTREACHED() << "Quit called outside Run!";
}
}
void MessagePumpForUI::ScheduleWork() {
// This can be called on any thread, so we don't want to touch any state
// variables as we would then need locks all over. This ensures that if
// we are sleeping in a poll that we will wake up.
QCoreApplication::postEvent(&qt_pump,
new QEvent((QEvent::Type) sPokeEvent));
}
void MessagePumpForUI::ScheduleDelayedWork(const Time& delayed_work_time) {
// We need to wake up the loop in case the poll timeout needs to be
// adjusted. This will cause us to try to do work, but that's ok.
delayed_work_time_ = delayed_work_time;
ScheduleWork();
}
} // namespace base

Просмотреть файл

@ -0,0 +1,80 @@
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef BASE_MESSAGE_PUMP_QT_H_
#define BASE_MESSAGE_PUMP_QT_H_
#include <qobject.h>
#include "base/message_pump.h"
#include "base/time.h"
namespace base {
class MessagePumpForUI;
class MessagePumpQt : public QObject {
Q_OBJECT
public:
MessagePumpQt(MessagePumpForUI &pump);
~MessagePumpQt();
virtual bool event (QEvent *e);
private:
base::MessagePumpForUI &pump;
};
// This class implements a MessagePump needed for TYPE_UI MessageLoops on
// OS_LINUX platforms using QApplication event loop
class MessagePumpForUI : public MessagePump {
public:
MessagePumpForUI();
~MessagePumpForUI();
virtual void Run(Delegate* delegate);
virtual void Quit();
virtual void ScheduleWork();
virtual void ScheduleDelayedWork(const Time& delayed_work_time);
// Internal methods used for processing the pump callbacks. They are
// public for simplicity but should not be used directly.
// HandleDispatch is called after the poll has completed.
void HandleDispatch();
private:
// We may make recursive calls to Run, so we save state that needs to be
// separate between them in this structure type.
struct RunState {
Delegate* delegate;
// Used to flag that the current Run() invocation should return ASAP.
bool should_quit;
// Used to count how many Run() invocations are on the stack.
int run_depth;
// Used internally for controlling whether we want a message pump
// iteration to be blocking or not.
bool more_work_is_plausible;
};
RunState* state_;
// This is the time when we need to do delayed work.
Time delayed_work_time_;
// MessagePump implementation for Qt based on the GLib implement.
// On Qt we use a QObject base class and the
// default qApp in order to process events through QEventLoop.
MessagePumpQt qt_pump;
DISALLOW_COPY_AND_ASSIGN(MessagePumpForUI);
};
} // namespace base
#endif // BASE_MESSAGE_PUMP_QT_H_