Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(102)

Side by Side Diff: base/message_pump_libevent.cc

Issue 3202: Make tcp_client_socket_unittest pass on Linux.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « base/message_pump_libevent.h ('k') | build/SConscript.main » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 2006-2008 The Chromium Authors. 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.
4
5 #include "base/message_pump_libevent.h"
6 #include "base/logging.h"
7 #include "base/time.h"
8
9 #include "third_party/libevent/event.h"
10
11 // Called if a byte is received on the wakeup pipe
12 extern "C" void MessagePumpLibevent_wakeup(int socket, short flags, void *contex t) {
13 base::MessagePumpLibevent* that = static_cast<base::MessagePumpLibevent*>(cont ext);
14 DCHECK(that->wakeup_pipe_gazouta_ == socket);
15
16 // remove and discard the wakeup byte
17 char buf;
18 int nread = read(socket, &buf, 1);
19 DCHECK(nread == 1);
20 // tell libevent to break out of inner loop
21 event_base_loopbreak(that->evbase_);
22 }
23
24 namespace base {
25
26 MessagePumpLibevent::MessagePumpLibevent()
27 : keep_running_(true) {
28 evbase_ = event_base_new();
29 wakeup_event_ = new event;
30
31 // Dang, too much real work in the constructor.
32 int fds[2];
33 int err = pipe(fds);
34 DCHECK(!err);
35 if (err) {
36 wakeup_pipe_gazinta_ = -1;
37 wakeup_pipe_gazouta_ = -1;
38 memset(wakeup_event_, 0, sizeof(*wakeup_event_));
39 } else {
40 wakeup_pipe_gazouta_ = fds[0];
41 wakeup_pipe_gazinta_ = fds[1];
42 event_set(wakeup_event_, wakeup_pipe_gazouta_,
43 EV_READ | EV_PERSIST, MessagePumpLibevent_wakeup, this);
44 event_base_set(evbase_, wakeup_event_);
45
46 if (event_add(wakeup_event_, 0) == -1) {
47 DCHECK(0);
48 // Did I mention this was too much real work in the constructor?
49 }
50 }
51 }
52
53 MessagePumpLibevent::~MessagePumpLibevent() {
54 DCHECK(wakeup_event_);
55 DCHECK(evbase_);
56 event_del(wakeup_event_);
57 delete wakeup_event_;
58 wakeup_event_ = 0;
59 event_base_free(evbase_);
60 evbase_ = 0;
61 }
62
63 void MessagePumpLibevent::Run(Delegate* delegate) {
64 DCHECK(keep_running_) << "Quit must have been called outside of Run!";
65
66 for (;;) {
67 bool did_work = delegate->DoWork();
68 if (!keep_running_)
69 break;
70
71 did_work |= delegate->DoDelayedWork(&delayed_work_time_);
72 if (!keep_running_)
73 break;
74
75 if (did_work)
76 continue;
77
78 did_work = delegate->DoIdleWork();
79 if (!keep_running_)
80 break;
81
82 if (did_work)
83 continue;
84
85 // 50 wakeups per second sucks, but without this, tests take a long time or hang.
86 int poll_ms = 20;
87 if (!delayed_work_time_.is_null()) {
88 TimeDelta delay = delayed_work_time_ - Time::Now();
89 if (delay > TimeDelta()) {
90 int delay_ms = delay.InMilliseconds();
91 if (delay_ms < poll_ms)
92 poll_ms = delay_ms;
93 } else {
94 // It looks like delayed_work_time_ indicates a time in the past, so we
95 // need to call DoDelayedWork now.
96 delayed_work_time_ = Time();
97 }
98 }
99 struct timeval poll_tv;
100 poll_tv.tv_sec = 0;
101 poll_tv.tv_usec = poll_ms * 1000;
102 event_base_loopexit(evbase_, &poll_tv);
103 event_base_loop(evbase_, 0);
104 }
105
106 keep_running_ = true;
107 }
108
109 void MessagePumpLibevent::Quit() {
110 ScheduleWork();
111 keep_running_ = false;
112 }
113
114 void MessagePumpLibevent::ScheduleWork() {
115 // This can be called on any thread.
116 // Tell libevent (in a threadsafe way) that it should break out of its loop.
117 char buf = 0;
118 int nwrite = write(wakeup_pipe_gazinta_, &buf, 1);
119 DCHECK(nwrite == 1);
120 }
121
122 void MessagePumpLibevent::ScheduleDelayedWork(const Time& delayed_work_time) {
123 // We know that we can't be blocked on Wait right now since this method can
124 // only be called on the same thread as Run, so we only need to update our
125 // record of how long to sleep when we do sleep.
126 delayed_work_time_ = delayed_work_time;
127 }
128
129 } // namespace base
130
OLDNEW
« no previous file with comments | « base/message_pump_libevent.h ('k') | build/SConscript.main » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698