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

Side by Side Diff: Source/platform/heap/HeapTest.cpp

Issue 415083002: [oilpan]: fix deadlock when leaving a safepoint and sweeping. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: review feedback Created 6 years, 5 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
« no previous file with comments | « Source/modules/webdatabase/DatabaseBackendBase.cpp ('k') | Source/platform/heap/ThreadState.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 /* 1 /*
2 * Copyright (C) 2013 Google Inc. All rights reserved. 2 * Copyright (C) 2013 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 4859 matching lines...) Expand 10 before | Expand all | Expand 10 after
4870 4870
4871 // Regression test for out of bounds call through vtable. 4871 // Regression test for out of bounds call through vtable.
4872 // Passes if it doesn't crash. 4872 // Passes if it doesn't crash.
4873 TEST(HeapTest, GarbageCollectionDuringMixinConstruction) 4873 TEST(HeapTest, GarbageCollectionDuringMixinConstruction)
4874 { 4874 {
4875 ClassWithGarbageCollectingMixinConstructor* a = 4875 ClassWithGarbageCollectingMixinConstructor* a =
4876 new ClassWithGarbageCollectingMixinConstructor(); 4876 new ClassWithGarbageCollectingMixinConstructor();
4877 a->verify(); 4877 a->verify();
4878 } 4878 }
4879 4879
4880 static RecursiveMutex& recursiveMutex()
4881 {
4882 AtomicallyInitializedStatic(RecursiveMutex&, recursiveMutex = *new Recursive Mutex);
4883 return recursiveMutex;
4884 }
4885
4886 class DestructorLockingObject : public GarbageCollectedFinalized<DestructorLocki ngObject> {
4887 public:
4888 static DestructorLockingObject* create()
4889 {
4890 return new DestructorLockingObject();
4891 }
4892
4893 virtual ~DestructorLockingObject()
4894 {
4895 SafePointAwareMutexLocker lock(recursiveMutex());
4896 ++s_destructorCalls;
4897 }
4898
4899 static int s_destructorCalls;
4900 void trace(Visitor* visitor) { }
4901
4902 private:
4903 DestructorLockingObject() { }
4904 };
4905
4906 int DestructorLockingObject::s_destructorCalls = 0;
4907
4908 class RecursiveLockingTester {
4909 public:
4910 static void test()
4911 {
4912 DestructorLockingObject::s_destructorCalls = 0;
4913
4914 MutexLocker locker(mainThreadMutex());
4915 createThread(&workerThreadMain, 0, "Worker Thread");
4916
4917 // Park the main thread until the worker thread has initialized.
4918 parkMainThread();
4919
4920 {
4921 SafePointAwareMutexLocker recursiveLocker(recursiveMutex());
4922
4923 // Let the worker try to acquire the above mutex. It won't get it
4924 // until the main thread has done its GC.
4925 wakeWorkerThread();
4926
4927 Heap::collectGarbage(ThreadState::NoHeapPointersOnStack);
4928
4929 // The worker thread should not have swept yet since it is waiting
4930 // to get the global mutex.
4931 EXPECT_EQ(0, DestructorLockingObject::s_destructorCalls);
4932 }
4933 // At this point the main thread releases the global lock and the worker
4934 // can acquire it and do its sweep of its heaps. Just wait for the worke r
4935 // to complete its sweep and check the result.
4936 parkMainThread();
4937 EXPECT_EQ(1, DestructorLockingObject::s_destructorCalls);
4938 }
4939
4940 private:
4941 static void workerThreadMain(void* data)
4942 {
4943 MutexLocker locker(workerThreadMutex());
4944 ThreadState::attach();
4945
4946 DestructorLockingObject* dlo = DestructorLockingObject::create();
4947 ASSERT_UNUSED(dlo, dlo);
4948
4949 // Wake up the main thread which is waiting for the worker to do its
4950 // allocation.
4951 wakeMainThread();
4952
4953 // Wait for the main thread to get the global lock to ensure it has
4954 // it before the worker tries to acquire it. We want the worker to
4955 // block in the SafePointAwareMutexLocker until the main thread
4956 // has done a GC. The GC will not mark the "dlo" object since the worker
4957 // is entering the safepoint with NoHeapPointersOnStack. When the worker
4958 // subsequently gets the global lock and leaves the safepoint it will
4959 // sweep its heap and finalize "dlo". The destructor of "dlo" will try
4960 // to acquire the same global lock that the thread just got and deadlock
4961 // unless the global lock is recursive.
4962 parkWorkerThread();
4963 SafePointAwareMutexLocker recursiveLocker(recursiveMutex(), ThreadState: :NoHeapPointersOnStack);
4964
4965 // We won't get here unless the lock is recursive since the sweep done
4966 // in the constructor of SafePointAwareMutexLocker after
4967 // getting the lock will not complete given the "dlo" destructor is
4968 // waiting to get the same lock.
4969 // Tell the main thread the worker has done its sweep.
4970 wakeMainThread();
4971
4972 ThreadState::detach();
4973 }
4974
4975 static volatile IntWrapper* s_workerObjectPointer;
4976 };
4977
4978 TEST(HeapTest, RecursiveMutex)
4979 {
4980 RecursiveLockingTester::test();
4981 }
4982
4880 } // WebCore namespace 4983 } // WebCore namespace
OLDNEW
« no previous file with comments | « Source/modules/webdatabase/DatabaseBackendBase.cpp ('k') | Source/platform/heap/ThreadState.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698