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

Side by Side Diff: third_party/WebKit/Source/modules/fetch/CompositeDataConsumerHandleTest.cpp

Issue 2342233002: Remove Fetch[Blob|FormData]ConsumerHandle (Closed)
Patch Set: rebase Created 4 years, 2 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
OLDNEW
(Empty)
1 // Copyright 2015 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 "modules/fetch/CompositeDataConsumerHandle.h"
6
7 #include "modules/fetch/DataConsumerHandleTestUtil.h"
8 #include "platform/CrossThreadFunctional.h"
9 #include "platform/WaitableEvent.h"
10 #include "platform/heap/Handle.h"
11 #include "public/platform/Platform.h"
12 #include "public/platform/WebThread.h"
13 #include "public/platform/WebTraceLocation.h"
14 #include "testing/gmock/include/gmock/gmock.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "wtf/Locker.h"
17 #include "wtf/PtrUtil.h"
18 #include <memory>
19
20 namespace blink {
21
22 namespace {
23
24 using ::testing::ByMove;
25 using ::testing::InSequence;
26 using ::testing::Return;
27 using ::testing::StrictMock;
28 using Checkpoint = StrictMock<::testing::MockFunction<void(int)>>;
29
30 const WebDataConsumerHandle::Result kShouldWait = WebDataConsumerHandle::ShouldW ait;
31 const WebDataConsumerHandle::Result kOk = WebDataConsumerHandle::Ok;
32 const WebDataConsumerHandle::Flags kNone = WebDataConsumerHandle::FlagNone;
33
34 class MockReader : public WebDataConsumerHandle::Reader {
35 public:
36 static std::unique_ptr<StrictMock<MockReader>> create() { return wrapUnique( new StrictMock<MockReader>); }
37
38 using Result = WebDataConsumerHandle::Result;
39 using Flags = WebDataConsumerHandle::Flags;
40 MOCK_METHOD4(read, Result(void*, size_t, Flags, size_t*));
41 MOCK_METHOD3(beginRead, Result(const void**, Flags, size_t*));
42 MOCK_METHOD1(endRead, Result(size_t));
43 };
44
45 class MockHandle : public WebDataConsumerHandle {
46 public:
47 static std::unique_ptr<StrictMock<MockHandle>> create() { return wrapUnique( new StrictMock<MockHandle>); }
48
49 MOCK_METHOD1(obtainReader, std::unique_ptr<Reader>(Client*));
50
51 private:
52 const char* debugName() const override { return "MockHandle in CompositeData ConsumerHandleTest"; }
53 };
54
55 class ThreadingRegistrationTest : public DataConsumerHandleTestUtil::ThreadingTe stBase {
56 public:
57 using Self = ThreadingRegistrationTest;
58 static PassRefPtr<Self> create() { return adoptRef(new Self); }
59
60 void run()
61 {
62 ThreadHolder holder(this);
63 m_waitableEvent = wrapUnique(new WaitableEvent());
64
65 postTaskToUpdatingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self:: createHandle, wrapPassRefPtr(this)));
66 postTaskToReadingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self::o btainReader, wrapPassRefPtr(this)));
67 }
68
69 private:
70 ThreadingRegistrationTest() = default;
71
72 void createHandle()
73 {
74 m_handle = CompositeDataConsumerHandle::create(DataConsumerHandle::creat e("handle1", m_context), &m_updater);
75 m_waitableEvent->signal();
76 }
77 void obtainReader()
78 {
79 m_reader = m_handle->obtainReader(&m_client);
80 postTaskToUpdatingThread(BLINK_FROM_HERE, crossThreadBind(&Self::update, wrapPassRefPtr(this)));
81 }
82 void update()
83 {
84 m_updater->update(DataConsumerHandle::create("handle2", m_context));
85 m_updater.clear();
86 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::resetRea der, wrapPassRefPtr(this)));
87 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::signalDo ne, wrapPassRefPtr(this)));
88 }
89
90 std::unique_ptr<WebDataConsumerHandle> m_handle;
91 CrossThreadPersistent<CompositeDataConsumerHandle::Updater> m_updater;
92 };
93
94 class ThreadingRegistrationDeleteHandleTest : public DataConsumerHandleTestUtil: :ThreadingTestBase {
95 public:
96 using Self = ThreadingRegistrationDeleteHandleTest;
97 static PassRefPtr<Self> create() { return adoptRef(new Self); }
98
99 void run()
100 {
101 ThreadHolder holder(this);
102 m_waitableEvent = wrapUnique(new WaitableEvent());
103
104 postTaskToUpdatingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self:: createHandle, wrapPassRefPtr(this)));
105 postTaskToReadingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self::o btainReader, wrapPassRefPtr(this)));
106 }
107
108 private:
109 ThreadingRegistrationDeleteHandleTest() = default;
110
111 void createHandle()
112 {
113 m_handle = CompositeDataConsumerHandle::create(DataConsumerHandle::creat e("handle1", m_context), &m_updater);
114 m_waitableEvent->signal();
115 }
116
117 void obtainReader()
118 {
119 m_reader = m_handle->obtainReader(&m_client);
120 postTaskToUpdatingThread(BLINK_FROM_HERE, crossThreadBind(&Self::update, wrapPassRefPtr(this)));
121 }
122 void update()
123 {
124 m_updater->update(DataConsumerHandle::create("handle2", m_context));
125 m_updater.clear();
126 m_handle = nullptr;
127 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::resetRea der, wrapPassRefPtr(this)));
128 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::signalDo ne, wrapPassRefPtr(this)));
129 }
130
131 std::unique_ptr<WebDataConsumerHandle> m_handle;
132 CrossThreadPersistent<CompositeDataConsumerHandle::Updater> m_updater;
133 };
134
135 class ThreadingRegistrationDeleteReaderTest : public DataConsumerHandleTestUtil: :ThreadingTestBase {
136 public:
137 using Self = ThreadingRegistrationDeleteReaderTest;
138 static PassRefPtr<Self> create() { return adoptRef(new Self); }
139
140 void run()
141 {
142 ThreadHolder holder(this);
143 m_waitableEvent = wrapUnique(new WaitableEvent());
144
145 postTaskToUpdatingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self:: createHandle, wrapPassRefPtr(this)));
146 postTaskToReadingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self::o btainReader, wrapPassRefPtr(this)));
147 }
148
149 private:
150 ThreadingRegistrationDeleteReaderTest() = default;
151
152 void createHandle()
153 {
154 m_handle = CompositeDataConsumerHandle::create(DataConsumerHandle::creat e("handle1", m_context), &m_updater);
155 m_waitableEvent->signal();
156 }
157
158 void obtainReader()
159 {
160 m_reader = m_handle->obtainReader(&m_client);
161 postTaskToUpdatingThread(BLINK_FROM_HERE, crossThreadBind(&Self::update, wrapPassRefPtr(this)));
162 }
163 void update()
164 {
165 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::resetRea der, wrapPassRefPtr(this)));
166 m_updater->update(DataConsumerHandle::create("handle2", m_context));
167 m_updater.clear();
168 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::resetRea der, wrapPassRefPtr(this)));
169 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::signalDo ne, wrapPassRefPtr(this)));
170 }
171
172 std::unique_ptr<WebDataConsumerHandle> m_handle;
173 CrossThreadPersistent<CompositeDataConsumerHandle::Updater> m_updater;
174 };
175
176 class ThreadingUpdatingReaderWhileUpdatingTest : public DataConsumerHandleTestUt il::ThreadingTestBase {
177 public:
178 using Self = ThreadingUpdatingReaderWhileUpdatingTest;
179 static PassRefPtr<Self> create() { return adoptRef(new Self); }
180
181 void run()
182 {
183 ThreadHolder holder(this);
184 m_waitableEvent = wrapUnique(new WaitableEvent());
185 m_updateEvent = wrapUnique(new WaitableEvent());
186
187 postTaskToUpdatingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self:: createHandle, wrapPassRefPtr(this)));
188 postTaskToReadingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self::o btainReader, wrapPassRefPtr(this)));
189 }
190
191 private:
192 ThreadingUpdatingReaderWhileUpdatingTest() = default;
193
194 void createHandle()
195 {
196 m_handle = CompositeDataConsumerHandle::create(DataConsumerHandle::creat e("handle1", m_context), &m_updater);
197 m_waitableEvent->signal();
198 }
199
200 void obtainReader()
201 {
202 m_reader = m_handle->obtainReader(&m_client);
203 postTaskToUpdatingThread(BLINK_FROM_HERE, crossThreadBind(&Self::update, wrapPassRefPtr(this)));
204 m_updateEvent->wait();
205 }
206
207 void update()
208 {
209 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::reobtain Reader, wrapPassRefPtr(this)));
210 m_updater->update(DataConsumerHandle::create("handle2", m_context));
211 m_updater.clear();
212 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::resetRea der, wrapPassRefPtr(this)));
213 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::signalDo ne, wrapPassRefPtr(this)));
214 m_updateEvent->signal();
215 }
216
217 void reobtainReader()
218 {
219 m_reader = nullptr;
220 m_reader = m_handle->obtainReader(&m_client);
221 }
222
223 std::unique_ptr<WebDataConsumerHandle> m_handle;
224 CrossThreadPersistent<CompositeDataConsumerHandle::Updater> m_updater;
225 std::unique_ptr<WaitableEvent> m_updateEvent;
226 };
227
228 class ThreadingRegistrationUpdateTwiceAtOneTimeTest : public DataConsumerHandleT estUtil::ThreadingTestBase {
229 public:
230 using Self = ThreadingRegistrationUpdateTwiceAtOneTimeTest;
231 static PassRefPtr<Self> create() { return adoptRef(new Self); }
232
233 void run()
234 {
235 ThreadHolder holder(this);
236 m_waitableEvent = wrapUnique(new WaitableEvent());
237 m_updateEvent = wrapUnique(new WaitableEvent());
238
239 postTaskToUpdatingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self:: createHandle, wrapPassRefPtr(this)));
240 postTaskToReadingThreadAndWait(BLINK_FROM_HERE, crossThreadBind(&Self::o btainReader, wrapPassRefPtr(this)));
241 }
242
243 private:
244 ThreadingRegistrationUpdateTwiceAtOneTimeTest() = default;
245
246 void createHandle()
247 {
248 m_handle = CompositeDataConsumerHandle::create(DataConsumerHandle::creat e("handle1", m_context), &m_updater);
249 m_waitableEvent->signal();
250 }
251
252 void obtainReader()
253 {
254 m_reader = m_handle->obtainReader(&m_client);
255 postTaskToUpdatingThread(BLINK_FROM_HERE, crossThreadBind(&Self::update, wrapPassRefPtr(this)));
256 // Stalls this thread while updating handles.
257 m_updateEvent->wait();
258 }
259 void update()
260 {
261 m_updater->update(DataConsumerHandle::create("handle2", m_context));
262 m_updater->update(DataConsumerHandle::create("handle3", m_context));
263 m_updateEvent->signal();
264 m_updater.clear();
265 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::resetRea der, wrapPassRefPtr(this)));
266 postTaskToReadingThread(BLINK_FROM_HERE, crossThreadBind(&Self::signalDo ne, wrapPassRefPtr(this)));
267 }
268
269 std::unique_ptr<WebDataConsumerHandle> m_handle;
270 CrossThreadPersistent<CompositeDataConsumerHandle::Updater> m_updater;
271 std::unique_ptr<WaitableEvent> m_updateEvent;
272 };
273
274 TEST(CompositeDataConsumerHandleTest, Read)
275 {
276 char buffer[20];
277 size_t size = 0;
278 DataConsumerHandleTestUtil::NoopClient client;
279 Checkpoint checkpoint;
280
281 std::unique_ptr<MockHandle> handle1 = MockHandle::create();
282 std::unique_ptr<MockHandle> handle2 = MockHandle::create();
283
284 // They will be adopted by |obtainReader|.
285 MockReader* reader1 = MockReader::create().release();
286 MockReader* reader2 = MockReader::create().release();
287
288 InSequence s;
289 EXPECT_CALL(checkpoint, Call(0));
290 EXPECT_CALL(*handle1, obtainReader(&client)).WillOnce(Return(ByMove(WTF::wra pUnique(reader1))));
291 EXPECT_CALL(checkpoint, Call(1));
292 EXPECT_CALL(*reader1, read(buffer, sizeof(buffer), kNone, &size)).WillOnce(R eturn(kOk));
293 EXPECT_CALL(checkpoint, Call(2));
294 EXPECT_CALL(*handle2, obtainReader(&client)).WillOnce(Return(ByMove(WTF::wra pUnique(reader2))));
295 EXPECT_CALL(checkpoint, Call(3));
296 EXPECT_CALL(*reader2, read(buffer, sizeof(buffer), kNone, &size)).WillOnce(R eturn(kOk));
297 EXPECT_CALL(checkpoint, Call(4));
298
299 CompositeDataConsumerHandle::Updater* updater = nullptr;
300 std::unique_ptr<WebDataConsumerHandle> handle = CompositeDataConsumerHandle: :create(std::move(handle1), &updater);
301 checkpoint.Call(0);
302 std::unique_ptr<WebDataConsumerHandle::Reader> reader = handle->obtainReader (&client);
303 checkpoint.Call(1);
304 EXPECT_EQ(kOk, reader->read(buffer, sizeof(buffer), kNone, &size));
305 checkpoint.Call(2);
306 updater->update(std::move(handle2));
307 checkpoint.Call(3);
308 EXPECT_EQ(kOk, reader->read(buffer, sizeof(buffer), kNone, &size));
309 checkpoint.Call(4);
310 }
311
312 TEST(CompositeDataConsumerHandleTest, TwoPhaseRead)
313 {
314 const void* p = nullptr;
315 size_t size = 0;
316 Checkpoint checkpoint;
317
318 std::unique_ptr<MockHandle> handle1 = MockHandle::create();
319 std::unique_ptr<MockHandle> handle2 = MockHandle::create();
320
321 // They are adopted by |obtainReader|.
322 MockReader* reader1 = MockReader::create().release();
323 MockReader* reader2 = MockReader::create().release();
324
325 InSequence s;
326 EXPECT_CALL(checkpoint, Call(0));
327 EXPECT_CALL(*handle1, obtainReader(nullptr)).WillOnce(Return(ByMove(WTF::wra pUnique(reader1))));
328 EXPECT_CALL(checkpoint, Call(1));
329 EXPECT_CALL(*reader1, beginRead(&p, kNone, &size)).WillOnce(Return(kOk));
330 EXPECT_CALL(checkpoint, Call(2));
331 EXPECT_CALL(*reader1, endRead(0)).WillOnce(Return(kOk));
332 EXPECT_CALL(checkpoint, Call(3));
333 EXPECT_CALL(*handle2, obtainReader(nullptr)).WillOnce(Return(ByMove(WTF::wra pUnique(reader2))));
334 EXPECT_CALL(checkpoint, Call(4));
335 EXPECT_CALL(*reader2, beginRead(&p, kNone, &size)).WillOnce(Return(kOk));
336 EXPECT_CALL(checkpoint, Call(5));
337 EXPECT_CALL(*reader2, endRead(0)).WillOnce(Return(kOk));
338 EXPECT_CALL(checkpoint, Call(6));
339
340 CompositeDataConsumerHandle::Updater* updater = nullptr;
341 std::unique_ptr<WebDataConsumerHandle> handle = CompositeDataConsumerHandle: :create(std::move(handle1), &updater);
342 checkpoint.Call(0);
343 std::unique_ptr<WebDataConsumerHandle::Reader> reader = handle->obtainReader (nullptr);
344 checkpoint.Call(1);
345 EXPECT_EQ(kOk, reader->beginRead(&p, kNone, &size));
346 checkpoint.Call(2);
347 EXPECT_EQ(kOk, reader->endRead(0));
348 checkpoint.Call(3);
349 updater->update(std::move(handle2));
350 checkpoint.Call(4);
351 EXPECT_EQ(kOk, reader->beginRead(&p, kNone, &size));
352 checkpoint.Call(5);
353 EXPECT_EQ(kOk, reader->endRead(0));
354 checkpoint.Call(6);
355 }
356
357 TEST(CompositeDataConsumerHandleTest, HangingTwoPhaseRead)
358 {
359 const void* p = nullptr;
360 size_t size = 0;
361 Checkpoint checkpoint;
362
363 std::unique_ptr<MockHandle> handle1 = MockHandle::create();
364 std::unique_ptr<MockHandle> handle2 = MockHandle::create();
365 std::unique_ptr<MockHandle> handle3 = MockHandle::create();
366
367 // They are adopted by |obtainReader|.
368 MockReader* reader1 = MockReader::create().release();
369 MockReader* reader2 = MockReader::create().release();
370 MockReader* reader3 = MockReader::create().release();
371
372 InSequence s;
373 EXPECT_CALL(checkpoint, Call(0));
374 EXPECT_CALL(*handle1, obtainReader(nullptr)).WillOnce(Return(ByMove(WTF::wra pUnique(reader1))));
375 EXPECT_CALL(checkpoint, Call(1));
376 EXPECT_CALL(*reader1, beginRead(&p, kNone, &size)).WillOnce(Return(kOk));
377 EXPECT_CALL(checkpoint, Call(2));
378 EXPECT_CALL(checkpoint, Call(3));
379 EXPECT_CALL(*reader1, endRead(0)).WillOnce(Return(kOk));
380 EXPECT_CALL(*handle2, obtainReader(nullptr)).WillOnce(Return(ByMove(WTF::wra pUnique(reader2))));
381 EXPECT_CALL(checkpoint, Call(4));
382 EXPECT_CALL(*reader2, beginRead(&p, kNone, &size)).WillOnce(Return(kShouldWa it));
383 EXPECT_CALL(checkpoint, Call(5));
384 EXPECT_CALL(*handle3, obtainReader(nullptr)).WillOnce(Return(ByMove(WTF::wra pUnique(reader3))));
385 EXPECT_CALL(checkpoint, Call(6));
386 EXPECT_CALL(*reader3, beginRead(&p, kNone, &size)).WillOnce(Return(kOk));
387 EXPECT_CALL(checkpoint, Call(7));
388 EXPECT_CALL(*reader3, endRead(0)).WillOnce(Return(kOk));
389 EXPECT_CALL(checkpoint, Call(8));
390
391 CompositeDataConsumerHandle::Updater* updater = nullptr;
392 std::unique_ptr<WebDataConsumerHandle> handle = CompositeDataConsumerHandle: :create(std::move(handle1), &updater);
393 checkpoint.Call(0);
394 std::unique_ptr<WebDataConsumerHandle::Reader> reader = handle->obtainReader (nullptr);
395 checkpoint.Call(1);
396 EXPECT_EQ(kOk, reader->beginRead(&p, kNone, &size));
397 checkpoint.Call(2);
398 updater->update(std::move(handle2));
399 checkpoint.Call(3);
400 EXPECT_EQ(kOk, reader->endRead(0));
401 checkpoint.Call(4);
402 EXPECT_EQ(kShouldWait, reader->beginRead(&p, kNone, &size));
403 checkpoint.Call(5);
404 updater->update(std::move(handle3));
405 checkpoint.Call(6);
406 EXPECT_EQ(kOk, reader->beginRead(&p, kNone, &size));
407 checkpoint.Call(7);
408 EXPECT_EQ(kOk, reader->endRead(0));
409 checkpoint.Call(8);
410 }
411
412 TEST(CompositeDataConsumerHandleTest, RegisterClientOnDifferentThreads)
413 {
414 RefPtr<ThreadingRegistrationTest> test = ThreadingRegistrationTest::create() ;
415 test->run();
416
417 EXPECT_EQ(
418 "A reader is attached to handle1 on the reading thread.\n"
419 "A reader is detached from handle1 on the reading thread.\n"
420 "A reader is attached to handle2 on the reading thread.\n"
421 "A reader is detached from handle2 on the reading thread.\n",
422 test->result());
423 }
424
425 TEST(CompositeDataConsumerHandleTest, DeleteHandleWhileUpdating)
426 {
427 RefPtr<ThreadingRegistrationDeleteHandleTest> test = ThreadingRegistrationDe leteHandleTest::create();
428 test->run();
429
430 EXPECT_EQ(
431 "A reader is attached to handle1 on the reading thread.\n"
432 "A reader is detached from handle1 on the reading thread.\n"
433 "A reader is attached to handle2 on the reading thread.\n"
434 "A reader is detached from handle2 on the reading thread.\n",
435 test->result());
436 }
437
438 TEST(CompositeDataConsumerHandleTest, DeleteReaderWhileUpdating)
439 {
440 RefPtr<ThreadingRegistrationDeleteReaderTest> test = ThreadingRegistrationDe leteReaderTest::create();
441 test->run();
442
443 EXPECT_EQ(
444 "A reader is attached to handle1 on the reading thread.\n"
445 "A reader is detached from handle1 on the reading thread.\n",
446 test->result());
447 }
448
449 TEST(CompositeDataConsumerHandleTest, UpdateReaderWhileUpdating)
450 {
451 RefPtr<ThreadingUpdatingReaderWhileUpdatingTest> test = ThreadingUpdatingRea derWhileUpdatingTest::create();
452 test->run();
453
454 EXPECT_EQ(
455 "A reader is attached to handle1 on the reading thread.\n"
456 "A reader is detached from handle1 on the reading thread.\n"
457 "A reader is attached to handle2 on the reading thread.\n"
458 "A reader is detached from handle2 on the reading thread.\n",
459 test->result());
460 }
461
462 TEST(CompositeDataConsumerHandleTest, UpdateTwiceAtOnce)
463 {
464 RefPtr<ThreadingRegistrationUpdateTwiceAtOneTimeTest> test = ThreadingRegist rationUpdateTwiceAtOneTimeTest::create();
465 test->run();
466
467 EXPECT_EQ(
468 "A reader is attached to handle1 on the reading thread.\n"
469 "A reader is detached from handle1 on the reading thread.\n"
470 "A reader is attached to handle3 on the reading thread.\n"
471 "A reader is detached from handle3 on the reading thread.\n",
472 test->result());
473 }
474
475 TEST(CompositeDataConsumerHandleTest, DoneHandleNotification)
476 {
477 RefPtr<DataConsumerHandleTestUtil::ThreadingHandleNotificationTest> test = D ataConsumerHandleTestUtil::ThreadingHandleNotificationTest::create();
478 CompositeDataConsumerHandle::Updater* updater = nullptr;
479 // Test this function returns.
480 test->run(CompositeDataConsumerHandle::create(createDoneDataConsumerHandle() , &updater));
481 }
482
483 TEST(CompositeDataConsumerHandleTest, DoneHandleNoNotification)
484 {
485 RefPtr<DataConsumerHandleTestUtil::ThreadingHandleNoNotificationTest> test = DataConsumerHandleTestUtil::ThreadingHandleNoNotificationTest::create();
486 CompositeDataConsumerHandle::Updater* updater = nullptr;
487 // Test this function doesn't crash.
488 test->run(CompositeDataConsumerHandle::create(createDoneDataConsumerHandle() , &updater));
489 }
490
491 } // namespace
492
493 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698