xref: /trunk/main/sal/test/unloading/unloadTest.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3) !
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 
29 // MARKER(update_precomp.py): autogen include statement, do not remove
30 #include "precompiled_sal.hxx"
31 
32 #include<osl/module.hxx>
33 #include <osl/time.h>
34 #include <rtl/ustring.hxx>
35 #include <stdio.h>
36 #include <cppuhelper/factory.hxx>
37 #include <cppuhelper/servicefactory.hxx>
38 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
39 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
40 #include <com/sun/star/lang/XServiceInfo.hpp>
41 #include <com/sun/star/lang/XComponent.hpp>
42 #include <com/sun/star/beans/XPropertySet.hpp>
43 #include <com/sun/star/uno/XComponentContext.hpp>
44 #include <com/sun/star/uno/XUnloadingPreference.hpp>
45 #include <com/sun/star/lang/XTypeProvider.hpp>
46 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
47 
48 #include <stdio.h>
49 using namespace ::rtl;
50 using namespace ::osl;
51 using namespace ::com::sun::star::uno;
52 using namespace ::com::sun::star::lang;
53 using namespace ::cppu;
54 using namespace ::com::sun::star::beans;
55 using namespace ::com::sun::star::container;
56 
57 #define IMPLNAME1 "com.sun.star.comp.sal.UnloadingTest1"
58 #define SERVICENAME1 "com.sun.star.UnloadingTest1"
59 #define IMPLNAME2 "com.sun.star.comp.sal.UnloadingTest2"
60 #define SERVICENAME2 "com.sun.star.UnloadingTest2"
61 #define IMPLNAME3 "com.sun.star.comp.sal.UnloadingTest3"
62 #define SERVICENAME3 "com.sun.star.UnloadingTest3"
63 #define IMPLNAME4 "com.sun.star.comp.sal.OneInstanceTest"
64 #define SERVICENAME4 "com.sun.star.OneInstanceTest"
65 
66 #define IMPLNAME21 "com.sun.star.comp.sal.UnloadingTest21"
67 #define SERVICENAME21 "com.sun.star.UnloadingTest21"
68 #define IMPLNAME22 "com.sun.star.comp.sal.UnloadingTest22"
69 #define SERVICENAME22 "com.sun.star.UnloadingTest22"
70 #define IMPLNAME23 "com.sun.star.comp.sal.UnloadingTest23"
71 #define SERVICENAME23 "com.sun.star.UnloadingTest23"
72 
73 #ifdef UNX
74 #define LIBRARY1 "libsamplelib1.so"
75 #define LIBRARY2 "libsamplelib2.so"
76 #elif defined WNT
77 #define LIBRARY1 "samplelib1"
78 #define LIBRARY2 "samplelib2"
79 #endif
80 /*
81 Tested: rtl_registerModuleForUnloading, rtl_unregisterModuleForUnloading, rtl_unloadUnusedLibraries
82         1 component.
83 
84 next: Test with multiple components
85         Listener mechanism.
86 */
87 
88 sal_Bool test1();
89 sal_Bool test2();
90 sal_Bool test3();
91 sal_Bool test4();
92 sal_Bool test5();
93 sal_Bool test6();
94 sal_Bool test7();
95 sal_Bool test8();
96 sal_Bool test9();
97 void SAL_CALL listenerCallback( void* id);
98 
99 int main(int argc, char* argv[])
100 {
101   // Test if the servicemanager can be created and if the sample libs
102   // can be loaded
103 //  Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
104 //     OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
105 //    if( !serviceManager.is())
106 //    {
107 //      printf("\n ####################################################\n"
108 //         "Error: could not create service manager. \n"
109 //         "Is the executable in the office program directory?\n");
110 //      return -1;
111 //    }
112 
113 //    Reference<XInterface> xint1=  serviceManager->createInstance( OUString(
114 //                  RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
115 
116 //    if( !xint1.is())
117 //    {
118 //        printf("\n ###################################################\n"
119 //           "Error: could not create service from samplelib1\n"
120 //           "Is samplelib1 in the office program directory and is it "
121 //           "registered?\n");
122 //        return -1;
123 //    }
124 //    Reference<XInterface> xint2=  serviceManager->createInstance( OUString(
125 //                  RTL_CONSTASCII_USTRINGPARAM(SERVICENAME21)));
126 //    if( !xint2.is())
127 //      {
128 //        printf("\n ###################################################"
129 //           "Error: could not create service from samplelib2\n"
130 //           "Is samplelib2 in the office program directory and is it "
131 //           "registered?\n");
132 //        return -1;
133 //      }
134 //        //destroy servicemanager
135 //        Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
136 //        Any any_prop= xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
137 //        Reference<XComponentContext> xContext;
138 //        any_prop >>= xContext;
139 //        Reference<XComponent> xComponent( xContext, UNO_QUERY);
140 //        xComponent->dispose();
141 
142 //        //unload samplelib1 and samplelib2. We need the handles, therefore load
143 //        // the libs
144 //        OUString libname1( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
145 //        OUString libname2( RTL_CONSTASCII_USTRINGPARAM(LIBRARY2));
146 //        oslModule m1= osl_loadModule(libname1.pData, 0);
147 //        oslModule m2= osl_loadModule(libname2.pData, 0);
148 //        osl_unloadModule( m1);
149 //        osl_unloadModule( m1);
150 //        osl_unloadModule( m2);
151 //        osl_unloadModule( m2);
152 
153 
154   sal_Bool ret1= test1();
155   if( ret1) printf( "\n Test 1 successful \n");
156     else printf("\n !!!!!! Test 1 failed\n");
157     sal_Bool ret2= test2();
158     if( ret2) printf( "\n Test 2 successful \n");
159     else printf("\n !!!!!! Test 2 failed\n");
160     sal_Bool ret3= test3();
161     if( ret3) printf( "\n Test 3 successful \n");
162     else printf("\n !!!!!! Test 3 failed\n");
163     sal_Bool ret4= test4();
164     if( ret4) printf( "\n Test 4 successful \n");
165     else printf("\n !!!!!! Test 4 failed\n");
166     sal_Bool ret5= test5();
167     if( ret5) printf( "\n Test 5 successful \n");
168     else printf("\n !!!!!! Test 5 failed\n");
169     // takes some time (10s)
170     sal_Bool ret6= test6();
171     sal_Bool ret7= test7(); // prints message itself
172     sal_Bool ret8= test8();
173     if( ret8) printf( "\n Test 8 successful \n");
174     else printf("\n !!!!!! Test 8 failed\n");
175     sal_Bool ret9= test9();
176     if( ret9) printf( "\n Test 9 successful: service manager is unloading listener\n");
177     else printf("\n !!!!! Test 9 failed\n");
178 
179     return 0;
180 }
181 
182 /* Create an instance of SERVICENAME1, call a function and unload module.
183    This tests the loader and basic functionality.
184    The library will be loaded once manually and the handle will be stored.
185    Then the library will be unloaded. After rtl_unloadUnusedLibraries we try to
186    get a symbol of the unloaded lib. If this fails then the test is successful.
187 */
188 sal_Bool test1()
189 {
190     printf("Test 1 ####################################################\n");
191     oslModule handleMod=0;
192     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
193     {
194     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
195         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
196     Reference<XInterface> xint= serviceManager->createInstance( OUString(
197                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
198 
199     // get the handle
200     handleMod=  osl_loadModule( lib1Name.pData, 0);
201     osl_unloadModule( handleMod);
202     xint=0;
203 
204     Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
205     Any any_prop=   xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
206     Reference<XComponentContext> xContext;
207     any_prop >>= xContext;
208     Reference<XComponent> xComponent( xContext, UNO_QUERY);
209     xComponent->dispose();
210     }
211     rtl_unloadUnusedModules( NULL);
212 
213     // Try to get a symbol, must fail
214     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
215     void* pSymbol= osl_getSymbol(  handleMod, sSymbol.pData);
216 
217     if( !pSymbol)
218         return sal_True;
219     return sal_False;
220 }
221 
222 /* Multipe loadModule + rtl_registerModuleForUnloading.
223 The module will be registered as often as it has been loaded.
224 */
225 sal_Bool test2()
226 {
227     printf("Test 2 ####################################################\n");
228     oslModule handleMod=0;
229     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
230     {
231     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
232         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
233 
234     Reference<XInterface> xint= serviceManager->createInstance( OUString(
235                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
236 
237     handleMod=  osl_loadModule( lib1Name.pData, 0);
238     osl_unloadModule( handleMod);
239     //-----------------------------------------------------------
240     oslModule mod1= osl_loadModule( lib1Name.pData, 0);
241     oslModule mod2= osl_loadModule( lib1Name.pData, 0);
242     oslModule mod3= osl_loadModule( lib1Name.pData, 0);
243 
244     rtl_registerModuleForUnloading(mod1);
245     rtl_registerModuleForUnloading(mod2);
246     rtl_registerModuleForUnloading(mod3);
247     // ----------------------------------------------------------
248     Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
249     Any any_prop=   xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
250     Reference<XComponentContext> xContext;
251     any_prop >>= xContext;
252     Reference<XComponent> xComponent( xContext, UNO_QUERY);
253     xComponent->dispose();
254     }
255     rtl_unloadUnusedModules( NULL);
256 
257     // Try to get a symbol, must fail
258     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
259     void* pSymbol= osl_getSymbol(  handleMod, sSymbol.pData);
260 
261     if( !pSymbol)
262         return sal_True;
263     return sal_False;
264 }
265 
266 /* Multipe loadModule + rtl_registerModuleForUnloading.
267 The module will be registered one time less as it has been loaded.
268 */
269 sal_Bool test3()
270 {
271     printf("Test 3 ####################################################\n");
272     oslModule handleMod=0;
273     sal_Bool retval=sal_False;
274     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
275     {
276     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
277         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
278 
279     Reference<XInterface> xint= serviceManager->createInstance( OUString(
280                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
281 
282     handleMod=  osl_loadModule( lib1Name.pData, 0);
283     osl_unloadModule( handleMod);
284     //-----------------------------------------------------------
285     oslModule mod1= osl_loadModule( lib1Name.pData, 0);
286     oslModule mod2= osl_loadModule( lib1Name.pData, 0);
287     oslModule mod3= osl_loadModule( lib1Name.pData, 0);
288 
289     rtl_registerModuleForUnloading(mod1);
290     rtl_registerModuleForUnloading(mod2);
291     // ----------------------------------------------------------
292     Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
293     Any any_prop=   xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
294     Reference<XComponentContext> xContext;
295     any_prop >>= xContext;
296     Reference<XComponent> xComponent( xContext, UNO_QUERY);
297     xComponent->dispose();
298     }
299     rtl_unloadUnusedModules( NULL);
300 
301     // Try to get a symbol, must succeed
302     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
303     void* pSymbol= osl_getSymbol(  handleMod, sSymbol.pData);
304 
305     if( pSymbol)
306     {
307         retval= sal_True;
308         osl_unloadModule( handleMod);
309         pSymbol= osl_getSymbol( handleMod, sSymbol.pData);
310     }
311     return retval;
312 }
313 /* 2 Modules
314 
315 */
316 sal_Bool test4()
317 {
318     printf("Test 4 ####################################################\n");
319     oslModule handleMod1=0;
320     oslModule handleMod2=0;
321     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
322     OUString lib2Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY2));
323     {
324     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
325         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
326 
327     Reference<XInterface> xint= serviceManager->createInstance( OUString(
328                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
329 
330     handleMod1= osl_loadModule( lib1Name.pData, 0);
331     osl_unloadModule( handleMod1);
332     Reference<XInterface> xint2=    serviceManager->createInstance( OUString(
333                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME21)));
334 
335     handleMod2= osl_loadModule( lib2Name.pData, 0);
336     osl_unloadModule( handleMod2);
337 
338     //-----------------------------------------------------------
339     // ----------------------------------------------------------
340     Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
341     Any any_prop=   xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
342     Reference<XComponentContext> xContext;
343     any_prop >>= xContext;
344     Reference<XComponent> xComponent( xContext, UNO_QUERY);
345     xComponent->dispose();
346     }
347     rtl_unloadUnusedModules( NULL);
348 
349     // Try to get a symbol, must fail
350     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
351     void* pSymbol= osl_getSymbol(  handleMod1, sSymbol.pData);
352 
353     void* pSymbol2= osl_getSymbol(  handleMod2, sSymbol.pData);
354     if( ! pSymbol && !pSymbol2)
355         return sal_True;
356     return sal_False;
357 }
358 
359 /* 2 Modules and 6 services
360 
361 */
362 sal_Bool test5()
363 {
364     printf("test5 ####################################################\n");
365     oslModule handleMod1=0;
366     oslModule handleMod2=0;
367     sal_Bool btest1= sal_False;
368     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
369     OUString lib2Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY2));
370     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
371     {
372     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
373         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
374 
375     //-----------------------------------------------------------
376     Reference<XInterface> xint= serviceManager->createInstance( OUString(
377                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
378     Reference<XInterface> xint2=    serviceManager->createInstance( OUString(
379                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME2)));
380     Reference<XInterface> xint3=    serviceManager->createInstance( OUString(
381                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME3)));
382     Reference<XInterface> xint4=    serviceManager->createInstance( OUString(
383                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME21)));
384     Reference<XInterface> xint5=    serviceManager->createInstance( OUString(
385                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME22)));
386     Reference<XInterface> xint6=    serviceManager->createInstance( OUString(
387                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME23)));
388 
389     // ----------------------------------------------------------
390     handleMod1= osl_loadModule( lib1Name.pData, 0);
391     osl_unloadModule( handleMod1);
392     handleMod2= osl_loadModule( lib2Name.pData, 0);
393     osl_unloadModule( handleMod2);
394 
395     // get rid of the service manager
396     Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
397     Any any_prop=   xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
398     Reference<XComponentContext> xContext;
399     any_prop >>= xContext;
400     Reference<XComponent> xComponent( xContext, UNO_QUERY);
401     xComponent->dispose();
402 
403     // try unloading, must fail
404     rtl_unloadUnusedModules( NULL);
405     void* pSymbol= osl_getSymbol(  handleMod1, sSymbol.pData);
406 
407     void* pSymbol2= osl_getSymbol(  handleMod2, sSymbol.pData);
408     if(  pSymbol && pSymbol2)
409         btest1= sal_True;
410 
411     }
412 
413     // Try to get a symbol, must succeed
414     rtl_unloadUnusedModules( NULL);
415 
416     void* pSymbol= osl_getSymbol(  handleMod1, sSymbol.pData);
417     void* pSymbol2= osl_getSymbol(  handleMod2, sSymbol.pData);
418     if( ! pSymbol && !pSymbol2 && btest1)
419         return sal_True;
420     return sal_False;
421 }
422 
423 /*
424 TimeValue Test
425 rtl_unloadUnusedModules takes a TimeValue which determines a timespan
426 a module must have been constantly unused in order to be unloaded.
427 This is only a rough test. To make accurate tests, one should directly
428 write code in the unload.cxx file.
429 The function will not return (loop) when the test fails or the result value
430 is far off the 10 seconds value.
431 */
432 sal_Bool test6()
433 {
434     printf("test6 ####################################################\n");
435     oslModule handleMod1=0;
436     oslModule handleMod2=0;
437     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
438     OUString lib2Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY2));
439     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
440     {
441     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
442         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
443     Reference<XInterface> xint= serviceManager->createInstance( OUString(
444                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
445 
446     // ----------------------------------------------------------
447     handleMod1= osl_loadModule( lib1Name.pData, 0);
448     osl_unloadModule( handleMod1);
449 
450     // get rid of the service manager
451     Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
452     Any any_prop=   xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
453     Reference<XComponentContext> xContext;
454     any_prop >>= xContext;
455     Reference<XComponent> xComponent( xContext, UNO_QUERY);
456     xComponent->dispose();
457     }
458 
459     // Enter a loop and try unloading. At least after 10 seconds
460     // this should be successful.
461     TimeValue time={10,0};
462 
463     TimeValue beforeTime={0,0};
464     printf("\n unloading should take about 10 seconds\n");
465     osl_getSystemTime( &beforeTime);
466     for(;;)
467     {
468 
469         rtl_unloadUnusedModules( &time);
470         void* pSymbol= osl_getSymbol(  handleMod1, sSymbol.pData);
471         if( ! pSymbol)
472             break;
473     }
474     TimeValue afterTime={0,0};
475     osl_getSystemTime( &afterTime);
476 
477     printf("\n it took about %i seconds \n Check the value!!!", afterTime.Seconds - beforeTime.Seconds);
478     printf(" hit return to continue\n");
479     getchar();
480 
481     return sal_True;
482 }
483 
484 /*
485 */
486 sal_Bool test7()
487 {
488     printf("Test 7 ####################################################"
489             "\nThe callback function should be called 3 times\n");
490     sal_Int32 id1=1;
491     sal_Int32 id2=2;
492     sal_Int32 id3=3;
493     sal_Int32 cookie1= rtl_addUnloadingListener( listenerCallback, &id1);
494     sal_Int32 cookie2= rtl_addUnloadingListener( listenerCallback, &id2);
495     sal_Int32 cookie3= rtl_addUnloadingListener( listenerCallback, &id3);
496 
497     printf("\nTest 7 \nThe listener should be called 3 times\n");
498     rtl_unloadUnusedModules( NULL);
499 
500     rtl_removeUnloadingListener( cookie1);
501     rtl_removeUnloadingListener( cookie2);
502     rtl_removeUnloadingListener( cookie3);
503 
504     sal_Int32 cookie4= rtl_addUnloadingListener( listenerCallback, &id1);
505     sal_Int32 cookie5= rtl_addUnloadingListener( listenerCallback, &id2);
506     sal_Int32 cookie6= rtl_addUnloadingListener( listenerCallback, &id3);
507 
508     if( cookie1 == cookie4 &&
509         cookie2 == cookie5 )
510     {
511         printf("\n###cookie recycling works\n");
512         printf("hit return to continue\n");
513         getchar();
514     }
515     else
516     {
517         printf("\n###cookie recycling failed!!!\n");
518         printf("hit return to continue\n");
519         getchar();
520     }
521 
522     rtl_removeUnloadingListener( cookie1);
523     rtl_removeUnloadingListener( cookie2);
524     rtl_removeUnloadingListener( cookie3);
525     return sal_True;
526 }
527 
528 /* Test one-instance-service default factory (XUnloadingPreference)
529     cppuhelper/source/factory.cxx
530 */
531 sal_Bool test8()
532 {
533     printf("Test 8 ####################################################\n");
534     oslModule handleMod1=0;
535     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
536     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
537 
538     sal_Bool b_ifaceSupported=sal_False;
539     sal_Bool b_instances_identical= sal_False;
540     sal_Bool b_releaseBeforeLoading= sal_False;
541     sal_Bool b_releaseAfterLoading= sal_False;
542     sal_Bool b_unloaded= sal_False;
543 
544     {
545     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
546         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
547     Reference<XContentEnumerationAccess> xContent( serviceManager, UNO_QUERY);
548     Reference<XEnumeration> xenum=  xContent->createContentEnumeration(
549         OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME4)));
550 
551     Any any_elem;
552     if( xenum->hasMoreElements())
553         any_elem= xenum->nextElement();
554     Reference<XInterface> xinterfaceFact;
555     any_elem>>=xinterfaceFact;
556     Reference<XTypeProvider> xprov( xinterfaceFact, UNO_QUERY);
557 
558     Sequence<Type> seqTypes= xprov->getTypes();
559 
560     //  XTypeProvider test
561     for( sal_Int32 i=0; i<seqTypes.getLength(); i++)
562     {
563         OUString name= seqTypes[i].getTypeName();
564         if( name == OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.uno.XUnloadingPreference")))
565             b_ifaceSupported= sal_True;
566     }
567 
568     // XUnloadingPreference::releaseOnNotification should return true now because we haven't
569     // created an instance yet
570     Reference<XUnloadingPreference> xreject( xinterfaceFact, UNO_QUERY);
571     b_releaseBeforeLoading= xreject->releaseOnNotification();
572 
573     // Create instance. Afterwards releaseOnNotification should return false.
574     Reference<XInterface> xint= serviceManager->createInstance( OUString(
575                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME4)));
576     b_releaseAfterLoading= xreject->releaseOnNotification();
577     b_releaseAfterLoading= b_releaseAfterLoading? sal_False : sal_True;
578 
579     // safe the handle of the module
580     handleMod1= osl_loadModule( lib1Name.pData, 0);
581     osl_unloadModule( handleMod1);
582 
583     // ----------------------------------------------------------
584     // for debugging
585     Reference<XServiceInfo> info( xint, UNO_QUERY);
586     OUString s= info->getImplementationName();
587 
588     // get another instance which must be the same
589     Reference<XInterface> xint2=    serviceManager->createInstance( OUString(
590                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME4)));
591 
592     b_instances_identical= xint == xint2;
593 
594     // get rid of the service manager
595     Reference<XPropertySet> xSet( serviceManager, UNO_QUERY);
596     Any any_prop=   xSet->getPropertyValue( OUString(RTL_CONSTASCII_USTRINGPARAM("DefaultContext")));
597     Reference<XComponentContext> xContext;
598     any_prop >>= xContext;
599     Reference<XComponent> xComponent( xContext, UNO_QUERY);
600     xComponent->dispose();
601     }
602 
603     rtl_unloadUnusedModules( NULL);
604 
605     // The library must be unloaded now
606     void* pSymbol= osl_getSymbol(  handleMod1, sSymbol.pData);
607     if( ! pSymbol )
608         b_unloaded= sal_True;
609 
610     if( b_ifaceSupported && b_instances_identical && b_releaseBeforeLoading &&
611         b_releaseAfterLoading && b_unloaded)
612         return sal_True;
613     return sal_False;
614 }
615 
616 void SAL_CALL listenerCallback( void* id)
617 {
618     printf(" listener called with id= %i\n", *(sal_Int32*)id);
619 }
620 
621 /*
622 
623   */
624 sal_Bool test9()
625 {
626     printf("Test 9 ####################################################\n");
627     oslModule handleMod=0;
628     sal_Bool retval=sal_False;
629     OUString lib1Name( RTL_CONSTASCII_USTRINGPARAM(LIBRARY1));
630 
631     Reference<XMultiServiceFactory> serviceManager= createRegistryServiceFactory(
632         OUString( RTL_CONSTASCII_USTRINGPARAM("applicat.rdb")));
633 
634     Reference<XInterface> xint= serviceManager->createInstance( OUString(
635                 RTL_CONSTASCII_USTRINGPARAM(SERVICENAME1)));
636     // Release the service. The library refcount should be 1
637     xint=0;
638 
639     handleMod=  osl_loadModule( lib1Name.pData, 0);
640     osl_unloadModule( handleMod);
641     //-----------------------------------------------------------
642 
643     // the service manager is still alive
644     rtl_unloadUnusedModules( NULL);
645     // Try to get a symbol, must fail
646     OUString sSymbol( RTL_CONSTASCII_USTRINGPARAM("component_getFactory"));
647     void* pSymbol= osl_getSymbol(  handleMod, sSymbol.pData);
648 
649     if( pSymbol)
650     {
651         retval= sal_False;
652     }
653     else
654         retval= sal_True;
655     return retval;
656 }
657