VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/xpcom/proxy/tests/proxytests.cpp@ 86714

Last change on this file since 86714 was 1, checked in by vboxsync, 55 years ago

import

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.8 KB
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is mozilla.org code.
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 * Pierre Phaneuf <[email protected]>
24 *
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
36 *
37 * ***** END LICENSE BLOCK ***** */
38
39#include <stdio.h>
40
41#include "nsXPCOM.h"
42#include "nsIComponentManager.h"
43#include "nsIComponentRegistrar.h"
44#include "nsIServiceManager.h"
45#include "nsCOMPtr.h"
46
47#include "nscore.h"
48#include "nspr.h"
49#include "prmon.h"
50
51#include "nsITestProxy.h"
52
53#include "nsIProxyObjectManager.h"
54#include "nsIEventQueueService.h"
55
56static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID);
57
58/***************************************************************************/
59/* nsTestXPCFoo */
60/***************************************************************************/
61class nsTestXPCFoo : public nsITestProxy
62{
63 NS_DECL_ISUPPORTS
64 NS_IMETHOD Test(PRInt32 p1, PRInt32 p2, PRInt32* retval);
65 NS_IMETHOD Test2();
66 NS_IMETHOD Test3(nsISupports *p1, nsISupports **p2);
67
68 nsTestXPCFoo();
69};
70
71nsTestXPCFoo::nsTestXPCFoo()
72{
73 NS_ADDREF_THIS();
74}
75
76NS_IMPL_ISUPPORTS1(nsTestXPCFoo, nsITestProxy)
77
78NS_IMETHODIMP nsTestXPCFoo::Test(PRInt32 p1, PRInt32 p2, PRInt32* retval)
79{
80 printf("Thread (%d) Test Called successfully! Party on...\n", p1);
81 *retval = p1+p2;
82 return NS_OK;
83}
84
85
86NS_IMETHODIMP nsTestXPCFoo::Test2()
87{
88 printf("The quick brown netscape jumped over the old lazy ie..\n");
89
90 return NS_OK;
91}
92
93NS_IMETHODIMP nsTestXPCFoo::Test3(nsISupports *p1, nsISupports **p2)
94{
95 if (p1 != nsnull)
96 {
97 nsITestProxy *test;
98
99 p1->QueryInterface(NS_GET_IID(nsITestProxy), (void**)&test);
100
101 test->Test2();
102 PRInt32 a;
103 test->Test( 1, 2, &a);
104 printf("\n1+2=%d\n",a);
105 }
106
107
108 *p2 = new nsTestXPCFoo();
109 return NS_OK;
110}
111
112/***************************************************************************/
113/* nsTestXPCFoo2 */
114/***************************************************************************/
115class nsTestXPCFoo2 : public nsITestProxy
116{
117 NS_DECL_ISUPPORTS
118 NS_IMETHOD Test(PRInt32 p1, PRInt32 p2, PRInt32* retval);
119 NS_IMETHOD Test2();
120 NS_IMETHOD Test3(nsISupports *p1, nsISupports **p2);
121
122 nsTestXPCFoo2();
123};
124
125nsTestXPCFoo2::nsTestXPCFoo2()
126{
127 NS_ADDREF_THIS();
128}
129
130NS_IMPL_THREADSAFE_ISUPPORTS1(nsTestXPCFoo2, nsITestProxy)
131
132NS_IMETHODIMP nsTestXPCFoo2::Test(PRInt32 p1, PRInt32 p2, PRInt32* retval)
133{
134printf("calling back to caller!\n\n");
135
136 nsIProxyObjectManager* manager;
137 nsITestProxy * proxyObject;
138
139 nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID,
140 NS_GET_IID(nsIProxyObjectManager),
141 (nsISupports **)&manager);
142
143 printf("ProxyObjectManager: %p \n", manager);
144
145 PR_ASSERT(manager);
146
147 manager->GetProxyForObject((nsIEventQueue*)p1, NS_GET_IID(nsITestProxy), this, PROXY_SYNC, (void**)&proxyObject);
148 proxyObject->Test3(nsnull, nsnull);
149
150 printf("Deleting Proxy Object\n");
151 NS_RELEASE(proxyObject);
152
153 return NS_OK;
154}
155
156
157NS_IMETHODIMP nsTestXPCFoo2::Test2()
158{
159 printf("nsTestXPCFoo2::Test2() called\n");
160
161 return NS_OK;
162}
163
164
165NS_IMETHODIMP nsTestXPCFoo2::Test3(nsISupports *p1, nsISupports **p2)
166{
167 printf("Got called");
168 return NS_OK;
169}
170
171
172
173typedef struct _ArgsStruct
174{
175 nsIEventQueue* queue;
176 PRInt32 threadNumber;
177}ArgsStruct;
178
179
180
181// This will create two objects both descendants of a single IID.
182void TestCase_TwoClassesOneInterface(void *arg)
183{
184 ArgsStruct *argsStruct = (ArgsStruct*) arg;
185
186
187 nsIProxyObjectManager* manager;
188
189 nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID,
190 NS_GET_IID(nsIProxyObjectManager),
191 (nsISupports **)&manager);
192
193 printf("ProxyObjectManager: %p \n", manager);
194
195 PR_ASSERT(manager);
196
197 nsITestProxy *proxyObject;
198 nsITestProxy *proxyObject2;
199
200 nsTestXPCFoo* foo = new nsTestXPCFoo();
201 nsTestXPCFoo2* foo2 = new nsTestXPCFoo2();
202
203 PR_ASSERT(foo);
204 PR_ASSERT(foo2);
205
206
207 manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject);
208
209 manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo2, PROXY_SYNC, (void**)&proxyObject2);
210
211
212
213 if (proxyObject && proxyObject2)
214 {
215 // release ownership of the real object.
216
217 PRInt32 a;
218 nsresult rv;
219 PRInt32 threadNumber = argsStruct->threadNumber;
220
221 printf("Deleting real Object (%d)\n", threadNumber);
222 NS_RELEASE(foo);
223
224 printf("Deleting real Object 2 (%d)\n", threadNumber);
225 NS_RELEASE(foo2);
226
227
228 printf("Thread (%d) Prior to calling proxyObject->Test.\n", threadNumber);
229 rv = proxyObject->Test(threadNumber, 0, &a);
230 printf("Thread (%d) error: %d.\n", threadNumber, rv);
231
232
233 printf("Thread (%d) Prior to calling proxyObject->Test2.\n", threadNumber);
234 rv = proxyObject->Test2();
235 printf("Thread (%d) error: %d.\n", threadNumber, rv);
236
237 printf("Thread (%d) Prior to calling proxyObject2->Test2.\n", threadNumber);
238 rv = proxyObject2->Test2();
239 printf("Thread (%d) proxyObject2 error: %d.\n", threadNumber, rv);
240
241 printf("Deleting Proxy Object (%d)\n", threadNumber );
242 NS_RELEASE(proxyObject);
243
244 printf("Deleting Proxy Object 2 (%d)\n", threadNumber );
245 NS_RELEASE(proxyObject2);
246 }
247
248 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
249}
250
251
252
253void TestCase_NestedLoop(void *arg)
254{
255 ArgsStruct *argsStruct = (ArgsStruct*) arg;
256
257
258 nsIProxyObjectManager* manager;
259
260 nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID,
261 NS_GET_IID(nsIProxyObjectManager),
262 (nsISupports **)&manager);
263
264 printf("ProxyObjectManager: %p \n", manager);
265
266 PR_ASSERT(manager);
267
268 nsITestProxy *proxyObject;
269 nsTestXPCFoo2* foo = new nsTestXPCFoo2();
270
271 PR_ASSERT(foo);
272
273
274 manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject);
275
276 if (proxyObject)
277 {
278 // release ownership of the real object.
279
280 nsresult rv;
281 PRInt32 threadNumber = argsStruct->threadNumber;
282
283 printf("Deleting real Object (%d)\n", threadNumber);
284 NS_RELEASE(foo);
285
286 PRInt32 retval;
287
288 printf("Getting EventQueue...\n");
289
290 nsIEventQueue* eventQ;
291 nsCOMPtr<nsIEventQueueService> eventQService =
292 do_GetService(kEventQueueServiceCID, &rv);
293 if (NS_SUCCEEDED(rv))
294 {
295 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ);
296 if (NS_FAILED(rv))
297 rv = eventQService->CreateThreadEventQueue();
298 if (NS_FAILED(rv))
299 return;
300 else
301 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ);
302
303 printf("Thread (%d) Prior to calling proxyObject->Test.\n", threadNumber);
304 rv = proxyObject->Test(NS_PTR_TO_INT32(eventQ), 0, &retval);
305 printf("Thread (%d) proxyObject error: %d.\n", threadNumber, rv);
306
307 printf("Deleting Proxy Object (%d)\n", threadNumber );
308 NS_RELEASE(proxyObject);
309 }
310
311 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
312 }
313}
314
315
316
317void TestCase_2(void *arg)
318{
319
320 ArgsStruct *argsStruct = (ArgsStruct*) arg;
321
322 nsIProxyObjectManager* manager;
323
324 nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID,
325 NS_GET_IID(nsIProxyObjectManager),
326 (nsISupports **)&manager);
327
328 PR_ASSERT(manager);
329
330 nsITestProxy *proxyObject;
331
332 manager->GetProxy(argsStruct->queue,
333 NS_GET_IID(nsITestProxy), // should be CID!
334 nsnull,
335 NS_GET_IID(nsITestProxy),
336 PROXY_SYNC,
337 (void**)&proxyObject);
338
339 if (proxyObject != nsnull)
340 {
341 NS_RELEASE(proxyObject);
342 }
343}
344
345
346
347void TestCase_nsISupports(void *arg)
348{
349
350 ArgsStruct *argsStruct = (ArgsStruct*) arg;
351
352 nsIProxyObjectManager* manager;
353
354 nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID,
355 NS_GET_IID(nsIProxyObjectManager),
356 (nsISupports **)&manager);
357
358 PR_ASSERT(manager);
359
360 nsITestProxy *proxyObject;
361 nsTestXPCFoo* foo = new nsTestXPCFoo();
362
363 PR_ASSERT(foo);
364
365 manager->GetProxyForObject(argsStruct->queue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject);
366
367 if (proxyObject != nsnull)
368 {
369 nsISupports *bISupports = nsnull, *cISupports = nsnull;
370
371 proxyObject->Test3(foo, &bISupports);
372 proxyObject->Test3(bISupports, &cISupports);
373
374 nsITestProxy *test;
375 bISupports->QueryInterface(NS_GET_IID(nsITestProxy), (void**)&test);
376
377 test->Test2();
378
379 NS_RELEASE(foo);
380 NS_RELEASE(proxyObject);
381 }
382}
383
384
385
386
387
388/***************************************************************************/
389/* ProxyTest */
390/***************************************************************************/
391
392static void PR_CALLBACK ProxyTest( void *arg )
393{
394 //TestCase_TwoClassesOneInterface(arg);
395 // TestCase_2(arg);
396 //TestCase_nsISupports(arg);
397 TestCase_NestedLoop(arg);
398
399 NS_RELEASE( ((ArgsStruct*) arg)->queue);
400 free((void*) arg);
401}
402
403nsIEventQueue *gEventQueue = nsnull;
404
405static void PR_CALLBACK EventLoop( void *arg )
406{
407 nsresult rv;
408 printf("Creating EventQueue...\n");
409
410 nsIEventQueue* eventQ;
411 nsCOMPtr<nsIEventQueueService> eventQService =
412 do_GetService(kEventQueueServiceCID, &rv);
413 if (NS_SUCCEEDED(rv)) {
414 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ);
415 if (NS_FAILED(rv))
416 rv = eventQService->CreateThreadEventQueue();
417 if (NS_FAILED(rv))
418 return;
419 else
420 rv = eventQService->GetThreadEventQueue(NS_CURRENT_THREAD, &eventQ);
421 }
422 if (NS_FAILED(rv)) return;
423
424 rv = eventQ->QueryInterface(NS_GET_IID(nsIEventQueue), (void**)&gEventQueue);
425 if (NS_FAILED(rv)) return;
426
427
428 printf("Verifing calling Proxy on eventQ thread.\n");
429
430 nsIProxyObjectManager* manager;
431
432 nsServiceManager::GetService( NS_XPCOMPROXY_CONTRACTID,
433 NS_GET_IID(nsIProxyObjectManager),
434 (nsISupports **)&manager);
435
436 PR_ASSERT(manager);
437
438 nsITestProxy *proxyObject;
439 nsTestXPCFoo* foo = new nsTestXPCFoo();
440
441 PR_ASSERT(foo);
442
443 manager->GetProxyForObject(gEventQueue, NS_GET_IID(nsITestProxy), foo, PROXY_SYNC, (void**)&proxyObject);
444
445 PRInt32 a;
446 proxyObject->Test(1, 2, &a);
447 proxyObject->Test2();
448
449
450 NS_RELEASE(proxyObject);
451 delete foo;
452
453 printf("End of Verification calling Proxy on eventQ thread.\n");
454
455
456 printf("Looping for events.\n");
457
458 PLEvent* event = nsnull;
459
460 while ( PR_SUCCESS == PR_Sleep( PR_MillisecondsToInterval(1)) )
461 {
462 rv = gEventQueue->GetEvent(&event);
463 if (NS_FAILED(rv))
464 return;
465 gEventQueue->HandleEvent(event);
466 }
467
468 gEventQueue->ProcessPendingEvents();
469
470 printf("Closing down Event Queue.\n");
471 delete gEventQueue;
472 gEventQueue = nsnull;
473
474 printf("End looping for events.\n\n");
475}
476
477int
478main(int argc, char **argv)
479{
480 int numberOfThreads = 1;
481
482 if (argc > 1)
483 numberOfThreads = atoi(argv[1]);
484
485 nsCOMPtr<nsIServiceManager> servMan;
486 NS_InitXPCOM2(getter_AddRefs(servMan), nsnull, nsnull);
487 nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(servMan);
488 NS_ASSERTION(registrar, "Null nsIComponentRegistrar");
489 registrar->AutoRegister(nsnull);
490
491 static PRThread** threads = (PRThread**) calloc(sizeof(PRThread*), numberOfThreads);
492 static PRThread* aEventThread;
493
494 aEventThread = PR_CreateThread(PR_USER_THREAD,
495 EventLoop,
496 NULL,
497 PR_PRIORITY_NORMAL,
498 PR_GLOBAL_THREAD,
499 PR_JOINABLE_THREAD,
500 0 );
501
502
503 PR_Sleep(PR_MillisecondsToInterval(1000));
504
505 NS_ASSERTION(gEventQueue, "no main event queue"); // BAD BAD BAD. EVENT THREAD DID NOT CREATE QUEUE. This may be a timing issue, set the
506 // sleep about longer, and try again.
507
508 printf("Spawn Threads:\n");
509 for (PRInt32 spawn = 0; spawn < numberOfThreads; spawn++)
510 {
511
512 ArgsStruct *args = (ArgsStruct *) malloc (sizeof(ArgsStruct));
513
514 args->queue = gEventQueue;
515 NS_ADDREF(args->queue);
516 args->threadNumber = spawn;
517
518 threads[spawn] = PR_CreateThread(PR_USER_THREAD,
519 ProxyTest,
520 args,
521 PR_PRIORITY_NORMAL,
522 PR_GLOBAL_THREAD,
523 PR_JOINABLE_THREAD,
524 0 );
525
526 printf("\tThread (%d) spawned\n", spawn);
527
528 PR_Sleep( PR_MillisecondsToInterval(250) );
529 }
530
531 printf("All Threads Spawned.\n\n");
532
533
534
535 printf("Wait for threads.\n");
536 for (PRInt32 i = 0; i < numberOfThreads; i++)
537 {
538 PRStatus rv;
539 printf("Thread (%d) Join...\n", i);
540 rv = PR_JoinThread(threads[i]);
541 printf("Thread (%d) Joined. (error: %d).\n", i, rv);
542 }
543
544 PR_Interrupt(aEventThread);
545 PR_JoinThread(aEventThread);
546
547
548 printf("Calling Cleanup.\n");
549 PR_Cleanup();
550
551 printf("Return zero.\n");
552 return 0;
553}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette