1 // Copyright 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ozone/wayland/display_poll_thread.h"
10 #include <sys/socket.h>
11 #include <sys/types.h>
12 #include <wayland-client.h>
14 #include "base/bind.h"
15 #include "ozone/wayland/display.h"
17 namespace ozonewayland {
18 const int MAX_EVENTS = 16;
20 WaylandDisplayPollThread::WaylandDisplayPollThread(wl_display* display)
21 : base::Thread("WaylandDisplayPollThread"),
23 polling_(true, false),
24 stop_polling_(true, false) {
28 WaylandDisplayPollThread::~WaylandDisplayPollThread() {
29 StopProcessingEvents();
32 void WaylandDisplayPollThread::StartProcessingEvents() {
33 DCHECK(!polling_.IsSignaled());
34 base::Thread::Options options;
35 options.message_loop_type = base::MessageLoop::TYPE_IO;
36 StartWithOptions(options);
37 SetPriority(base::kThreadPriority_Background);
38 message_loop_proxy()->PostTask(FROM_HERE, base::Bind(
39 &WaylandDisplayPollThread::DisplayRun, this));
42 void WaylandDisplayPollThread::StopProcessingEvents() {
43 if (polling_.IsSignaled())
44 stop_polling_.Signal();
49 void WaylandDisplayPollThread::CleanUp() {
50 SetThreadWasQuitProperly(true);
53 void WaylandDisplayPollThread::DisplayRun(WaylandDisplayPollThread* data) {
55 int i, ret, count = 0;
57 unsigned display_fd = wl_display_get_fd(data->display_);
59 ep.events = POLLIN | POLLERR | POLLHUP;
61 // Set the signal state. This is used to query from other threads (i.e.
62 // StopProcessingEvents on Main thread), if this thread is still polling.
63 data->polling_.Signal();
66 // http://cgit.freedesktop.org/wayland/weston/tree/clients/window.c#n5531.
68 wl_display_dispatch_pending(data->display_);
69 ret = wl_display_flush(data->display_);
70 if (ret < 0 && errno != EAGAIN) {
73 // StopProcessingEvents has been called or we have been asked to stop
74 // polling. Break from the loop.
75 if (data->stop_polling_.IsSignaled())
78 count = poll(&ep, 1, -1);
79 // Break if epoll wait returned value less than 0 and we aren't interrupted
81 if (count < 0 && errno != EINTR) {
82 LOG(ERROR) << "poll returned an error." << errno;
88 // We can have cases where POLLIN and POLLHUP are both set for
89 // example. Don't break if both flags are set.
90 if ((event & POLLERR || event & POLLHUP) &&
96 ret = wl_display_dispatch(data->display_);
98 LOG(ERROR) << "wl_display_dispatch failed with an error." << errno;
105 data->polling_.Reset();
106 data->stop_polling_.Reset();
109 } // namespace ozonewayland