From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- .../xpcom18a4/xpcom/proxy/tests/proxytests.cpp | 553 +++++++++++++++++++++ 1 file changed, 553 insertions(+) create mode 100644 src/libs/xpcom18a4/xpcom/proxy/tests/proxytests.cpp (limited to 'src/libs/xpcom18a4/xpcom/proxy/tests/proxytests.cpp') diff --git a/src/libs/xpcom18a4/xpcom/proxy/tests/proxytests.cpp b/src/libs/xpcom18a4/xpcom/proxy/tests/proxytests.cpp new file mode 100644 index 00000000..20693463 --- /dev/null +++ b/src/libs/xpcom18a4/xpcom/proxy/tests/proxytests.cpp @@ -0,0 +1,553 @@ +/* -*- 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 mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Pierre Phaneuf + * + * Alternatively, the contents of this file may be used under the terms of + * either of 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 + +#include "nsXPCOM.h" +#include "nsIComponentManager.h" +#include "nsIComponentRegistrar.h" +#include "nsIServiceManager.h" +#include "nsCOMPtr.h" + +#include "nscore.h" +#include "nspr.h" +#include "prmon.h" + +#include "nsITestProxy.h" + +#include "nsIProxyObjectManager.h" +#include "nsIEventQueueService.h" + +static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); + +/***************************************************************************/ +/* nsTestXPCFoo */ +/***************************************************************************/ +class nsTestXPCFoo : public nsITestProxy +{ + NS_DECL_ISUPPORTS + NS_IMETHOD Test(PRInt32 p1, PRInt32 p2, PRInt32* retval); + NS_IMETHOD Test2(); + NS_IMETHOD Test3(nsISupports *p1, nsISupports **p2); + + nsTestXPCFoo(); +}; + +nsTestXPCFoo::nsTestXPCFoo() +{ + NS_ADDREF_THIS(); +} + +NS_IMPL_ISUPPORTS1(nsTestXPCFoo, nsITestProxy) + +NS_IMETHODIMP nsTestXPCFoo::Test(PRInt32 p1, PRInt32 p2, PRInt32* retval) +{ + printf("Thread (%d) Test Called successfully! Party on...\n", p1); + *retval = p1+p2; + return NS_OK; +} + + +NS_IMETHODIMP nsTestXPCFoo::Test2() +{ + printf("The quick brown netscape jumped over the old lazy ie..\n"); + + return NS_OK; +} + +NS_IMETHODIMP nsTestXPCFoo::Test3(nsISupports *p1, nsISupports **p2) +{ + if (p1 != nsnull) + { + nsITestProxy *test; + + p1->QueryInterface(NS_GET_IID(nsITestProxy), (void**)&test); + + test->Test2(); + PRInt32 a; + test->Test( 1, 2, &a); + printf("\n1+2=%d\n",a); + } + + + *p2 = new nsTestXPCFoo(); + return NS_OK; +} + +/***************************************************************************/ +/* nsTestXPCFoo2 */ +/***************************************************************************/ +class nsTestXPCFoo2 : public nsITestProxy +{ + NS_DECL_ISUPPORTS + NS_IMETHOD Test(PRInt32 p1, PRInt32 p2, PRInt32* retval); + NS_IMETHOD Test2(); + NS_IMETHOD Test3(nsISupports *p1, nsISupports **p2); + + nsTestXPCFoo2(); +}; + +nsTestXPCFoo2::nsTestXPCFoo2() +{ + NS_ADDREF_THIS(); +} + +NS_IMPL_THREADSAFE_ISUPPORTS1(nsTestXPCFoo2, nsITestProxy) + +NS_IMETHODIMP nsTestXPCFoo2::Test(PRInt32 p1, PRInt32 p2, PRInt32* retval) +{ +printf("calling back to caller!\n\n"); + + nsIProxyObjectManager* manager; + nsITestProxy * proxyObject; + + nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID, + NS_GET_IID(nsIProxyObjectManager), + (nsISupports **)&manager); + + printf("ProxyObjectManager: %p \n", manager); + + PR_ASSERT(manager); + + manager->GetProxyForObject((nsIEventQueue*)p1, NS_GET_IID(nsITestProxy), this, PROXY_SYNC, (void**)&proxyObject); + proxyObject->Test3(nsnull, nsnull); + + printf("Deleting Proxy Object\n"); + NS_RELEASE(proxyObject); + + return NS_OK; +} + + +NS_IMETHODIMP nsTestXPCFoo2::Test2() +{ + printf("nsTestXPCFoo2::Test2() called\n"); + + return NS_OK; +} + + +NS_IMETHODIMP nsTestXPCFoo2::Test3(nsISupports *p1, nsISupports **p2) +{ + printf("Got called"); + return NS_OK; +} + + + +typedef struct _ArgsStruct +{ + nsIEventQueue* queue; + PRInt32 threadNumber; +}ArgsStruct; + + + +// This will create two objects both descendants of a single IID. +void TestCase_TwoClassesOneInterface(void *arg) +{ + ArgsStruct *argsStruct = (ArgsStruct*) arg; + + + nsIProxyObjectManager* manager; + + nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID, + NS_GET_IID(nsIProxyObjectManager), + (nsISupports **)&manager); + + printf("ProxyObjectManager: %p \n", manager); + + PR_ASSERT(manager); + + nsITestProxy *proxyObject; + nsITestProxy *proxyObject2; + + nsTestXPCFoo* foo = new nsTestXPCFoo(); + nsTestXPCFoo2* foo2 = new nsTestXPCFoo2(); + + PR_ASSERT(foo); + PR_ASSERT(foo2); + + + manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); + + manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo2, PROXY_SYNC, (void**)&proxyObject2); + + + + if (proxyObject && proxyObject2) + { + // release ownership of the real object. + + PRInt32 a; + nsresult rv; + PRInt32 threadNumber = argsStruct->threadNumber; + + printf("Deleting real Object (%d)\n", threadNumber); + NS_RELEASE(foo); + + printf("Deleting real Object 2 (%d)\n", threadNumber); + NS_RELEASE(foo2); + + + printf("Thread (%d) Prior to calling proxyObject->Test.\n", threadNumber); + rv = proxyObject->Test(threadNumber, 0, &a); + printf("Thread (%d) error: %d.\n", threadNumber, rv); + + + printf("Thread (%d) Prior to calling proxyObject->Test2.\n", threadNumber); + rv = proxyObject->Test2(); + printf("Thread (%d) error: %d.\n", threadNumber, rv); + + printf("Thread (%d) Prior to calling proxyObject2->Test2.\n", threadNumber); + rv = proxyObject2->Test2(); + printf("Thread (%d) proxyObject2 error: %d.\n", threadNumber, rv); + + printf("Deleting Proxy Object (%d)\n", threadNumber ); + NS_RELEASE(proxyObject); + + printf("Deleting Proxy Object 2 (%d)\n", threadNumber ); + NS_RELEASE(proxyObject2); + } + + PR_Sleep( PR_MillisecondsToInterval(1000) ); // If your thread goes away, your stack goes away. Only use ASYNC on calls that do not have out parameters +} + + + +void TestCase_NestedLoop(void *arg) +{ + ArgsStruct *argsStruct = (ArgsStruct*) arg; + + + nsIProxyObjectManager* manager; + + nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID, + NS_GET_IID(nsIProxyObjectManager), + (nsISupports **)&manager); + + printf("ProxyObjectManager: %p \n", manager); + + PR_ASSERT(manager); + + nsITestProxy *proxyObject; + nsTestXPCFoo2* foo = new nsTestXPCFoo2(); + + PR_ASSERT(foo); + + + manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); + + if (proxyObject) + { + // release ownership of the real object. + + nsresult rv; + PRInt32 threadNumber = argsStruct->threadNumber; + + printf("Deleting real Object (%d)\n", threadNumber); + NS_RELEASE(foo); + + PRInt32 retval; + + printf("Getting EventQueue...\n"); + + nsIEventQueue* eventQ; + nsCOMPtr eventQService = + do_GetService(kEventQueueServiceCID, &rv); + if (NS_SUCCEEDED(rv)) + { + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); + if (NS_FAILED(rv)) + rv = eventQService->CreateThreadEventQueue(); + if (NS_FAILED(rv)) + return; + else + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); + + printf("Thread (%d) Prior to calling proxyObject->Test.\n", threadNumber); + rv = proxyObject->Test(NS_PTR_TO_INT32(eventQ), 0, &retval); + printf("Thread (%d) proxyObject error: %d.\n", threadNumber, rv); + + printf("Deleting Proxy Object (%d)\n", threadNumber ); + NS_RELEASE(proxyObject); + } + + PR_Sleep( PR_MillisecondsToInterval(1000) ); // If your thread goes away, your stack goes away. Only use ASYNC on calls that do not have out parameters + } +} + + + +void TestCase_2(void *arg) +{ + + ArgsStruct *argsStruct = (ArgsStruct*) arg; + + nsIProxyObjectManager* manager; + + nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID, + NS_GET_IID(nsIProxyObjectManager), + (nsISupports **)&manager); + + PR_ASSERT(manager); + + nsITestProxy *proxyObject; + + manager->GetProxy(argsStruct->queue, + NS_GET_IID(nsITestProxy), // should be CID! + nsnull, + NS_GET_IID(nsITestProxy), + PROXY_SYNC, + (void**)&proxyObject); + + if (proxyObject != nsnull) + { + NS_RELEASE(proxyObject); + } +} + + + +void TestCase_nsISupports(void *arg) +{ + + ArgsStruct *argsStruct = (ArgsStruct*) arg; + + nsIProxyObjectManager* manager; + + nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID, + NS_GET_IID(nsIProxyObjectManager), + (nsISupports **)&manager); + + PR_ASSERT(manager); + + nsITestProxy *proxyObject; + nsTestXPCFoo* foo = new nsTestXPCFoo(); + + PR_ASSERT(foo); + + manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); + + if (proxyObject != nsnull) + { + nsISupports *bISupports = nsnull, *cISupports = nsnull; + + proxyObject->Test3(foo, &bISupports); + proxyObject->Test3(bISupports, &cISupports); + + nsITestProxy *test; + bISupports->QueryInterface(NS_GET_IID(nsITestProxy), (void**)&test); + + test->Test2(); + + NS_RELEASE(foo); + NS_RELEASE(proxyObject); + } +} + + + + + +/***************************************************************************/ +/* ProxyTest */ +/***************************************************************************/ + +static void PR_CALLBACK ProxyTest( void *arg ) +{ + //TestCase_TwoClassesOneInterface(arg); + // TestCase_2(arg); + //TestCase_nsISupports(arg); + TestCase_NestedLoop(arg); + + NS_RELEASE( ((ArgsStruct*) arg)->queue); + free((void*) arg); +} + +nsIEventQueue *gEventQueue = nsnull; + +static void PR_CALLBACK EventLoop( void *arg ) +{ + nsresult rv; + printf("Creating EventQueue...\n"); + + nsIEventQueue* eventQ; + nsCOMPtr eventQService = + do_GetService(kEventQueueServiceCID, &rv); + if (NS_SUCCEEDED(rv)) { + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); + if (NS_FAILED(rv)) + rv = eventQService->CreateThreadEventQueue(); + if (NS_FAILED(rv)) + return; + else + rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ); + } + if (NS_FAILED(rv)) return; + + rv = eventQ->QueryInterface(NS_GET_IID(nsIEventQueue), (void**)&gEventQueue); + if (NS_FAILED(rv)) return; + + + printf("Verifing calling Proxy on eventQ thread.\n"); + + nsIProxyObjectManager* manager; + + nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID, + NS_GET_IID(nsIProxyObjectManager), + (nsISupports **)&manager); + + PR_ASSERT(manager); + + nsITestProxy *proxyObject; + nsTestXPCFoo* foo = new nsTestXPCFoo(); + + PR_ASSERT(foo); + + manager->GetProxyForObject(gEventQueue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject); + + PRInt32 a; + proxyObject->Test(1, 2, &a); + proxyObject->Test2(); + + + NS_RELEASE(proxyObject); + delete foo; + + printf("End of Verification calling Proxy on eventQ thread.\n"); + + + printf("Looping for events.\n"); + + PLEvent* event = nsnull; + + while ( PR_SUCCESS == PR_Sleep( PR_MillisecondsToInterval(1)) ) + { + rv = gEventQueue->GetEvent(&event); + if (NS_FAILED(rv)) + return; + gEventQueue->HandleEvent(event); + } + + gEventQueue->ProcessPendingEvents(); + + printf("Closing down Event Queue.\n"); + delete gEventQueue; + gEventQueue = nsnull; + + printf("End looping for events.\n\n"); +} + +int +main(int argc, char **argv) +{ + int numberOfThreads = 1; + + if (argc > 1) + numberOfThreads = atoi(argv[1]); + + nsCOMPtr servMan; + NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull); + nsCOMPtr registrar = do_QueryInterface(servMan); + NS_ASSERTION(registrar, "Null nsIComponentRegistrar"); + registrar->AutoRegister(nsnull); + + static PRThread** threads = (PRThread**) calloc(sizeof(PRThread*), numberOfThreads); + static PRThread* aEventThread; + + aEventThread = PR_CreateThread(PR_USER_THREAD, + EventLoop, + NULL, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0 ); + + + PR_Sleep(PR_MillisecondsToInterval(1000)); + + NS_ASSERTION(gEventQueue, "no main event queue"); // BAD BAD BAD. EVENT THREAD DID NOT CREATE QUEUE. This may be a timing issue, set the + // sleep about longer, and try again. + + printf("Spawn Threads:\n"); + for (PRInt32 spawn = 0; spawn < numberOfThreads; spawn++) + { + + ArgsStruct *args = (ArgsStruct *) malloc (sizeof(ArgsStruct)); + + args->queue = gEventQueue; + NS_ADDREF(args->queue); + args->threadNumber = spawn; + + threads[spawn] = PR_CreateThread(PR_USER_THREAD, + ProxyTest, + args, + PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, + 0 ); + + printf("\tThread (%d) spawned\n", spawn); + + PR_Sleep( PR_MillisecondsToInterval(250) ); + } + + printf("All Threads Spawned.\n\n"); + + + + printf("Wait for threads.\n"); + for (PRInt32 i = 0; i < numberOfThreads; i++) + { + PRStatus rv; + printf("Thread (%d) Join...\n", i); + rv = PR_JoinThread(threads[i]); + printf("Thread (%d) Joined. (error: %d).\n", i, rv); + } + + PR_Interrupt(aEventThread); + PR_JoinThread(aEventThread); + + + printf("Calling Cleanup.\n"); + PR_Cleanup(); + + printf("Return zero.\n"); + return 0; +} -- cgit v1.2.3