ACE+TAO-7_0_8
[ACE_TAO.git] / ACE / tests / Based_Pointer_Test.cpp
blob875bb70d188bc52d136a56693e0f6b87f4c9ce45
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 using Get_Bp_Repository_Inst = void *(*)();
61 // Declare an allocator based MMAP_Memory_Pool
62 using MMAP_Allocator = ACE_Malloc_T<ACE_MMAP_Memory_Pool, ACE_Null_Mutex, ACE_PI_Control_Block>;
65 // Check that the ACE_Based_Pointer_Repository can be accessed
66 // from a Windows DLL
67 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=1991)
68 int singleton_test ()
70 void* baddr1 = ACE_BASED_POINTER_REPOSITORY::instance();
71 void* baddr2 = ACE_BASED_POINTER_REPOSITORY::instance();
73 if (baddr1 != baddr2)
75 ACE_ERROR_RETURN ((LM_ERROR,
76 ACE_TEXT ("ACE_Based_Pointer_Repository is not a singleton\n")),
77 -1);
80 // Protection against this test being run on platforms not supporting Dlls.
81 #if defined(ACE_HAS_DYNAMIC_LINKING)
82 ACE_TString dll_file;
83 const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
84 if (subdir_env)
86 dll_file = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
87 dll_file += ACE_DIRECTORY_SEPARATOR_STR;
90 dll_file += OBJ_PREFIX ACE_TEXT ("Based_Pointer_Test_Lib") OBJ_SUFFIX;
92 // If DLL causes multiple instances of singleton
93 // then the ACE_Cleanup object registered
94 // with the ACE_Object_manager will no longer be valid,
95 // at exit time if the library is unloaded. Override
96 // the default close on destruct.
97 ACE_DLL dll;
98 int retval = dll.open (dll_file.c_str (),
99 ACE_DEFAULT_SHLIB_MODE,
102 if (retval != 0)
104 ACE_TCHAR *dll_error = dll.error ();
105 ACE_ERROR_RETURN ((LM_ERROR,
106 ACE_TEXT ("Error in DLL Open: %s\n"),
107 dll_error ? dll_error : ACE_TEXT ("unknown error")),
108 -1);
111 #if defined (ACE_OPENVMS)
112 // with OPENVMS symbol names > 31 cause us trouble with dlsym()
113 void* foo = dll.symbol (ACE_TEXT ("get_based_pointer_repo_inst"));
114 #else
115 void* foo = dll.symbol (ACE_TEXT ("get_based_pointer_repository_instance"));
116 #endif
118 // Cast the void* to function* with a long as intermediate.
119 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
120 Get_Bp_Repository_Inst get_bp_repository_inst =
121 reinterpret_cast<Get_Bp_Repository_Inst> (tmp);
122 if (get_bp_repository_inst == 0)
123 ACE_ERROR_RETURN ((LM_ERROR,
124 ACE_TEXT ("%p\n"),
125 dll.error ()),
126 -1);
128 void* baddr_dll = get_bp_repository_inst ();
130 dll.close ();
132 if (baddr_dll != baddr1)
134 ACE_ERROR_RETURN ((LM_ERROR,
135 ACE_TEXT ("ACE_Based_Pointer_Repository is not a ")
136 ACE_TEXT ("singleton in DLL <%@> <%@>\n"),
137 baddr_dll,
138 baddr1),
139 -1);
141 #endif /* ACE_HAS_DYNAMIC_LINKING */
143 return 0;
146 // Check that MMAP memory blocks are correctly mapped
147 // into the Based_Pointer_Repository
149 mmap_map_test()
151 MMAP_Allocator* alloc = 0;
153 ACE_OS::unlink("foo");
155 // The 'options' are only here to quiet MSVC 6. It can be removed
156 // when MSVC 6 support is removed.
157 MMAP_Allocator::MEMORY_POOL_OPTIONS *options = 0;
158 ACE_NEW_RETURN
159 (alloc,
160 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options),
161 -1);
163 void* addr = alloc->base_addr();
164 if(addr == 0)
166 ACE_ERROR((LM_ERROR,
167 ACE_TEXT ("Unable to get base to MMAP Memory Pool\n")));
168 alloc->remove();
169 delete alloc;
170 return -1;
173 // Check a base address mapping was added to the Repository
174 // when the pool was created
175 void* ba = 0;
176 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
178 ACE_ERROR((LM_ERROR, ACE_TEXT ("Unable to access repository\n")));
179 alloc->remove();
180 delete alloc;
181 return -1;
184 alloc->remove();
185 delete alloc;
187 if(ba != addr)
189 ACE_ERROR_RETURN ((LM_ERROR,
190 ACE_TEXT ("MMAP pool mapping not present\n")),
191 -1);
194 // Check Mapping is removed when object is deleted
195 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
197 ACE_ERROR_RETURN ((LM_ERROR,
198 ACE_TEXT ("Unable to access repository\n")),
199 -1);
201 if(ba != 0)
203 ACE_ERROR_RETURN ((LM_ERROR,
204 ACE_TEXT ("MMAP pool mapping not removed\n")),
205 -1);
208 return 0;
211 // Check that persistent MMAP memory blocks are correctly remapped
212 // into the Based_Pointer_Repository
213 // (i.e. maps based on backing stores that are already
214 // present in the filesystem)
215 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2216)
217 mmap_persistent_map_test()
219 MMAP_Allocator* alloc = 0;
221 // The 'options' are only here to quiet MSVC 6. It can be removed
222 // when MSVC 6 support is removed.
223 MMAP_Allocator::MEMORY_POOL_OPTIONS *options = 0;
224 ACE_OS::unlink("foo");
226 ACE_NEW_RETURN
227 (alloc,
228 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options),
229 -1);
230 alloc->sync();
232 // Delete Malloc and the memory pool, but do not remove
233 // the backing store
234 alloc->memory_pool().release(0);
235 delete alloc;
238 // Recreate segment with existing backing store
240 ACE_NEW_RETURN
241 (alloc,
242 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT("foo"), options),
243 -1);
245 void* addr = alloc->base_addr();
246 if(addr == 0)
248 ACE_ERROR ((LM_ERROR,
249 ACE_TEXT ("Unable to get base to persistent MMAP Memory Pool\n")));
250 alloc->remove();
251 delete alloc;
252 return -1;
254 void* ba = 0;
255 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
257 ACE_ERROR ((LM_ERROR,
258 ACE_TEXT ("Unable to find base address after map of persistent segment\n")));
259 alloc->remove();
260 delete alloc;
261 return -1;
263 if(ba == 0)
265 ACE_ERROR ((LM_ERROR,
266 ACE_TEXT ("Persistent MMAP Memory Pool not mapped\n")));
267 alloc->remove();
268 delete alloc;
269 return -1;
272 alloc->remove();
273 delete alloc;
274 return 0;
277 // Check that MMAP memory blocks are correctly remapped
278 // into the Based_Pointer_Repository
279 // (i.e. when a segment is resized it may move its base address
280 // because the OS cannot fit the new segment size at the same
281 // base address, in this case the Repository must be updated)
282 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2218)
284 mmap_remap_test()
286 // Use a Position Independent memory segment
287 // because this one is going to move
289 MMAP_Allocator *alloc[ 3 ]= {0, 0, 0};
290 void *pool_base[ 3 ]= {0, 0, 0};
292 // Make sure the Pool options are set to allow
293 // the segment to move
294 ACE_MMAP_Memory_Pool_Options data_opts(
296 ACE_MMAP_Memory_Pool_Options::NEVER_FIXED );
297 int i;
299 for (i= 0; i<3; ++i)
301 ACE_TCHAR store[ MAXPATHLEN + 1 ];
302 ACE_OS::snprintf( store, MAXPATHLEN + 1, ACE_TEXT("foo%d"), i );
303 ACE_OS::unlink( store );
305 ACE_NEW_RETURN (alloc[ i ],
306 MMAP_Allocator (store, store, &data_opts),
307 -1);
308 pool_base[ i ]= alloc[ i ]->base_addr();
311 // sort pools into base address order
312 for (i= 0; i<2; ++i)
314 if (pool_base[ i ] < pool_base[ i+1 ])
316 void *tmp1= pool_base[ i ];
317 MMAP_Allocator *tmp2= alloc[ i ];
318 pool_base[ i ]= pool_base[ i+1 ];
319 alloc[ i ]= alloc[ i+1 ];
320 pool_base[ i+1 ]= tmp1;
321 alloc[ i+1 ]= tmp2;
322 i= -1;
326 // alloc[1] is now bounded, whether memory grows up or
327 // down, it will hit either alloc[0] or alloc[2] and have
328 // to be remapped.
330 // Calculate maximum space between base addresses
332 size_t size= (char *) pool_base[ 0 ] - (char *) pool_base[ 1 ];
333 size_t tmpsize= (char *) pool_base[ 1 ] - (char *) pool_base[ 2 ];
334 size= (size < tmpsize) ? tmpsize : size;
336 // force pool to move
337 ++size;
339 (void)alloc[ 1 ]->malloc(size);
340 void *nba= alloc[ 1 ]->base_addr();
342 if (pool_base[ 1 ] == nba)
344 ACE_ERROR ((LM_ERROR,
345 ACE_TEXT ("MMAP Pool did not move base address as expected\n")));
346 for (i= 0; i<3; ++i)
348 alloc[ i ]->remove();
349 delete alloc[ i ];
351 return -1;
354 void *ba= 0;
355 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(nba, ba) == -1)
357 ACE_ERROR ((LM_ERROR,
358 ACE_TEXT ("Unable to find base address after remap of segment\n")));
359 for (i= 0; i<3; ++i)
361 alloc[ i ]->remove();
362 delete alloc[ i ];
364 return -1;
367 if (ba != nba)
369 ACE_ERROR ((LM_ERROR,
370 ACE_TEXT ("New base address not mapped after MMAP remap\n")));
371 for (i= 0; i<3; ++i)
373 alloc[ i ]->remove();
374 delete alloc[ i ];
376 return -1;
379 // Check old base address has been removed
380 // from the repository
381 if (ACE_BASED_POINTER_REPOSITORY::instance()->find( pool_base[ 1 ], ba ) == -1)
383 ACE_ERROR ((LM_ERROR,
384 ACE_TEXT ("Unable to find base address after remap of segment\n")));
385 for (i= 0; i<3; ++i)
387 alloc[ i ]->remove();
388 delete alloc[ i ];
390 return -1;
393 if (ba == pool_base[ 1 ])
395 ACE_ERROR ((LM_ERROR,
396 ACE_TEXT ("Old base address not removed after MMAP remap\n")));
397 for (i= 0; i<3; ++i)
399 alloc[ i ]->remove();
400 delete alloc[ i ];
402 return -1;
405 for (i= 0; i<3; ++i)
407 alloc[ i ]->remove();
408 delete alloc[ i ];
410 return 0;
415 run_main (int, ACE_TCHAR *[])
417 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
419 int retval = 0;
421 retval += singleton_test ();
422 retval += mmap_map_test();
423 retval += mmap_persistent_map_test();
424 retval += mmap_remap_test();
426 ACE_Based_Pointer_Basic<Foo> Foo_Ptr;
427 ACE_UNUSED_ARG (Foo_Ptr);
429 ACE_END_TEST;
430 return retval == 0 ? 0 : 1;
433 #else /* ! ACE_HAS_POSITION_INDEPENDENT_POINTERS */
434 // Nothing to test !
436 run_main (int, ACE_TCHAR *[])
438 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
439 ACE_Based_Pointer_Basic<Foo> Foo_Ptr;
440 ACE_UNUSED_ARG (Foo_Ptr);
441 ACE_END_TEST;
442 return 0;
444 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */