зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1240985 - IPC glib deadlock fix (r=jld)
This commit is contained in:
Родитель
771b5739fb
Коммит
b336ddb3ad
|
@ -124,7 +124,8 @@ namespace base {
|
|||
MessagePumpForUI::MessagePumpForUI()
|
||||
: state_(NULL),
|
||||
context_(g_main_context_default()),
|
||||
wakeup_gpollfd_(new GPollFD) {
|
||||
wakeup_gpollfd_(new GPollFD),
|
||||
pipe_full_(false) {
|
||||
// Create our wakeup pipe, which is used to flag when work was scheduled.
|
||||
int fds[2];
|
||||
CHECK(pipe(fds) == 0);
|
||||
|
@ -230,10 +231,12 @@ bool MessagePumpForUI::HandleCheck() {
|
|||
if (!state_) // state_ may be null during tests.
|
||||
return false;
|
||||
|
||||
// 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 glib
|
||||
// poll will tell us whether there was data, so this read shouldn't block.
|
||||
// We should only ever have a single message on the wakeup pipe since we only
|
||||
// write to the pipe when pipe_full_ is false. The glib poll will tell us
|
||||
// whether there was data, so this read shouldn't block.
|
||||
if (wakeup_gpollfd_->revents & G_IO_IN) {
|
||||
pipe_full_ = false;
|
||||
|
||||
char msg;
|
||||
if (HANDLE_EINTR(read(wakeup_pipe_read_, &msg, 1)) != 1 || msg != '!') {
|
||||
NOTREACHED() << "Error reading from the wakeup pipe.";
|
||||
|
@ -297,6 +300,11 @@ void MessagePumpForUI::Quit() {
|
|||
}
|
||||
|
||||
void MessagePumpForUI::ScheduleWork() {
|
||||
bool was_full = pipe_full_.exchange(true);
|
||||
if (was_full) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "base/observer_list.h"
|
||||
#include "base/time.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
|
||||
typedef union _GdkEvent GdkEvent;
|
||||
typedef struct _GMainContext GMainContext;
|
||||
|
@ -131,6 +132,8 @@ class MessagePumpForUI : public MessagePump {
|
|||
// Use an autoptr to avoid needing the definition of GPollFD in the header.
|
||||
mozilla::UniquePtr<GPollFD> wakeup_gpollfd_;
|
||||
|
||||
mozilla::Atomic<bool> pipe_full_;
|
||||
|
||||
// List of observers.
|
||||
ObserverList<Observer> observers_;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче