15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/worker_pool.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 10ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "base/message_loop/message_loop.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h" 12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/synchronization/waitable_event.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/test/test_timeouts.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_checker_impl.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/platform_test.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef PlatformTest WorkerPoolTest; 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PostTaskAndReplyTester 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe<PostTaskAndReplyTester> { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PostTaskAndReplyTester() : finished_(false), test_event_(false, false) {} 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void RunTest() { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(thread_checker_.CalledOnValidThread()); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkerPool::PostTaskAndReply( 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PostTaskAndReplyTester::OnWorkerThread, this), 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&PostTaskAndReplyTester::OnOriginalThread, this), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_event_.Wait(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnWorkerThread() { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We're not on the original thread. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(thread_checker_.CalledOnValidThread()); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_event_.Signal(); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnOriginalThread() { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(thread_checker_.CalledOnValidThread()); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) finished_ = true; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool finished() const { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return finished_; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<PostTaskAndReplyTester>; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PostTaskAndReplyTester() {} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool finished_; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent test_event_; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The Impl version performs its checks even in release builds. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadCheckerImpl thread_checker_; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerPoolTest, PostTask) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent test_event(false, false); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent long_test_event(false, false); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkerPool::PostTask(FROM_HERE, 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&test_event)), 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) false); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WorkerPool::PostTask(FROM_HERE, 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&WaitableEvent::Signal, 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(&long_test_event)), 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_event.Wait(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) long_test_event.Wait(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) || defined(OS_LINUX) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flaky on Windows and Linux (http://crbug.com/130337) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_PostTaskAndReply DISABLED_PostTaskAndReply 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_PostTaskAndReply PostTaskAndReply 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(WorkerPoolTest, MAYBE_PostTaskAndReply) { 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MessageLoop message_loop; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PostTaskAndReplyTester> tester(new PostTaskAndReplyTester()); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tester->RunTest(); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TimeDelta kMaxDuration = TestTimeouts::tiny_timeout(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks start = TimeTicks::Now(); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!tester->finished() && TimeTicks::Now() - start < kMaxDuration) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_IOS) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Ensure that the other thread has a chance to run even on a single-core 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // device. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_yield_np(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RunLoop().RunUntilIdle(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(tester->finished()); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 113