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

Side by Side Diff: mojo/spy/spy.cc

Issue 225203002: Mojo Spy core first cut (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: first version Created 6 years, 8 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
« mojo/service_manager/service_manager.cc ('K') | « mojo/spy/spy.h ('k') | no next file » | 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 2014 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 "mojo/spy/spy.h"
6
7 #include "base/bind.h"
8 #include "base/location.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/threading/worker_pool.h"
11
12 #include "mojo/public/cpp/system/core.h"
13 #include "mojo/service_manager/service_manager.h"
14
15 namespace {
16
17 const size_t kMessageBufSize = 2 * 1024;
18 const size_t kHandleBufSize = 64;
19
20 // In charge of processing messages that flow over a
21 // single message pipe.
22 class MessageProcessor :
23 public base::RefCountedThreadSafe<MessageProcessor> {
24 public:
25
26 MessageProcessor()
27 : last_result_(MOJO_RESULT_OK),
28 bytes_transfered_(0) {
29
30 message_count_[0] = 0;
31 message_count_[1] = 0;
32 handle_count_[0] = 0;
33 handle_count_[1] = 0;
34 }
35
36 virtual ~MessageProcessor() {}
37
38 void Start(mojo::ScopedMessagePipeHandle client,
39 mojo::ScopedMessagePipeHandle interceptor) {
40
DaveMoore 2014/04/04 21:06:46 Nit: Extra blank line
cpu_(ooo_6.6-7.5) 2014/04/04 23:42:45 Done.
41 std::vector<mojo::MessagePipeHandle> pipes;
42 pipes.push_back(client.get());
43 pipes.push_back(interceptor.get());
44 std::vector<MojoWaitFlags> wait_flags;
45 wait_flags.push_back(MOJO_WAIT_FLAG_READABLE);
46 wait_flags.push_back(MOJO_WAIT_FLAG_READABLE);
47
48 scoped_ptr<char> mbuf(new char[kMessageBufSize]);
49 scoped_ptr<MojoHandle> hbuf(new MojoHandle[kHandleBufSize]);
50
51 // Main processing loop:
52 // 1- Wait for an empoint to have a message.
DaveMoore 2014/04/04 21:06:46 Nit: endpoint?
cpu_(ooo_6.6-7.5) 2014/04/04 23:42:45 Done.
53 // 2- Read the message
54 // 3- Log data
55 // 4- Wait until the opposite port is ready for writting
56 // 4- Write the message to opposite port.
57
58 for (;;) {
59 int r = WaitMany(pipes, wait_flags, MOJO_DEADLINE_INDEFINITE);
60 if ((r < 0) || (r > 1)) {
61 last_result_ = r;
62 break;
63 }
64
65 uint32_t bytes_read = kMessageBufSize;
66 uint32_t handles_read = kHandleBufSize;
67
68 if (!CheckResult(ReadMessageRaw(pipes[r],
69 mbuf.get(), &bytes_read,
70 hbuf.get(), &handles_read,
71 MOJO_READ_MESSAGE_FLAG_NONE)))
72 break;
73
74 if (!bytes_read && !handles_read)
75 continue;
76
77 if (handles_read)
78 handle_count_[r] += handles_read;
79
80 ++message_count_[r];
81 bytes_transfered_ += bytes_read;
82
83 mojo::MessagePipeHandle write_handle = (r == 0) ? pipes[1] : pipes[0];
84 if(!CheckResult(Wait(write_handle,
DaveMoore 2014/04/04 21:06:46 Nit: space after if
cpu_(ooo_6.6-7.5) 2014/04/04 23:42:45 Done.
85 MOJO_WAIT_FLAG_WRITABLE,
86 MOJO_DEADLINE_INDEFINITE)))
87 break;
88
89 if(!CheckResult(WriteMessageRaw(write_handle,
DaveMoore 2014/04/04 21:06:46 Nit: space after if
cpu_(ooo_6.6-7.5) 2014/04/04 23:42:45 Done.
90 mbuf.get(), bytes_read,
91 hbuf.get(), handles_read,
92 MOJO_WRITE_MESSAGE_FLAG_NONE)))
93 break;
94 }
95
96 }
97
98 private:
99 bool CheckResult(MojoResult mr) {
100 if (mr == MOJO_RESULT_OK)
101 return true;
102 last_result_ = mr;
103 return false;
104 }
105
106 MojoResult last_result_;
107 uint32_t bytes_transfered_;
108 uint32_t message_count_[2];
109 uint32_t handle_count_[2];
110 };
111
112 // In charge of intercepting access to the service manager.
113 class SpyInterceptor : public mojo::ServiceInterceptor {
114 private:
115 virtual mojo::ScopedMessagePipeHandle OnConnectToClient(
116 const GURL& url, mojo::ScopedMessagePipeHandle real_client) {
117 if (!MustIntercept(url))
118 return real_client.Pass();
119
120 // You can get an invalid handle if the app (or service) is
121 // by unconventional means, for example the command line.
122 if (!real_client.is_valid())
123 return real_client.Pass();
124
125 mojo::ScopedMessagePipeHandle faux_client;
126 mojo::ScopedMessagePipeHandle interceptor;
127 CreateMessagePipe(&faux_client, &interceptor);
128
129 scoped_refptr<MessageProcessor> processor = new MessageProcessor();
130 base::WorkerPool::PostTask(
131 FROM_HERE,
132 base::Bind(&MessageProcessor::Start,
133 processor,
134 base::Passed(&real_client), base::Passed(&interceptor)),
135 true);
136
137 return faux_client.Pass();
138 }
139
140 bool MustIntercept(const GURL& url) {
141 // TODO(cpu): manage who and when to intercept.
142 return true;
143 }
144 };
145
146 } // namespace
147
148 namespace mojo {
149
150 Spy::Spy(mojo::ServiceManager* service_manager, const std::string& options) {
151 service_manager->SetInterceptor(new SpyInterceptor());
152 }
153
154 Spy::~Spy(){
155 // TODO(cpu): Do not leak the interceptor. Lifetime between the
156 // service_manager and the spy is still unclear hence the leak.
157 }
158
159 } // namespace mojo
OLDNEW
« mojo/service_manager/service_manager.cc ('K') | « mojo/spy/spy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698