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