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

Side by Side Diff: base/message_pump_libevent.cc

Issue 14068: Reverting 6911. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years 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') | chrome/common/ipc_channel_posix.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/message_pump_libevent.h" 5 #include "base/message_pump_libevent.h"
6 6
7 #include <fcntl.h> 7 #include <fcntl.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/scoped_nsautorelease_pool.h" 10 #include "base/scoped_nsautorelease_pool.h"
11 #include "base/time.h" 11 #include "base/time.h"
12 #include "third_party/libevent/event.h" 12 #include "third_party/libevent/event.h"
13 13
14 namespace base { 14 namespace base {
15 15
16 // Return 0 on success 16 // Return 0 on success
17 // Too small a function to bother putting in a library? 17 // Too small a function to bother putting in a library?
18 static int SetNonBlocking(int fd) { 18 static int SetNonBlocking(int fd)
19 int flags = fcntl(fd, F_GETFL, 0); 19 {
20 if (flags == -1) 20 int flags = fcntl(fd, F_GETFL, 0);
21 flags = 0; 21 if (-1 == flags)
22 return fcntl(fd, F_SETFL, flags | O_NONBLOCK); 22 flags = 0;
23 } 23 return fcntl(fd, F_SETFL, flags | O_NONBLOCK);
24
25 MessagePumpLibevent::FileDescriptorWatcher::FileDescriptorWatcher()
26 : is_persistent_(false),
27 event_(NULL) {
28 }
29
30 MessagePumpLibevent::FileDescriptorWatcher::~FileDescriptorWatcher() {
31 if (event_.get()) {
32 StopWatchingFileDescriptor();
33 }
34 }
35
36 void MessagePumpLibevent::FileDescriptorWatcher::Init(event *e,
37 bool is_persistent) {
38 DCHECK(e);
39
40 // Cleanup any old event we might have been watching.
41 if (event_.get()) {
42 StopWatchingFileDescriptor();
43 }
44
45 is_persistent = is_persistent_;
46 event_.reset(e);
47 }
48
49 bool MessagePumpLibevent::FileDescriptorWatcher::StopWatchingFileDescriptor() {
50 if (event_.get() == NULL) {
51 return true;
52 }
53
54 // event_del() is a no-op of the event isn't active.
55 return (event_del(event_.get()) == 0);
56 } 24 }
57 25
58 // Called if a byte is received on the wakeup pipe. 26 // Called if a byte is received on the wakeup pipe.
59 void MessagePumpLibevent::OnWakeup(int socket, short flags, void* context) { 27 void MessagePumpLibevent::OnWakeup(int socket, short flags, void* context) {
28
60 base::MessagePumpLibevent* that = 29 base::MessagePumpLibevent* that =
61 static_cast<base::MessagePumpLibevent*>(context); 30 static_cast<base::MessagePumpLibevent*>(context);
62 DCHECK(that->wakeup_pipe_out_ == socket); 31 DCHECK(that->wakeup_pipe_out_ == socket);
63 32
64 // Remove and discard the wakeup byte. 33 // Remove and discard the wakeup byte.
65 char buf; 34 char buf;
66 int nread = read(socket, &buf, 1); 35 int nread = read(socket, &buf, 1);
67 DCHECK(nread == 1); 36 DCHECK(nread == 1);
68 // Tell libevent to break out of inner loop. 37 // Tell libevent to break out of inner loop.
69 event_base_loopbreak(that->event_base_); 38 event_base_loopbreak(that->event_base_);
(...skipping 15 matching lines...) Expand all
85 return false; 54 return false;
86 if (SetNonBlocking(fds[0])) 55 if (SetNonBlocking(fds[0]))
87 return false; 56 return false;
88 if (SetNonBlocking(fds[1])) 57 if (SetNonBlocking(fds[1]))
89 return false; 58 return false;
90 wakeup_pipe_out_ = fds[0]; 59 wakeup_pipe_out_ = fds[0];
91 wakeup_pipe_in_ = fds[1]; 60 wakeup_pipe_in_ = fds[1];
92 61
93 wakeup_event_ = new event; 62 wakeup_event_ = new event;
94 event_set(wakeup_event_, wakeup_pipe_out_, EV_READ | EV_PERSIST, 63 event_set(wakeup_event_, wakeup_pipe_out_, EV_READ | EV_PERSIST,
95 OnWakeup, this); 64 » OnWakeup, this);
96 event_base_set(event_base_, wakeup_event_); 65 event_base_set(event_base_, wakeup_event_);
97 66
98 if (event_add(wakeup_event_, 0)) 67 if (event_add(wakeup_event_, 0))
99 return false; 68 return false;
100 return true; 69 return true;
101 } 70 }
102 71
103 MessagePumpLibevent::~MessagePumpLibevent() { 72 MessagePumpLibevent::~MessagePumpLibevent() {
104 DCHECK(wakeup_event_); 73 DCHECK(wakeup_event_);
105 DCHECK(event_base_); 74 DCHECK(event_base_);
106 event_del(wakeup_event_); 75 event_del(wakeup_event_);
107 delete wakeup_event_; 76 delete wakeup_event_;
108 event_base_free(event_base_); 77 event_base_free(event_base_);
109 } 78 }
110 79
111 bool MessagePumpLibevent::WatchFileDescriptor(int fd, 80 void MessagePumpLibevent::WatchSocket(int socket, short interest_mask,
112 bool persistent, 81 event* e, Watcher* watcher) {
113 Mode mode,
114 FileDescriptorWatcher *controller,
115 Watcher *delegate) {
116 DCHECK(fd > 0);
117 DCHECK(controller);
118 DCHECK(delegate);
119 DCHECK(mode == WATCH_READ || mode == WATCH_WRITE || mode == WATCH_READ_WRITE);
120 82
121 int event_mask = persistent ? EV_PERSIST : 0; 83 // Set current interest mask and message pump for this event
122 if (mode == WATCH_READ || mode == WATCH_READ_WRITE) { 84 event_set(e, socket, interest_mask, OnReadinessNotification, watcher);
123 event_mask |= EV_READ; 85
124 } 86 // Tell libevent which message pump this socket will belong to when we add it.
125 if (mode == WATCH_WRITE || mode == WATCH_READ_WRITE) { 87 event_base_set(event_base_, e);
126 event_mask |= EV_WRITE; 88
89 // Add this socket to the list of monitored sockets.
90 if (event_add(e, NULL))
91 NOTREACHED();
92 }
93
94 void MessagePumpLibevent::WatchFileHandle(int fd, short interest_mask,
95 event* e, FileWatcher* watcher) {
96 // Set current interest mask and message pump for this event
97 if ((interest_mask & EV_READ) != 0) {
98 event_set(e, fd, interest_mask, OnFileReadReadinessNotification, watcher);
99 } else {
100 event_set(e, fd, interest_mask, OnFileWriteReadinessNotification, watcher);
127 } 101 }
128 102
129 // Ownership is transferred to the controller. 103 // Tell libevent which message pump this fd will belong to when we add it.
130 scoped_ptr<event> evt(new event); 104 event_base_set(event_base_, e);
131 // Set current interest mask and message pump for this event.
132 event_set(evt.get(), fd, event_mask | EV_READ, OnLibeventNotification,
133 delegate);
134 105
135 // Tell libevent which message pump this socket will belong to when we add it. 106 // Add this fd to the list of monitored sockets.
136 if (event_base_set(event_base_, evt.get()) != 0) { 107 if (event_add(e, NULL))
137 return false; 108 NOTREACHED();
138 }
139
140 // Add this socket to the list of monitored sockets.
141 if (event_add(evt.get(), NULL) != 0) {
142 return false;
143 }
144
145 // Transfer ownership of e to controller.
146 controller->Init(evt.release(), persistent);
147 return true;
148 } 109 }
149 110
111 void MessagePumpLibevent::UnwatchSocket(event* e) {
112 // Remove this socket from the list of monitored sockets.
113 if (event_del(e))
114 NOTREACHED();
115 }
150 116
151 void MessagePumpLibevent::OnLibeventNotification(int fd, short flags, 117 void MessagePumpLibevent::UnwatchFileHandle(event* e) {
152 void* context) { 118 // Remove this fd from the list of monitored fds.
119 if (event_del(e))
120 NOTREACHED();
121 }
122
123 void MessagePumpLibevent::OnReadinessNotification(int socket, short flags,
124 void* context) {
125 // The given socket is ready for I/O.
126 // Tell the owner what kind of I/O the socket is ready for.
153 Watcher* watcher = static_cast<Watcher*>(context); 127 Watcher* watcher = static_cast<Watcher*>(context);
128 watcher->OnSocketReady(flags);
129 }
154 130
155 if (flags & EV_WRITE) { 131 void MessagePumpLibevent::OnFileReadReadinessNotification(int fd, short flags,
156 watcher->OnFileCanWriteWithoutBlocking(fd); 132 void* context) {
157 } 133 FileWatcher* watcher = static_cast<FileWatcher*>(context);
158 if (flags & EV_READ) { 134 watcher->OnFileReadReady(fd);
159 watcher->OnFileCanReadWithoutBlocking(fd); 135 }
160 } 136
137 void MessagePumpLibevent::OnFileWriteReadinessNotification(int fd, short flags,
138 void* context) {
139 FileWatcher* watcher = static_cast<FileWatcher*>(context);
140 watcher->OnFileWriteReady(fd);
161 } 141 }
162 142
163 // Reentrant! 143 // Reentrant!
164 void MessagePumpLibevent::Run(Delegate* delegate) { 144 void MessagePumpLibevent::Run(Delegate* delegate) {
165 DCHECK(keep_running_) << "Quit must have been called outside of Run!"; 145 DCHECK(keep_running_) << "Quit must have been called outside of Run!";
166 146
167 bool old_in_run = in_run_; 147 bool old_in_run = in_run_;
168 in_run_ = true; 148 in_run_ = true;
169 149
170 for (;;) { 150 for (;;) {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 } 207 }
228 208
229 void MessagePumpLibevent::ScheduleDelayedWork(const Time& delayed_work_time) { 209 void MessagePumpLibevent::ScheduleDelayedWork(const Time& delayed_work_time) {
230 // We know that we can't be blocked on Wait right now since this method can 210 // We know that we can't be blocked on Wait right now since this method can
231 // only be called on the same thread as Run, so we only need to update our 211 // only be called on the same thread as Run, so we only need to update our
232 // record of how long to sleep when we do sleep. 212 // record of how long to sleep when we do sleep.
233 delayed_work_time_ = delayed_work_time; 213 delayed_work_time_ = delayed_work_time;
234 } 214 }
235 215
236 } // namespace base 216 } // namespace base
OLDNEW
« no previous file with comments | « base/message_pump_libevent.h ('k') | chrome/common/ipc_channel_posix.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698