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

Side by Side Diff: base/message_pump_libevent.h

Issue 2098020: Jankometer: Generalize the code more. Add better support for monitoring IO thread. (Closed) Base URL: http://src.chromium.org/git/chromium.git
Patch Set: Address darin's comments. Created 10 years, 6 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
« no previous file with comments | « base/message_loop_unittest.cc ('k') | base/message_pump_libevent.cc » ('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) 2006-2008 The Chromium Authors. All rights reserved. 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 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 #ifndef BASE_MESSAGE_PUMP_LIBEVENT_H_ 5 #ifndef BASE_MESSAGE_PUMP_LIBEVENT_H_
6 #define BASE_MESSAGE_PUMP_LIBEVENT_H_ 6 #define BASE_MESSAGE_PUMP_LIBEVENT_H_
7 7
8 #include "base/basictypes.h"
8 #include "base/message_pump.h" 9 #include "base/message_pump.h"
10 #include "base/observer_list.h"
9 #include "base/time.h" 11 #include "base/time.h"
10 12
11 // Declare structs we need from libevent.h rather than including it 13 // Declare structs we need from libevent.h rather than including it
12 struct event_base; 14 struct event_base;
13 struct event; 15 struct event;
14 16
15 namespace base { 17 namespace base {
16 18
17 // Class to monitor sockets and issue callbacks when sockets are ready for I/O 19 // Class to monitor sockets and issue callbacks when sockets are ready for I/O
18 // TODO(dkegel): add support for background file IO somehow 20 // TODO(dkegel): add support for background file IO somehow
19 class MessagePumpLibevent : public MessagePump { 21 class MessagePumpLibevent : public MessagePump {
20 public: 22 public:
23 class IOObserver {
24 public:
25 IOObserver() {}
21 26
22 // Object returned by WatchFileDescriptor to manage further watching. 27 // An IOObserver is an object that receives IO notifications from the
23 class FileDescriptorWatcher { 28 // MessagePump.
24 public: 29 //
25 FileDescriptorWatcher(); 30 // NOTE: An IOObserver implementation should be extremely fast!
26 ~FileDescriptorWatcher(); // Implicitly calls StopWatchingFileDescriptor. 31 virtual void WillProcessIOEvent() = 0;
32 virtual void DidProcessIOEvent() = 0;
27 33
28 // NOTE: These methods aren't called StartWatching()/StopWatching() to 34 protected:
29 // avoid confusion with the win32 ObjectWatcher class. 35 virtual ~IOObserver() {}
30
31 // Stop watching the FD, always safe to call. No-op if there's nothing
32 // to do.
33 bool StopWatchingFileDescriptor();
34
35 private:
36 // Called by MessagePumpLibevent, ownership of |e| is transferred to this
37 // object.
38 void Init(event* e, bool is_persistent);
39
40 // Used by MessagePumpLibevent to take ownership of event_.
41 event *ReleaseEvent();
42 friend class MessagePumpLibevent;
43
44 private:
45 bool is_persistent_; // false if this event is one-shot.
46 event* event_;
47 DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
48 }; 36 };
49 37
50 // Used with WatchFileDescptor to asynchronously monitor the I/O readiness of 38 // Used with WatchFileDescptor to asynchronously monitor the I/O readiness of
51 // a File Descriptor. 39 // a File Descriptor.
52 class Watcher { 40 class Watcher {
53 public: 41 public:
54 virtual ~Watcher() {} 42 virtual ~Watcher() {}
55 // Called from MessageLoop::Run when an FD can be read from/written to 43 // Called from MessageLoop::Run when an FD can be read from/written to
56 // without blocking 44 // without blocking
57 virtual void OnFileCanReadWithoutBlocking(int fd) = 0; 45 virtual void OnFileCanReadWithoutBlocking(int fd) = 0;
58 virtual void OnFileCanWriteWithoutBlocking(int fd) = 0; 46 virtual void OnFileCanWriteWithoutBlocking(int fd) = 0;
59 }; 47 };
60 48
49 // Object returned by WatchFileDescriptor to manage further watching.
50 class FileDescriptorWatcher {
51 public:
52 FileDescriptorWatcher();
53 ~FileDescriptorWatcher(); // Implicitly calls StopWatchingFileDescriptor.
54
55 // NOTE: These methods aren't called StartWatching()/StopWatching() to
56 // avoid confusion with the win32 ObjectWatcher class.
57
58 // Stop watching the FD, always safe to call. No-op if there's nothing
59 // to do.
60 bool StopWatchingFileDescriptor();
61
62 private:
63 friend class MessagePumpLibevent;
64
65 // Called by MessagePumpLibevent, ownership of |e| is transferred to this
66 // object.
67 void Init(event* e, bool is_persistent);
68
69 // Used by MessagePumpLibevent to take ownership of event_.
70 event *ReleaseEvent();
71
72 void set_pump(MessagePumpLibevent* pump) { pump_ = pump; }
73 MessagePumpLibevent* pump() { return pump_; }
74
75 void set_watcher(Watcher* watcher) { watcher_ = watcher; }
76
77 void OnFileCanReadWithoutBlocking(int fd, MessagePumpLibevent* pump);
78 void OnFileCanWriteWithoutBlocking(int fd, MessagePumpLibevent* pump);
79
80 bool is_persistent_; // false if this event is one-shot.
81 event* event_;
82 MessagePumpLibevent* pump_;
83 Watcher* watcher_;
84
85 DISALLOW_COPY_AND_ASSIGN(FileDescriptorWatcher);
86 };
87
61 MessagePumpLibevent(); 88 MessagePumpLibevent();
62 virtual ~MessagePumpLibevent(); 89 virtual ~MessagePumpLibevent();
63 90
64 enum Mode { 91 enum Mode {
65 WATCH_READ = 1 << 0, 92 WATCH_READ = 1 << 0,
66 WATCH_WRITE = 1 << 1, 93 WATCH_WRITE = 1 << 1,
67 WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE 94 WATCH_READ_WRITE = WATCH_READ | WATCH_WRITE
68 }; 95 };
69 96
70 // Have the current thread's message loop watch for a a situation in which 97 // Have the current thread's message loop watch for a a situation in which
71 // reading/writing to the FD can be performed without blocking. 98 // reading/writing to the FD can be performed without blocking.
72 // Callers must provide a preallocated FileDescriptorWatcher object which 99 // Callers must provide a preallocated FileDescriptorWatcher object which
73 // can later be used to manage the lifetime of this event. 100 // can later be used to manage the lifetime of this event.
74 // If a FileDescriptorWatcher is passed in which is already attached to 101 // If a FileDescriptorWatcher is passed in which is already attached to
75 // an event, then the effect is cumulative i.e. after the call |controller| 102 // an event, then the effect is cumulative i.e. after the call |controller|
76 // will watch both the previous event and the new one. 103 // will watch both the previous event and the new one.
77 // If an error occurs while calling this method in a cumulative fashion, the 104 // If an error occurs while calling this method in a cumulative fashion, the
78 // event previously attached to |controller| is aborted. 105 // event previously attached to |controller| is aborted.
79 // Returns true on success. 106 // Returns true on success.
80 // TODO(dkegel): switch to edge-triggered readiness notification 107 // TODO(dkegel): switch to edge-triggered readiness notification
81 bool WatchFileDescriptor(int fd, 108 bool WatchFileDescriptor(int fd,
82 bool persistent, 109 bool persistent,
83 Mode mode, 110 Mode mode,
84 FileDescriptorWatcher *controller, 111 FileDescriptorWatcher *controller,
85 Watcher *delegate); 112 Watcher *delegate);
86 113
114 void AddIOObserver(IOObserver* obs);
115 void RemoveIOObserver(IOObserver* obs);
116
87 // MessagePump methods: 117 // MessagePump methods:
88 virtual void Run(Delegate* delegate); 118 virtual void Run(Delegate* delegate);
89 virtual void Quit(); 119 virtual void Quit();
90 virtual void ScheduleWork(); 120 virtual void ScheduleWork();
91 virtual void ScheduleDelayedWork(const Time& delayed_work_time); 121 virtual void ScheduleDelayedWork(const Time& delayed_work_time);
92 122
93 private: 123 private:
124 void WillProcessIOEvent();
125 void DidProcessIOEvent();
94 126
95 // Risky part of constructor. Returns true on success. 127 // Risky part of constructor. Returns true on success.
96 bool Init(); 128 bool Init();
97 129
98 // This flag is set to false when Run should return. 130 // This flag is set to false when Run should return.
99 bool keep_running_; 131 bool keep_running_;
100 132
101 // This flag is set when inside Run. 133 // This flag is set when inside Run.
102 bool in_run_; 134 bool in_run_;
103 135
(...skipping 11 matching lines...) Expand all
115 // Unix pipe used to implement ScheduleWork() 147 // Unix pipe used to implement ScheduleWork()
116 // ... callback; called by libevent inside Run() when pipe is ready to read 148 // ... callback; called by libevent inside Run() when pipe is ready to read
117 static void OnWakeup(int socket, short flags, void* context); 149 static void OnWakeup(int socket, short flags, void* context);
118 // ... write end; ScheduleWork() writes a single byte to it 150 // ... write end; ScheduleWork() writes a single byte to it
119 int wakeup_pipe_in_; 151 int wakeup_pipe_in_;
120 // ... read end; OnWakeup reads it and then breaks Run() out of its sleep 152 // ... read end; OnWakeup reads it and then breaks Run() out of its sleep
121 int wakeup_pipe_out_; 153 int wakeup_pipe_out_;
122 // ... libevent wrapper for read end 154 // ... libevent wrapper for read end
123 event* wakeup_event_; 155 event* wakeup_event_;
124 156
157 ObserverList<IOObserver> io_observers_;
158
125 DISALLOW_COPY_AND_ASSIGN(MessagePumpLibevent); 159 DISALLOW_COPY_AND_ASSIGN(MessagePumpLibevent);
126 }; 160 };
127 161
128 } // namespace base 162 } // namespace base
129 163
130 #endif // BASE_MESSAGE_PUMP_LIBEVENT_H_ 164 #endif // BASE_MESSAGE_PUMP_LIBEVENT_H_
OLDNEW
« no previous file with comments | « base/message_loop_unittest.cc ('k') | base/message_pump_libevent.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698