Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / base / memory / weak_ptr_unittest.cc
1 // Copyright (c) 2012 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/memory/weak_ptr.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/debug/leak_annotations.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/synchronization/waitable_event.h"
14 #include "base/threading/thread.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16
17 namespace base {
18 namespace {
19
20 template <class T>
21 class OffThreadObjectCreator {
22  public:
23   static T* NewObject() {
24     T* result;
25     {
26       Thread creator_thread("creator_thread");
27       creator_thread.Start();
28       creator_thread.message_loop()->PostTask(
29           FROM_HERE,
30           base::Bind(OffThreadObjectCreator::CreateObject, &result));
31     }
32     DCHECK(result);  // We synchronized on thread destruction above.
33     return result;
34   }
35  private:
36   static void CreateObject(T** result) {
37     *result = new T;
38   }
39 };
40
41 struct Base {
42   std::string member;
43 };
44 struct Derived : public Base {};
45
46 struct TargetBase {};
47 struct Target : public TargetBase, public SupportsWeakPtr<Target> {
48   virtual ~Target() {}
49 };
50 struct DerivedTarget : public Target {};
51 struct Arrow {
52   WeakPtr<Target> target;
53 };
54 struct TargetWithFactory : public Target {
55   TargetWithFactory() : factory(this) {}
56   WeakPtrFactory<Target> factory;
57 };
58
59 // Helper class to create and destroy weak pointer copies
60 // and delete objects on a background thread.
61 class BackgroundThread : public Thread {
62  public:
63   BackgroundThread() : Thread("owner_thread") {}
64
65   ~BackgroundThread() override { Stop(); }
66
67   void CreateArrowFromTarget(Arrow** arrow, Target* target) {
68     WaitableEvent completion(true, false);
69     message_loop()->PostTask(
70         FROM_HERE,
71         base::Bind(&BackgroundThread::DoCreateArrowFromTarget,
72                    arrow, target, &completion));
73     completion.Wait();
74   }
75
76   void CreateArrowFromArrow(Arrow** arrow, const Arrow* other) {
77     WaitableEvent completion(true, false);
78     message_loop()->PostTask(
79         FROM_HERE,
80         base::Bind(&BackgroundThread::DoCreateArrowFromArrow,
81                    arrow, other, &completion));
82     completion.Wait();
83   }
84
85   void DeleteTarget(Target* object) {
86     WaitableEvent completion(true, false);
87     message_loop()->PostTask(
88         FROM_HERE,
89         base::Bind(&BackgroundThread::DoDeleteTarget, object, &completion));
90     completion.Wait();
91   }
92
93   void CopyAndAssignArrow(Arrow* object) {
94     WaitableEvent completion(true, false);
95     message_loop()->PostTask(
96         FROM_HERE,
97         base::Bind(&BackgroundThread::DoCopyAndAssignArrow,
98                    object, &completion));
99     completion.Wait();
100   }
101
102   void CopyAndAssignArrowBase(Arrow* object) {
103     WaitableEvent completion(true, false);
104     message_loop()->PostTask(
105         FROM_HERE,
106         base::Bind(&BackgroundThread::DoCopyAndAssignArrowBase,
107                    object, &completion));
108     completion.Wait();
109   }
110
111   void DeleteArrow(Arrow* object) {
112     WaitableEvent completion(true, false);
113     message_loop()->PostTask(
114         FROM_HERE,
115         base::Bind(&BackgroundThread::DoDeleteArrow, object, &completion));
116     completion.Wait();
117   }
118
119   Target* DeRef(const Arrow* arrow) {
120     WaitableEvent completion(true, false);
121     Target* result = NULL;
122     message_loop()->PostTask(
123         FROM_HERE,
124         base::Bind(&BackgroundThread::DoDeRef, arrow, &result, &completion));
125     completion.Wait();
126     return result;
127   }
128
129  protected:
130   static void DoCreateArrowFromArrow(Arrow** arrow,
131                                      const Arrow* other,
132                                      WaitableEvent* completion) {
133     *arrow = new Arrow;
134     **arrow = *other;
135     completion->Signal();
136   }
137
138   static void DoCreateArrowFromTarget(Arrow** arrow,
139                                       Target* target,
140                                       WaitableEvent* completion) {
141     *arrow = new Arrow;
142     (*arrow)->target = target->AsWeakPtr();
143     completion->Signal();
144   }
145
146   static void DoDeRef(const Arrow* arrow,
147                       Target** result,
148                       WaitableEvent* completion) {
149     *result = arrow->target.get();
150     completion->Signal();
151   }
152
153   static void DoDeleteTarget(Target* object, WaitableEvent* completion) {
154     delete object;
155     completion->Signal();
156   }
157
158   static void DoCopyAndAssignArrow(Arrow* object, WaitableEvent* completion) {
159     // Copy constructor.
160     Arrow a = *object;
161     // Assignment operator.
162     *object = a;
163     completion->Signal();
164   }
165
166   static void DoCopyAndAssignArrowBase(
167       Arrow* object,
168       WaitableEvent* completion) {
169     // Copy constructor.
170     WeakPtr<TargetBase> b = object->target;
171     // Assignment operator.
172     WeakPtr<TargetBase> c;
173     c = object->target;
174     completion->Signal();
175   }
176
177   static void DoDeleteArrow(Arrow* object, WaitableEvent* completion) {
178     delete object;
179     completion->Signal();
180   }
181 };
182
183 }  // namespace
184
185 TEST(WeakPtrFactoryTest, Basic) {
186   int data;
187   WeakPtrFactory<int> factory(&data);
188   WeakPtr<int> ptr = factory.GetWeakPtr();
189   EXPECT_EQ(&data, ptr.get());
190 }
191
192 TEST(WeakPtrFactoryTest, Comparison) {
193   int data;
194   WeakPtrFactory<int> factory(&data);
195   WeakPtr<int> ptr = factory.GetWeakPtr();
196   WeakPtr<int> ptr2 = ptr;
197   EXPECT_EQ(ptr.get(), ptr2.get());
198 }
199
200 TEST(WeakPtrFactoryTest, OutOfScope) {
201   WeakPtr<int> ptr;
202   EXPECT_EQ(NULL, ptr.get());
203   {
204     int data;
205     WeakPtrFactory<int> factory(&data);
206     ptr = factory.GetWeakPtr();
207   }
208   EXPECT_EQ(NULL, ptr.get());
209 }
210
211 TEST(WeakPtrFactoryTest, Multiple) {
212   WeakPtr<int> a, b;
213   {
214     int data;
215     WeakPtrFactory<int> factory(&data);
216     a = factory.GetWeakPtr();
217     b = factory.GetWeakPtr();
218     EXPECT_EQ(&data, a.get());
219     EXPECT_EQ(&data, b.get());
220   }
221   EXPECT_EQ(NULL, a.get());
222   EXPECT_EQ(NULL, b.get());
223 }
224
225 TEST(WeakPtrFactoryTest, MultipleStaged) {
226   WeakPtr<int> a;
227   {
228     int data;
229     WeakPtrFactory<int> factory(&data);
230     a = factory.GetWeakPtr();
231     {
232       WeakPtr<int> b = factory.GetWeakPtr();
233     }
234     EXPECT_TRUE(NULL != a.get());
235   }
236   EXPECT_EQ(NULL, a.get());
237 }
238
239 TEST(WeakPtrFactoryTest, Dereference) {
240   Base data;
241   data.member = "123456";
242   WeakPtrFactory<Base> factory(&data);
243   WeakPtr<Base> ptr = factory.GetWeakPtr();
244   EXPECT_EQ(&data, ptr.get());
245   EXPECT_EQ(data.member, (*ptr).member);
246   EXPECT_EQ(data.member, ptr->member);
247 }
248
249 TEST(WeakPtrFactoryTest, UpCast) {
250   Derived data;
251   WeakPtrFactory<Derived> factory(&data);
252   WeakPtr<Base> ptr = factory.GetWeakPtr();
253   ptr = factory.GetWeakPtr();
254   EXPECT_EQ(ptr.get(), &data);
255 }
256
257 TEST(WeakPtrTest, SupportsWeakPtr) {
258   Target target;
259   WeakPtr<Target> ptr = target.AsWeakPtr();
260   EXPECT_EQ(&target, ptr.get());
261 }
262
263 TEST(WeakPtrTest, DerivedTarget) {
264   DerivedTarget target;
265   WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target);
266   EXPECT_EQ(&target, ptr.get());
267 }
268
269 TEST(WeakPtrTest, InvalidateWeakPtrs) {
270   int data;
271   WeakPtrFactory<int> factory(&data);
272   WeakPtr<int> ptr = factory.GetWeakPtr();
273   EXPECT_EQ(&data, ptr.get());
274   EXPECT_TRUE(factory.HasWeakPtrs());
275   factory.InvalidateWeakPtrs();
276   EXPECT_EQ(NULL, ptr.get());
277   EXPECT_FALSE(factory.HasWeakPtrs());
278
279   // Test that the factory can create new weak pointers after a
280   // InvalidateWeakPtrs call, and they remain valid until the next
281   // InvalidateWeakPtrs call.
282   WeakPtr<int> ptr2 = factory.GetWeakPtr();
283   EXPECT_EQ(&data, ptr2.get());
284   EXPECT_TRUE(factory.HasWeakPtrs());
285   factory.InvalidateWeakPtrs();
286   EXPECT_EQ(NULL, ptr2.get());
287   EXPECT_FALSE(factory.HasWeakPtrs());
288 }
289
290 TEST(WeakPtrTest, HasWeakPtrs) {
291   int data;
292   WeakPtrFactory<int> factory(&data);
293   {
294     WeakPtr<int> ptr = factory.GetWeakPtr();
295     EXPECT_TRUE(factory.HasWeakPtrs());
296   }
297   EXPECT_FALSE(factory.HasWeakPtrs());
298 }
299
300 TEST(WeakPtrTest, ObjectAndWeakPtrOnDifferentThreads) {
301   // Test that it is OK to create an object that supports WeakPtr on one thread,
302   // but use it on another.  This tests that we do not trip runtime checks that
303   // ensure that a WeakPtr is not used by multiple threads.
304   scoped_ptr<Target> target(OffThreadObjectCreator<Target>::NewObject());
305   WeakPtr<Target> weak_ptr = target->AsWeakPtr();
306   EXPECT_EQ(target.get(), weak_ptr.get());
307 }
308
309 TEST(WeakPtrTest, WeakPtrInitiateAndUseOnDifferentThreads) {
310   // Test that it is OK to create an object that has a WeakPtr member on one
311   // thread, but use it on another.  This tests that we do not trip runtime
312   // checks that ensure that a WeakPtr is not used by multiple threads.
313   scoped_ptr<Arrow> arrow(OffThreadObjectCreator<Arrow>::NewObject());
314   Target target;
315   arrow->target = target.AsWeakPtr();
316   EXPECT_EQ(&target, arrow->target.get());
317 }
318
319 TEST(WeakPtrTest, MoveOwnershipImplicitly) {
320   // Move object ownership to another thread by releasing all weak pointers
321   // on the original thread first, and then establish WeakPtr on a different
322   // thread.
323   BackgroundThread background;
324   background.Start();
325
326   Target* target = new Target();
327   {
328     WeakPtr<Target> weak_ptr = target->AsWeakPtr();
329     // Main thread deletes the WeakPtr, then the thread ownership of the
330     // object can be implicitly moved.
331   }
332   Arrow* arrow;
333
334   // Background thread creates WeakPtr(and implicitly owns the object).
335   background.CreateArrowFromTarget(&arrow, target);
336   EXPECT_EQ(background.DeRef(arrow), target);
337
338   {
339     // Main thread creates another WeakPtr, but this does not trigger implicitly
340     // thread ownership move.
341     Arrow arrow;
342     arrow.target = target->AsWeakPtr();
343
344     // The new WeakPtr is owned by background thread.
345     EXPECT_EQ(target, background.DeRef(&arrow));
346   }
347
348   // Target can only be deleted on background thread.
349   background.DeleteTarget(target);
350   background.DeleteArrow(arrow);
351 }
352
353 TEST(WeakPtrTest, MoveOwnershipOfUnreferencedObject) {
354   BackgroundThread background;
355   background.Start();
356
357   Arrow* arrow;
358   {
359     Target target;
360     // Background thread creates WeakPtr.
361     background.CreateArrowFromTarget(&arrow, &target);
362
363     // Bind to background thread.
364     EXPECT_EQ(&target, background.DeRef(arrow));
365
366     // Release the only WeakPtr.
367     arrow->target.reset();
368
369     // Now we should be able to create a new reference from this thread.
370     arrow->target = target.AsWeakPtr();
371
372     // Re-bind to main thread.
373     EXPECT_EQ(&target, arrow->target.get());
374
375     // And the main thread can now delete the target.
376   }
377
378   delete arrow;
379 }
380
381 TEST(WeakPtrTest, MoveOwnershipAfterInvalidate) {
382   BackgroundThread background;
383   background.Start();
384
385   Arrow arrow;
386   scoped_ptr<TargetWithFactory> target(new TargetWithFactory);
387
388   // Bind to main thread.
389   arrow.target = target->factory.GetWeakPtr();
390   EXPECT_EQ(target.get(), arrow.target.get());
391
392   target->factory.InvalidateWeakPtrs();
393   EXPECT_EQ(NULL, arrow.target.get());
394
395   arrow.target = target->factory.GetWeakPtr();
396   // Re-bind to background thread.
397   EXPECT_EQ(target.get(), background.DeRef(&arrow));
398
399   // And the background thread can now delete the target.
400   background.DeleteTarget(target.release());
401 }
402
403 TEST(WeakPtrTest, MainThreadRefOutlivesBackgroundThreadRef) {
404   // Originating thread has a WeakPtr that outlives others.
405   // - Main thread creates a WeakPtr
406   // - Background thread creates a WeakPtr copy from the one in main thread
407   // - Destruct the WeakPtr on background thread
408   // - Destruct the WeakPtr on main thread
409   BackgroundThread background;
410   background.Start();
411
412   Target target;
413   Arrow arrow;
414   arrow.target = target.AsWeakPtr();
415
416   Arrow* arrow_copy;
417   background.CreateArrowFromArrow(&arrow_copy, &arrow);
418   EXPECT_EQ(arrow_copy->target.get(), &target);
419   background.DeleteArrow(arrow_copy);
420 }
421
422 TEST(WeakPtrTest, BackgroundThreadRefOutlivesMainThreadRef) {
423   // Originating thread drops all references before another thread.
424   // - Main thread creates a WeakPtr and passes copy to background thread
425   // - Destruct the pointer on main thread
426   // - Destruct the pointer on background thread
427   BackgroundThread background;
428   background.Start();
429
430   Target target;
431   Arrow* arrow_copy;
432   {
433     Arrow arrow;
434     arrow.target = target.AsWeakPtr();
435     background.CreateArrowFromArrow(&arrow_copy, &arrow);
436   }
437   EXPECT_EQ(arrow_copy->target.get(), &target);
438   background.DeleteArrow(arrow_copy);
439 }
440
441 TEST(WeakPtrTest, OwnerThreadDeletesObject) {
442   // Originating thread invalidates WeakPtrs while its held by other thread.
443   // - Main thread creates WeakPtr and passes Copy to background thread
444   // - Object gets destroyed on main thread
445   //   (invalidates WeakPtr on background thread)
446   // - WeakPtr gets destroyed on Thread B
447   BackgroundThread background;
448   background.Start();
449   Arrow* arrow_copy;
450   {
451     Target target;
452     Arrow arrow;
453     arrow.target = target.AsWeakPtr();
454     background.CreateArrowFromArrow(&arrow_copy, &arrow);
455   }
456   EXPECT_EQ(NULL, arrow_copy->target.get());
457   background.DeleteArrow(arrow_copy);
458 }
459
460 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtr) {
461   // Main thread creates a Target object.
462   Target target;
463   // Main thread creates an arrow referencing the Target.
464   Arrow *arrow = new Arrow();
465   arrow->target = target.AsWeakPtr();
466
467   // Background can copy and assign arrow (as well as the WeakPtr inside).
468   BackgroundThread background;
469   background.Start();
470   background.CopyAndAssignArrow(arrow);
471   background.DeleteArrow(arrow);
472 }
473
474 TEST(WeakPtrTest, NonOwnerThreadCanCopyAndAssignWeakPtrBase) {
475   // Main thread creates a Target object.
476   Target target;
477   // Main thread creates an arrow referencing the Target.
478   Arrow *arrow = new Arrow();
479   arrow->target = target.AsWeakPtr();
480
481   // Background can copy and assign arrow's WeakPtr to a base class WeakPtr.
482   BackgroundThread background;
483   background.Start();
484   background.CopyAndAssignArrowBase(arrow);
485   background.DeleteArrow(arrow);
486 }
487
488 TEST(WeakPtrTest, NonOwnerThreadCanDeleteWeakPtr) {
489   // Main thread creates a Target object.
490   Target target;
491   // Main thread creates an arrow referencing the Target.
492   Arrow* arrow = new Arrow();
493   arrow->target = target.AsWeakPtr();
494
495   // Background can delete arrow (as well as the WeakPtr inside).
496   BackgroundThread background;
497   background.Start();
498   background.DeleteArrow(arrow);
499 }
500
501 #if (!defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)) && GTEST_HAS_DEATH_TEST
502
503 TEST(WeakPtrDeathTest, WeakPtrCopyDoesNotChangeThreadBinding) {
504   // The default style "fast" does not support multi-threaded tests
505   // (introduces deadlock on Linux).
506   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
507
508   BackgroundThread background;
509   background.Start();
510
511   // Main thread creates a Target object.
512   Target target;
513   // Main thread creates an arrow referencing the Target.
514   Arrow arrow;
515   arrow.target = target.AsWeakPtr();
516
517   // Background copies the WeakPtr.
518   Arrow* arrow_copy;
519   background.CreateArrowFromArrow(&arrow_copy, &arrow);
520
521   // The copy is still bound to main thread so I can deref.
522   EXPECT_EQ(arrow.target.get(), arrow_copy->target.get());
523
524   // Although background thread created the copy, it can not deref the copied
525   // WeakPtr.
526   ASSERT_DEATH(background.DeRef(arrow_copy), "");
527
528   background.DeleteArrow(arrow_copy);
529 }
530
531 TEST(WeakPtrDeathTest, NonOwnerThreadDereferencesWeakPtrAfterReference) {
532   // The default style "fast" does not support multi-threaded tests
533   // (introduces deadlock on Linux).
534   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
535
536   // Main thread creates a Target object.
537   Target target;
538
539   // Main thread creates an arrow referencing the Target (so target's
540   // thread ownership can not be implicitly moved).
541   Arrow arrow;
542   arrow.target = target.AsWeakPtr();
543   arrow.target.get();
544
545   // Background thread tries to deref target, which violates thread ownership.
546   BackgroundThread background;
547   background.Start();
548   ASSERT_DEATH(background.DeRef(&arrow), "");
549 }
550
551 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesWeakPtrAfterReference) {
552   // The default style "fast" does not support multi-threaded tests
553   // (introduces deadlock on Linux).
554   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
555
556   scoped_ptr<Target> target(new Target());
557
558   // Main thread creates an arrow referencing the Target.
559   Arrow arrow;
560   arrow.target = target->AsWeakPtr();
561
562   // Background thread tries to deref target, binding it to the thread.
563   BackgroundThread background;
564   background.Start();
565   background.DeRef(&arrow);
566
567   // Main thread deletes Target, violating thread binding.
568   ASSERT_DEATH(target.reset(), "");
569
570   // |target.reset()| died so |target| still holds the object, so we
571   // must pass it to the background thread to teardown.
572   background.DeleteTarget(target.release());
573 }
574
575 TEST(WeakPtrDeathTest, NonOwnerThreadDeletesObjectAfterReference) {
576   // The default style "fast" does not support multi-threaded tests
577   // (introduces deadlock on Linux).
578   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
579
580   scoped_ptr<Target> target(new Target());
581
582   // Main thread creates an arrow referencing the Target, and references it, so
583   // that it becomes bound to the thread.
584   Arrow arrow;
585   arrow.target = target->AsWeakPtr();
586   arrow.target.get();
587
588   // Background thread tries to delete target, volating thread binding.
589   BackgroundThread background;
590   background.Start();
591   ASSERT_DEATH(background.DeleteTarget(target.release()), "");
592 }
593
594 TEST(WeakPtrDeathTest, NonOwnerThreadReferencesObjectAfterDeletion) {
595   // The default style "fast" does not support multi-threaded tests
596   // (introduces deadlock on Linux).
597   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
598
599   scoped_ptr<Target> target(new Target());
600
601   // Main thread creates an arrow referencing the Target.
602   Arrow arrow;
603   arrow.target = target->AsWeakPtr();
604
605   // Background thread tries to delete target, binding the object to the thread.
606   BackgroundThread background;
607   background.Start();
608   background.DeleteTarget(target.release());
609
610   // Main thread attempts to dereference the target, violating thread binding.
611   ASSERT_DEATH(arrow.target.get(), "");
612 }
613
614 #endif
615
616 }  // namespace base