mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
bug 532333: part 1: expose libevent signal events through chromium wrappers
This commit is contained in:
parent
43fec0c5cf
commit
e89e8adc89
@ -632,4 +632,14 @@ bool MessageLoopForIO::WatchFileDescriptor(int fd,
|
||||
delegate);
|
||||
}
|
||||
|
||||
#if defined(CHROMIUM_MOZILLA_BUILD)
|
||||
bool
|
||||
MessageLoopForIO::CatchSignal(int sig,
|
||||
SignalEvent* sigevent,
|
||||
SignalWatcher* delegate)
|
||||
{
|
||||
return pump_libevent()->CatchSignal(sig, sigevent, delegate);
|
||||
}
|
||||
#endif // defined(CHROMIUM_MOZILLA_BUILD)
|
||||
|
||||
#endif
|
||||
|
@ -507,6 +507,15 @@ class MessageLoopForIO : public MessageLoop {
|
||||
Mode mode,
|
||||
FileDescriptorWatcher *controller,
|
||||
Watcher *delegate);
|
||||
|
||||
#if defined(CHROMIUM_MOZILLA_BUILD)
|
||||
typedef base::MessagePumpLibevent::SignalEvent SignalEvent;
|
||||
typedef base::MessagePumpLibevent::SignalWatcher SignalWatcher;
|
||||
bool CatchSignal(int sig,
|
||||
SignalEvent* sigevent,
|
||||
SignalWatcher* delegate);
|
||||
#endif // defined(CHROMIUM_MOZILLA_BUILD)
|
||||
|
||||
#endif // defined(OS_POSIX)
|
||||
};
|
||||
|
||||
|
@ -211,6 +211,91 @@ void MessagePumpLibevent::OnLibeventNotification(int fd, short flags,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if defined(CHROMIUM_MOZILLA_BUILD)
|
||||
MessagePumpLibevent::SignalEvent::SignalEvent() :
|
||||
event_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
MessagePumpLibevent::SignalEvent::~SignalEvent()
|
||||
{
|
||||
if (event_) {
|
||||
StopCatching();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MessagePumpLibevent::SignalEvent::Init(event *e)
|
||||
{
|
||||
DCHECK(e);
|
||||
DCHECK(event_ == NULL);
|
||||
event_ = e;
|
||||
}
|
||||
|
||||
bool
|
||||
MessagePumpLibevent::SignalEvent::StopCatching()
|
||||
{
|
||||
// XXX/cjones: this code could be shared with
|
||||
// FileDescriptorWatcher. ironic that libevent is "more"
|
||||
// object-oriented than this C++
|
||||
event* e = ReleaseEvent();
|
||||
if (e == NULL)
|
||||
return true;
|
||||
|
||||
// event_del() is a no-op if the event isn't active.
|
||||
int rv = event_del(e);
|
||||
delete e;
|
||||
return (rv == 0);
|
||||
}
|
||||
|
||||
event *
|
||||
MessagePumpLibevent::SignalEvent::ReleaseEvent()
|
||||
{
|
||||
event *e = event_;
|
||||
event_ = NULL;
|
||||
return e;
|
||||
}
|
||||
|
||||
bool
|
||||
MessagePumpLibevent::CatchSignal(int sig,
|
||||
SignalEvent* sigevent,
|
||||
SignalWatcher* delegate)
|
||||
{
|
||||
DCHECK(sig > 0);
|
||||
DCHECK(sigevent);
|
||||
DCHECK(delegate);
|
||||
// TODO if we want to support re-using SignalEvents, this code needs
|
||||
// to jump through the same hoops as WatchFileDescriptor(). Not
|
||||
// needed at present
|
||||
DCHECK(NULL == sigevent->event_);
|
||||
|
||||
scoped_ptr<event> evt(new event);
|
||||
signal_set(evt.get(), sig, OnLibeventSignalNotification, delegate);
|
||||
|
||||
if (event_base_set(event_base_, evt.get()))
|
||||
return false;
|
||||
|
||||
if (signal_add(evt.get(), NULL))
|
||||
return false;
|
||||
|
||||
// Transfer ownership of evt to controller.
|
||||
sigevent->Init(evt.release());
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
MessagePumpLibevent::OnLibeventSignalNotification(int sig, short flags,
|
||||
void* context)
|
||||
{
|
||||
DCHECK(sig > 0);
|
||||
DCHECK(EV_SIGNAL == flags);
|
||||
DCHECK(context);
|
||||
reinterpret_cast<SignalWatcher*>(context)->OnSignal(sig);
|
||||
}
|
||||
#endif // defined(CHROMIUM_MOZILLA_BUILD)
|
||||
|
||||
|
||||
// Reentrant!
|
||||
void MessagePumpLibevent::Run(Delegate* delegate) {
|
||||
DCHECK(keep_running_) << "Quit must have been called outside of Run!";
|
||||
|
@ -84,6 +84,54 @@ class MessagePumpLibevent : public MessagePump {
|
||||
FileDescriptorWatcher *controller,
|
||||
Watcher *delegate);
|
||||
|
||||
|
||||
#if defined(CHROMIUM_MOZILLA_BUILD)
|
||||
// This is analagous to FileDescriptorWatcher above, which really is
|
||||
// just a wrapper around libevent's |struct event|. This class acts
|
||||
// as a sort of "scoped event watcher" in that it guarantees that
|
||||
// when this class is out of scope, the signal-event it wraps is
|
||||
// removed from libevent's guts.
|
||||
//
|
||||
// XXX/cjones: this isn't my favorite API, but preserving it in
|
||||
// order to match code above
|
||||
class SignalEvent {
|
||||
friend class MessagePumpLibevent;
|
||||
|
||||
public:
|
||||
SignalEvent();
|
||||
~SignalEvent(); // implicitly calls StopCatching()
|
||||
|
||||
// Have libevent forget this event.
|
||||
bool StopCatching();
|
||||
|
||||
private:
|
||||
void Init(event* e);
|
||||
event* ReleaseEvent();
|
||||
|
||||
event* event_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(SignalEvent);
|
||||
};
|
||||
|
||||
class SignalWatcher {
|
||||
public:
|
||||
virtual ~SignalWatcher() {}
|
||||
// Called from MessageLoop::Run when |sig| has been delivered to
|
||||
// this process
|
||||
virtual void OnSignal(int sig) = 0;
|
||||
};
|
||||
|
||||
// Have the current thread's message loop catch the signal |sig|.
|
||||
// Multiple watchers can catch the same signal; they're all notified
|
||||
// upon its delivery. Callers must provide a preallocated
|
||||
// SignalEvent object which can be used to manage the lifetime of
|
||||
// this event. Returns true on success.
|
||||
bool CatchSignal(int sig,
|
||||
SignalEvent* sigevent,
|
||||
SignalWatcher* delegate);
|
||||
#endif // defined(CHROMIUM_MOZILLA_BUILD)
|
||||
|
||||
|
||||
// MessagePump methods:
|
||||
virtual void Run(Delegate* delegate);
|
||||
virtual void Quit();
|
||||
@ -112,6 +160,12 @@ class MessagePumpLibevent : public MessagePump {
|
||||
static void OnLibeventNotification(int fd, short flags,
|
||||
void* context);
|
||||
|
||||
#if defined(CHROMIUM_MOZILLA_BUILD)
|
||||
// Called by libevent upon receiving a signal
|
||||
static void OnLibeventSignalNotification(int sig, short flags,
|
||||
void* context);
|
||||
#endif
|
||||
|
||||
// Unix pipe used to implement ScheduleWork()
|
||||
// ... callback; called by libevent inside Run() when pipe is ready to read
|
||||
static void OnWakeup(int socket, short flags, void* context);
|
||||
|
Loading…
Reference in New Issue
Block a user