Doxygen changes
[ACE_TAO.git] / ACE / tests / Based_Pointer_Test.cpp
blob7c8655ad8ba2ea84629e594e6bd6825806272a31
2 //=============================================================================
3 /**
4 * @file Based_Pointer_Test.cpp
6 * This test check the Based_Pointer and Based_Pointer_repository classes.
8 * @author Steve Williams <steve@telxio>
9 */
10 //=============================================================================
13 #include "test_config.h"
14 #include "ace/DLL.h"
15 #include "ace/ACE.h"
16 #ifdef ACE_HAS_POSITION_INDEPENDENT_POINTERS
17 #include "ace/Based_Pointer_Repository.h"
18 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */
19 #include "ace/Malloc_T.h"
20 #include "ace/MMAP_Memory_Pool.h"
21 #include "ace/PI_Malloc.h"
22 #include "ace/Null_Mutex.h"
23 #include "ace/Based_Pointer_T.h"
24 #include "ace/SString.h"
25 #include "ace/OS_NS_unistd.h"
27 class Foo
29 private:
30 Foo(const Foo &)
33 public:
34 friend class ace_dewarn_gplusplus;
35 ~Foo ()
40 class Void_Pointer : public ACE_Based_Pointer<void>
44 #ifdef ACE_HAS_POSITION_INDEPENDENT_POINTERS
46 #if defined (ACE_LD_DECORATOR_STR)
47 # define OBJ_SUFFIX ACE_LD_DECORATOR_STR ACE_DLL_SUFFIX
48 #else
49 # define OBJ_SUFFIX ACE_DLL_SUFFIX
50 #endif /* ACE_LD_DECORATOR_STR */
52 #if defined (ACE_WIN32) || defined (ACE_OPENVMS)
53 # define OBJ_PREFIX ACE_DLL_PREFIX
54 #else
55 # define OBJ_PREFIX ACE_TEXT("./") ACE_DLL_PREFIX
56 #endif /* ACE_WIN32 */
58 // Declare the type of the DLL symbol:
59 typedef void *(*Get_Bp_Repository_Inst)(void);
61 // Declare an allocator based MMAP_Memory_Pool
62 typedef ACE_Malloc_T< ACE_MMAP_MEMORY_POOL, ACE_Null_Mutex, ACE_PI_Control_Block
63 > MMAP_Allocator;
66 // Check that the ACE_Based_Pointer_Repository can be accessed
67 // from a Windows DLL
68 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=1991)
69 int singleton_test (void)
71 void* baddr1 = ACE_BASED_POINTER_REPOSITORY::instance();
72 void* baddr2 = ACE_BASED_POINTER_REPOSITORY::instance();
74 if (baddr1 != baddr2)
76 ACE_ERROR_RETURN ((LM_ERROR,
77 ACE_TEXT ("ACE_Based_Pointer_Repository is not a singleton\n")),
78 -1);
81 // Protection against this test being run on platforms not supporting Dlls.
82 #if defined(ACE_HAS_DYNAMIC_LINKING)
84 ACE_TString dll_file;
85 const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
86 if (subdir_env)
88 dll_file = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
89 dll_file += ACE_DIRECTORY_SEPARATOR_STR;
92 dll_file += OBJ_PREFIX ACE_TEXT ("Based_Pointer_Test_Lib") OBJ_SUFFIX;
94 // If DLL causes multiple instances of singleton
95 // then the ACE_Cleanup object registered
96 // with the ACE_Object_manager will no longer be valid,
97 // at exit time if the library is unloaded. Override
98 // the default close on destruct.
99 ACE_DLL dll;
100 int retval = dll.open (dll_file.c_str (),
101 ACE_DEFAULT_SHLIB_MODE,
104 if (retval != 0)
106 ACE_TCHAR *dll_error = dll.error ();
107 ACE_ERROR_RETURN ((LM_ERROR,
108 ACE_TEXT ("Error in DLL Open: %s\n"),
109 dll_error ? dll_error : ACE_TEXT ("unknown error")),
110 -1);
113 #if defined (ACE_OPENVMS)
114 // with OPENVMS symbol names > 31 cause us trouble with dlsym()
115 void* foo = dll.symbol (ACE_TEXT ("get_based_pointer_repo_inst"));
116 #else
117 void* foo = dll.symbol (ACE_TEXT ("get_based_pointer_repository_instance"));
118 #endif
120 // Cast the void* to function* with a long as intermediate.
121 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
122 Get_Bp_Repository_Inst get_bp_repository_inst =
123 reinterpret_cast<Get_Bp_Repository_Inst> (tmp);
124 if (get_bp_repository_inst == 0)
125 ACE_ERROR_RETURN ((LM_ERROR,
126 ACE_TEXT ("%p\n"),
127 dll.error ()),
128 -1);
130 void* baddr_dll = get_bp_repository_inst ();
132 dll.close ();
134 if (baddr_dll != baddr1)
136 ACE_ERROR_RETURN ((LM_ERROR,
137 ACE_TEXT ("ACE_Based_Pointer_Repository is not a ")
138 ACE_TEXT ("singleton in DLL <%@> <%@>\n"),
139 baddr_dll,
140 baddr1),
141 -1);
143 #endif /* ACE_HAS_DYNAMIC_LINKING */
145 return 0;
148 // Check that MMAP memory blocks are correctly mapped
149 // into the Based_Pointer_Repository
151 mmap_map_test(void)
153 MMAP_Allocator* alloc = 0;
155 ACE_OS::unlink("foo");
157 // The 'options' are only here to quiet MSVC 6. It can be removed
158 // when MSVC 6 support is removed.
159 MMAP_Allocator::MEMORY_POOL_OPTIONS *options = 0;
160 ACE_NEW_RETURN
161 (alloc,
162 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options),
163 -1);
165 void* addr = alloc->base_addr();
166 if(addr == 0)
168 ACE_ERROR((LM_ERROR,
169 ACE_TEXT ("Unable to get base to MMAP Memory Pool\n")));
170 alloc->remove();
171 delete alloc;
172 return -1;
175 // Check a base address mapping was added to the Repository
176 // when the pool was created
177 void* ba = 0;
178 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
180 ACE_ERROR((LM_ERROR, ACE_TEXT ("Unable to access repository\n")));
181 alloc->remove();
182 delete alloc;
183 return -1;
186 alloc->remove();
187 delete alloc;
189 if(ba != addr)
191 ACE_ERROR_RETURN ((LM_ERROR,
192 ACE_TEXT ("MMAP pool mapping not present\n")),
193 -1);
196 // Check Mapping is removed when object is deleted
197 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
199 ACE_ERROR_RETURN ((LM_ERROR,
200 ACE_TEXT ("Unable to access repository\n")),
201 -1);
203 if(ba != 0)
205 ACE_ERROR_RETURN ((LM_ERROR,
206 ACE_TEXT ("MMAP pool mapping not removed\n")),
207 -1);
210 return 0;
213 // Check that persistent MMAP memory blocks are correctly remapped
214 // into the Based_Pointer_Repository
215 // (i.e. maps based on backing stores that are already
216 // present in the filesystem)
217 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2216)
219 mmap_persistent_map_test(void)
221 MMAP_Allocator* alloc = 0;
223 // The 'options' are only here to quiet MSVC 6. It can be removed
224 // when MSVC 6 support is removed.
225 MMAP_Allocator::MEMORY_POOL_OPTIONS *options = 0;
226 ACE_OS::unlink("foo");
228 ACE_NEW_RETURN
229 (alloc,
230 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options),
231 -1);
232 alloc->sync();
234 // Delete Malloc and the memory pool, but do not remove
235 // the backing store
236 alloc->memory_pool().release(0);
237 delete alloc;
240 // Recreate segment with existing backing store
242 ACE_NEW_RETURN
243 (alloc,
244 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT("foo"), options),
245 -1);
247 void* addr = alloc->base_addr();
248 if(addr == 0)
250 ACE_ERROR ((LM_ERROR,
251 ACE_TEXT ("Unable to get base to persistent MMAP Memory Pool\n")));
252 alloc->remove();
253 delete alloc;
254 return -1;
256 void* ba = 0;
257 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
259 ACE_ERROR ((LM_ERROR,
260 ACE_TEXT ("Unable to find base address after map of persistent segment\n")));
261 alloc->remove();
262 delete alloc;
263 return -1;
265 if(ba == 0)
267 ACE_ERROR ((LM_ERROR,
268 ACE_TEXT ("Persistent MMAP Memory Pool not mapped\n")));
269 alloc->remove();
270 delete alloc;
271 return -1;
274 alloc->remove();
275 delete alloc;
276 return 0;
279 // Check that MMAP memory blocks are correctly remapped
280 // into the Based_Pointer_Repository
281 // (i.e. when a segment is resized it may move its base address
282 // because the OS cannot fit the new segment size at the same
283 // base address, in this case the Repository must be updated)
284 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2218)
286 mmap_remap_test(void)
288 // Use a Position Independent memory segment
289 // because this one is going to move
291 MMAP_Allocator *alloc[ 3 ]= {0, 0, 0};
292 void *pool_base[ 3 ]= {0, 0, 0};
294 // Make sure the Pool options are set to allow
295 // the segment to move
296 ACE_MMAP_Memory_Pool_Options data_opts(
298 ACE_MMAP_Memory_Pool_Options::NEVER_FIXED );
299 int i;
301 for (i= 0; i<3; ++i)
303 ACE_TCHAR store[ MAXPATHLEN + 1 ];
304 ACE_OS::snprintf( store, MAXPATHLEN + 1, ACE_TEXT("foo%d"), i );
305 ACE_OS::unlink( store );
307 ACE_NEW_RETURN (alloc[ i ],
308 MMAP_Allocator (store, store, &data_opts),
309 -1);
310 pool_base[ i ]= alloc[ i ]->base_addr();
313 // sort pools into base address order
314 for (i= 0; i<2; ++i)
316 if (pool_base[ i ] < pool_base[ i+1 ])
318 void *tmp1= pool_base[ i ];
319 MMAP_Allocator *tmp2= alloc[ i ];
320 pool_base[ i ]= pool_base[ i+1 ];
321 alloc[ i ]= alloc[ i+1 ];
322 pool_base[ i+1 ]= tmp1;
323 alloc[ i+1 ]= tmp2;
324 i= -1;
328 // alloc[1] is now bounded, whether memory grows up or
329 // down, it will hit either alloc[0] or alloc[2] and have
330 // to be remapped.
332 // Calculate maximum space between base addresses
334 size_t size= (char *) pool_base[ 0 ] - (char *) pool_base[ 1 ];
335 size_t tmpsize= (char *) pool_base[ 1 ] - (char *) pool_base[ 2 ];
336 size= (size < tmpsize) ? tmpsize : size;
338 // force pool to move
339 ++size;
341 (void)alloc[ 1 ]->malloc(size);
342 void *nba= alloc[ 1 ]->base_addr();
344 if (pool_base[ 1 ] == nba)
346 ACE_ERROR ((LM_ERROR,
347 ACE_TEXT ("MMAP Pool did not move base address as expected\n")));
348 for (i= 0; i<3; ++i)
350 alloc[ i ]->remove();
351 delete alloc[ i ];
353 return -1;
356 void *ba= 0;
357 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(nba, ba) == -1)
359 ACE_ERROR ((LM_ERROR,
360 ACE_TEXT ("Unable to find base address after remap of segment\n")));
361 for (i= 0; i<3; ++i)
363 alloc[ i ]->remove();
364 delete alloc[ i ];
366 return -1;
369 if (ba != nba)
371 ACE_ERROR ((LM_ERROR,
372 ACE_TEXT ("New base address not mapped after MMAP remap\n")));
373 for (i= 0; i<3; ++i)
375 alloc[ i ]->remove();
376 delete alloc[ i ];
378 return -1;
381 // Check old base address has been removed
382 // from the repository
383 if (ACE_BASED_POINTER_REPOSITORY::instance()->find( pool_base[ 1 ], ba ) == -1)
385 ACE_ERROR ((LM_ERROR,
386 ACE_TEXT ("Unable to find base address after remap of segment\n")));
387 for (i= 0; i<3; ++i)
389 alloc[ i ]->remove();
390 delete alloc[ i ];
392 return -1;
395 if (ba == pool_base[ 1 ])
397 ACE_ERROR ((LM_ERROR,
398 ACE_TEXT ("Old base address not removed after MMAP remap\n")));
399 for (i= 0; i<3; ++i)
401 alloc[ i ]->remove();
402 delete alloc[ i ];
404 return -1;
407 for (i= 0; i<3; ++i)
409 alloc[ i ]->remove();
410 delete alloc[ i ];
412 return 0;
417 run_main (int, ACE_TCHAR *[])
419 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
421 int retval = 0;
423 retval += singleton_test ();
424 retval += mmap_map_test();
425 retval += mmap_persistent_map_test();
426 retval += mmap_remap_test();
428 ACE_Based_Pointer_Basic<Foo> Foo_Ptr;
429 ACE_UNUSED_ARG (Foo_Ptr);
431 ACE_END_TEST;
432 return retval == 0 ? 0 : 1;
435 #else /* ! ACE_HAS_POSITION_INDEPENDENT_POINTERS */
436 // Nothing to test !
438 run_main (int, ACE_TCHAR *[])
440 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
441 ACE_Based_Pointer_Basic<Foo> Foo_Ptr;
442 ACE_UNUSED_ARG (Foo_Ptr);
443 ACE_END_TEST;
444 return 0;
446 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */