From a8377f4246805d8181f6f60cd43276ee23a40c21 Mon Sep 17 00:00:00 2001 From: Dave Townsend Date: Fri, 25 Jul 2008 10:21:04 -0400 Subject: [PATCH] Backout of bug 443874: Need a hook for thread creation and destruction in thread pool Removes the following changesets: 01e24ad20f35 ebf77231b06e f4b859edddd2 22201dfdb1f3 f8762f56712f 2c6f51bf3bed c8ac37904c16 --- xpcom/tests/Makefile.in | 5 - xpcom/tests/TestThreadPoolListener.cpp | 248 ------------------------- xpcom/threads/nsIThreadPool.idl | 35 +--- xpcom/threads/nsThreadPool.cpp | 41 +--- xpcom/threads/nsThreadPool.h | 2 - 5 files changed, 2 insertions(+), 329 deletions(-) delete mode 100644 xpcom/tests/TestThreadPoolListener.cpp diff --git a/xpcom/tests/Makefile.in b/xpcom/tests/Makefile.in index 1594d23f7ce0..8ea216a2b048 100644 --- a/xpcom/tests/Makefile.in +++ b/xpcom/tests/Makefile.in @@ -79,7 +79,6 @@ CPPSRCS = \ TestPipe.cpp \ TestRegistrationOrder.cpp \ TestProxies.cpp \ - TestThreadPoolListener.cpp \ TestTimers.cpp \ $(NULL) @@ -111,9 +110,6 @@ endif SIMPLE_PROGRAMS = $(CPPSRCS:.cpp=$(BIN_SUFFIX)) -# Make sure we have symbols in case we need to debug these. -MOZ_DEBUG_SYMBOLS = 1 - include $(topsrcdir)/config/config.mk ifndef MOZILLA_INTERNAL_API @@ -145,7 +141,6 @@ CPP_UNIT_TESTS = \ TestPipe \ TestServMgr \ TestTextFormatter \ - TestThreadPoolListener \ TestTimers \ $(NULL) diff --git a/xpcom/tests/TestThreadPoolListener.cpp b/xpcom/tests/TestThreadPoolListener.cpp deleted file mode 100644 index 3bbe86ec01f8..000000000000 --- a/xpcom/tests/TestThreadPoolListener.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Thread Pool Listener Test Code. - * - * The Initial Developer of the Original Code is - * Ben Turner . - * Portions created by the Initial Developer are Copyright (C) 2008 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "TestHarness.h" - -#include "nsIThread.h" -#include "nsIThreadPool.h" - -#include "nsAutoLock.h" -#include "nsThreadUtils.h" -#include "nsXPCOMCIDInternal.h" -#include "pratom.h" -#include "prinrval.h" -#include "prmon.h" -#include "prthread.h" - -#define NUMBER_OF_THREADS 4 - -// One hour... because test boxes can be slow! -#define IDLE_THREAD_TIMEOUT 3600000 - -static nsIThread** gCreatedThreadList = nsnull; -static nsIThread** gShutDownThreadList = nsnull; - -static PRMonitor* gMonitor = nsnull; - -static PRBool gAllRunnablesPosted = PR_FALSE; -static PRBool gAllThreadsCreated = PR_FALSE; -static PRBool gAllThreadsShutDown = PR_FALSE; - -#ifdef DEBUG -#define TEST_ASSERTION(_test, _msg) \ - NS_ASSERTION(_test, _msg); -#else -#define TEST_ASSERTION(_test, _msg) \ - PR_BEGIN_MACRO \ - if (!(_test)) { \ - NS_DebugBreak(NS_DEBUG_ABORT, _msg, #_test, __FILE__, __LINE__); \ - } \ - PR_END_MACRO -#endif - -class Listener : public nsIThreadPoolListener -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSITHREADPOOLLISTENER -}; - -NS_IMPL_THREADSAFE_ISUPPORTS1(Listener, nsIThreadPoolListener) - -NS_IMETHODIMP -Listener::OnThreadCreated() -{ - nsCOMPtr current(do_GetCurrentThread()); - TEST_ASSERTION(current, "Couldn't get current thread!"); - - nsAutoMonitor mon(gMonitor); - - while (!gAllRunnablesPosted) { - mon.Wait(); - } - - for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) { - nsIThread* thread = gCreatedThreadList[i]; - TEST_ASSERTION(thread != current, "Saw the same thread twice!"); - - if (!thread) { - gCreatedThreadList[i] = current; - if (i == (NUMBER_OF_THREADS - 1)) { - gAllThreadsCreated = PR_TRUE; - mon.NotifyAll(); - } - return NS_OK; - } - } - - TEST_ASSERTION(PR_FALSE, "Too many threads!"); - return NS_ERROR_FAILURE; -} - -NS_IMETHODIMP -Listener::OnThreadShuttingDown() -{ - nsCOMPtr current(do_GetCurrentThread()); - TEST_ASSERTION(current, "Couldn't get current thread!"); - - nsAutoMonitor mon(gMonitor); - - for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) { - nsIThread* thread = gShutDownThreadList[i]; - TEST_ASSERTION(thread != current, "Saw the same thread twice!"); - - if (!thread) { - gShutDownThreadList[i] = current; - if (i == (NUMBER_OF_THREADS - 1)) { - gAllThreadsShutDown = PR_TRUE; - mon.NotifyAll(); - } - return NS_OK; - } - } - - TEST_ASSERTION(PR_FALSE, "Too many threads!"); - return NS_ERROR_FAILURE; -} - -class AutoCreateAndDestroyMonitor -{ -public: - AutoCreateAndDestroyMonitor(PRMonitor** aMonitorPtr) - : mMonitorPtr(aMonitorPtr) { - *aMonitorPtr = nsAutoMonitor::NewMonitor("TestThreadPoolListener::AutoMon"); - TEST_ASSERTION(*aMonitorPtr, "Out of memory!"); - } - - ~AutoCreateAndDestroyMonitor() { - if (*mMonitorPtr) { - nsAutoMonitor::DestroyMonitor(*mMonitorPtr); - *mMonitorPtr = nsnull; - } - } - -private: - PRMonitor** mMonitorPtr; -}; - -int main(int argc, char** argv) -{ -#ifndef XP_WIN - ScopedXPCOM xpcom("ThreadPoolListener"); - NS_ENSURE_FALSE(xpcom.failed(), 1); - - nsIThread* createdThreadList[NUMBER_OF_THREADS] = { nsnull }; - gCreatedThreadList = createdThreadList; - - nsIThread* shutDownThreadList[NUMBER_OF_THREADS] = { nsnull }; - gShutDownThreadList = shutDownThreadList; - - AutoCreateAndDestroyMonitor newMon(&gMonitor); - NS_ENSURE_TRUE(gMonitor, 1); - - nsresult rv; - nsCOMPtr pool = - do_CreateInstance(NS_THREADPOOL_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, 1); - - rv = pool->SetThreadLimit(NUMBER_OF_THREADS); - NS_ENSURE_SUCCESS(rv, 1); - - rv = pool->SetIdleThreadLimit(NUMBER_OF_THREADS); - NS_ENSURE_SUCCESS(rv, 1); - - rv = pool->SetIdleThreadTimeout(IDLE_THREAD_TIMEOUT); - NS_ENSURE_SUCCESS(rv, 1); - - nsCOMPtr listener = new Listener(); - NS_ENSURE_TRUE(listener, 1); - - rv = pool->SetListener(listener); - NS_ENSURE_SUCCESS(rv, 1); - - { - nsAutoMonitor mon(gMonitor); - - for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) { - nsCOMPtr runnable = new nsRunnable(); - NS_ENSURE_TRUE(runnable, 1); - - rv = pool->Dispatch(runnable, NS_DISPATCH_NORMAL); - NS_ENSURE_SUCCESS(rv, 1); - } - - gAllRunnablesPosted = PR_TRUE; - mon.NotifyAll(); - } - - { - nsAutoMonitor mon(gMonitor); - while (!gAllThreadsCreated) { - mon.Wait(); - } - } - - rv = pool->Shutdown(); - NS_ENSURE_SUCCESS(rv, 1); - - { - nsAutoMonitor mon(gMonitor); - while (!gAllThreadsShutDown) { - mon.Wait(); - } - } - - for (PRUint32 i = 0; i < NUMBER_OF_THREADS; i++) { - nsIThread* created = gCreatedThreadList[i]; - NS_ENSURE_TRUE(created, 1); - - PRBool match = PR_FALSE; - for (PRUint32 j = 0; j < NUMBER_OF_THREADS; j++) { - nsIThread* destroyed = gShutDownThreadList[j]; - NS_ENSURE_TRUE(destroyed, 1); - - if (destroyed == created) { - match = PR_TRUE; - break; - } - } - - NS_ENSURE_TRUE(match, 1); - } -#endif - return 0; -} diff --git a/xpcom/threads/nsIThreadPool.idl b/xpcom/threads/nsIThreadPool.idl index 954e5d1c98d3..e0fc0ce086fa 100644 --- a/xpcom/threads/nsIThreadPool.idl +++ b/xpcom/threads/nsIThreadPool.idl @@ -38,28 +38,12 @@ #include "nsIEventTarget.idl" -[scriptable, uuid(ef194cab-3f86-4b61-b132-e5e96a79e5d1)] -interface nsIThreadPoolListener : nsISupports -{ - /** - * Called when a new thread is created by the thread pool. The notification - * happens on the newly-created thread. - */ - void onThreadCreated(); - - /** - * Called when a thread is about to be destroyed by the thread pool. The - * notification happens on the thread that is about to be destroyed. - */ - void onThreadShuttingDown(); -}; - /** * An interface to a thread pool. A thread pool creates a limited number of * anonymous (unnamed) worker threads. An event dispatched to the thread pool * will be run on the next available worker thread. */ -[scriptable, uuid(61cc5ac4-3f58-49f4-9d1c-8eaa73373de1)] +[scriptable, uuid(394c29f0-225f-487f-86d3-4c259da76cab)] interface nsIThreadPool : nsIEventTarget { /** @@ -86,21 +70,4 @@ interface nsIThreadPool : nsIEventTarget * destroyed. */ attribute unsigned long idleThreadTimeout; - - /** - * An optional listener that will be notified when a thread is created or - * destroyed in the course of the thread pool's operation. - * - * A listener will only receive notifications about threads created after the - * listener is set so it is recommended that the consumer set the listener - * before dispatching the first event. A listener that receives an - * onThreadCreated() notification is guaranteed to always receive the - * corresponding onThreadShuttingDown() notification. - * - * The thread pool takes ownership of the listener and releases it when the - * shutdown() method is called. Threads created after the listener is set will - * also take ownership of the listener so that the listener will be kept alive - * long enough to receive the guaranteed onThreadShuttingDown() notification. - */ - attribute nsIThreadPoolListener listener; }; diff --git a/xpcom/threads/nsThreadPool.cpp b/xpcom/threads/nsThreadPool.cpp index 83d3b760b04c..866931b97231 100644 --- a/xpcom/threads/nsThreadPool.cpp +++ b/xpcom/threads/nsThreadPool.cpp @@ -162,16 +162,6 @@ nsThreadPool::Run() PRBool wasIdle = PR_FALSE; PRIntervalTime idleSince; - nsCOMPtr listener; - { - nsAutoMonitor mon(mEvents.Monitor()); - listener = mListener; - } - - if (listener) { - listener->OnThreadCreated(); - } - do { nsCOMPtr event; { @@ -220,12 +210,8 @@ nsThreadPool::Run() } } while (!exitThread); - if (shutdownThreadOnExit) { - if (listener) { - listener->OnThreadShuttingDown(); - } + if (shutdownThreadOnExit) ShutdownThread(current); - } LOG(("THRD-P(%p) leave\n", this)); return NS_OK; @@ -271,18 +257,12 @@ NS_IMETHODIMP nsThreadPool::Shutdown() { nsCOMArray threads; - nsCOMPtr listener; { nsAutoMonitor mon(mEvents.Monitor()); mShutdown = PR_TRUE; mon.NotifyAll(); threads.AppendObjects(mThreads); - - // Swap in a null listener so that we release the listener at the end of - // this method. The listener will be kept alive as long as the other threads - // that were created when it was set. - mListener.swap(listener); } // It's important that we shutdown the threads while outside the event queue @@ -346,22 +326,3 @@ nsThreadPool::SetIdleThreadTimeout(PRUint32 value) mon.NotifyAll(); // wake up threads so they observe this change return NS_OK; } - -NS_IMETHODIMP -nsThreadPool::GetListener(nsIThreadPoolListener** aListener) -{ - nsAutoMonitor mon(mEvents.Monitor()); - NS_IF_ADDREF(*aListener = mListener); - return NS_OK; -} - -NS_IMETHODIMP -nsThreadPool::SetListener(nsIThreadPoolListener* aListener) -{ - nsCOMPtr swappedListener(aListener); - { - nsAutoMonitor mon(mEvents.Monitor()); - mListener.swap(swappedListener); - } - return NS_OK; -} diff --git a/xpcom/threads/nsThreadPool.h b/xpcom/threads/nsThreadPool.h index 1c1535fb0e21..9366b56cd404 100644 --- a/xpcom/threads/nsThreadPool.h +++ b/xpcom/threads/nsThreadPool.h @@ -44,7 +44,6 @@ #include "nsIRunnable.h" #include "nsEventQueue.h" #include "nsCOMArray.h" -#include "nsCOMPtr.h" class nsThreadPool : public nsIThreadPool, public nsIRunnable { @@ -68,7 +67,6 @@ private: PRUint32 mIdleThreadLimit; PRUint32 mIdleThreadTimeout; PRUint32 mIdleCount; - nsCOMPtr mListener; PRBool mShutdown; };