Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / Based_Pointer_Test.cpp
blob7b5f2ef37618e55c0a4eecc649e1d8f20c657fc8
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)
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 void* foo = dll.symbol (ACE_TEXT ("get_based_pointer_repository_instance"));
113 // Cast the void* to function* with a long as intermediate.
114 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
115 Get_Bp_Repository_Inst get_bp_repository_inst =
116 reinterpret_cast<Get_Bp_Repository_Inst> (tmp);
117 if (get_bp_repository_inst == 0)
118 ACE_ERROR_RETURN ((LM_ERROR,
119 ACE_TEXT ("%p\n"),
120 dll.error ()),
121 -1);
123 void* baddr_dll = get_bp_repository_inst ();
125 dll.close ();
127 if (baddr_dll != baddr1)
129 ACE_ERROR_RETURN ((LM_ERROR,
130 ACE_TEXT ("ACE_Based_Pointer_Repository is not a ")
131 ACE_TEXT ("singleton in DLL <%@> <%@>\n"),
132 baddr_dll,
133 baddr1),
134 -1);
136 #endif /* ACE_HAS_DYNAMIC_LINKING */
138 return 0;
141 // Check that MMAP memory blocks are correctly mapped
142 // into the Based_Pointer_Repository
144 mmap_map_test()
146 MMAP_Allocator* alloc = 0;
148 ACE_OS::unlink("foo");
150 // The 'options' are only here to quiet MSVC 6. It can be removed
151 // when MSVC 6 support is removed.
152 MMAP_Allocator::MEMORY_POOL_OPTIONS *options = 0;
153 ACE_NEW_RETURN
154 (alloc,
155 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options),
156 -1);
158 void* addr = alloc->base_addr();
159 if(addr == 0)
161 ACE_ERROR((LM_ERROR,
162 ACE_TEXT ("Unable to get base to MMAP Memory Pool\n")));
163 alloc->remove();
164 delete alloc;
165 return -1;
168 // Check a base address mapping was added to the Repository
169 // when the pool was created
170 void* ba = 0;
171 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
173 ACE_ERROR((LM_ERROR, ACE_TEXT ("Unable to access repository\n")));
174 alloc->remove();
175 delete alloc;
176 return -1;
179 alloc->remove();
180 delete alloc;
182 if(ba != addr)
184 ACE_ERROR_RETURN ((LM_ERROR,
185 ACE_TEXT ("MMAP pool mapping not present\n")),
186 -1);
189 // Check Mapping is removed when object is deleted
190 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
192 ACE_ERROR_RETURN ((LM_ERROR,
193 ACE_TEXT ("Unable to access repository\n")),
194 -1);
196 if(ba != 0)
198 ACE_ERROR_RETURN ((LM_ERROR,
199 ACE_TEXT ("MMAP pool mapping not removed\n")),
200 -1);
203 return 0;
206 // Check that persistent MMAP memory blocks are correctly remapped
207 // into the Based_Pointer_Repository
208 // (i.e. maps based on backing stores that are already
209 // present in the filesystem)
210 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2216)
212 mmap_persistent_map_test()
214 MMAP_Allocator* alloc = 0;
216 // The 'options' are only here to quiet MSVC 6. It can be removed
217 // when MSVC 6 support is removed.
218 MMAP_Allocator::MEMORY_POOL_OPTIONS *options = 0;
219 ACE_OS::unlink("foo");
221 ACE_NEW_RETURN
222 (alloc,
223 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options),
224 -1);
225 alloc->sync();
227 // Delete Malloc and the memory pool, but do not remove
228 // the backing store
229 alloc->memory_pool().release(0);
230 delete alloc;
233 // Recreate segment with existing backing store
235 ACE_NEW_RETURN
236 (alloc,
237 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT("foo"), options),
238 -1);
240 void* addr = alloc->base_addr();
241 if(addr == 0)
243 ACE_ERROR ((LM_ERROR,
244 ACE_TEXT ("Unable to get base to persistent MMAP Memory Pool\n")));
245 alloc->remove();
246 delete alloc;
247 return -1;
249 void* ba = 0;
250 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr, ba) == -1)
252 ACE_ERROR ((LM_ERROR,
253 ACE_TEXT ("Unable to find base address after map of persistent segment\n")));
254 alloc->remove();
255 delete alloc;
256 return -1;
258 if(ba == 0)
260 ACE_ERROR ((LM_ERROR,
261 ACE_TEXT ("Persistent MMAP Memory Pool not mapped\n")));
262 alloc->remove();
263 delete alloc;
264 return -1;
267 alloc->remove();
268 delete alloc;
269 return 0;
272 // Check that MMAP memory blocks are correctly remapped
273 // into the Based_Pointer_Repository
274 // (i.e. when a segment is resized it may move its base address
275 // because the OS cannot fit the new segment size at the same
276 // base address, in this case the Repository must be updated)
277 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2218)
279 mmap_remap_test()
281 // Use a Position Independent memory segment
282 // because this one is going to move
284 MMAP_Allocator *alloc[ 3 ]= {0, 0, 0};
285 void *pool_base[ 3 ]= {0, 0, 0};
287 // Make sure the Pool options are set to allow
288 // the segment to move
289 ACE_MMAP_Memory_Pool_Options data_opts(
291 ACE_MMAP_Memory_Pool_Options::NEVER_FIXED );
292 int i;
294 for (i= 0; i<3; ++i)
296 ACE_TCHAR store[ MAXPATHLEN + 1 ];
297 ACE_OS::snprintf( store, MAXPATHLEN + 1, ACE_TEXT("foo%d"), i );
298 ACE_OS::unlink( store );
300 ACE_NEW_RETURN (alloc[ i ],
301 MMAP_Allocator (store, store, &data_opts),
302 -1);
303 pool_base[ i ]= alloc[ i ]->base_addr();
306 // sort pools into base address order
307 for (i= 0; i<2; ++i)
309 if (pool_base[ i ] < pool_base[ i+1 ])
311 void *tmp1= pool_base[ i ];
312 MMAP_Allocator *tmp2= alloc[ i ];
313 pool_base[ i ]= pool_base[ i+1 ];
314 alloc[ i ]= alloc[ i+1 ];
315 pool_base[ i+1 ]= tmp1;
316 alloc[ i+1 ]= tmp2;
317 i= -1;
321 // alloc[1] is now bounded, whether memory grows up or
322 // down, it will hit either alloc[0] or alloc[2] and have
323 // to be remapped.
325 // Calculate maximum space between base addresses
327 size_t size= (char *) pool_base[ 0 ] - (char *) pool_base[ 1 ];
328 size_t tmpsize= (char *) pool_base[ 1 ] - (char *) pool_base[ 2 ];
329 size= (size < tmpsize) ? tmpsize : size;
331 // force pool to move
332 ++size;
334 (void)alloc[ 1 ]->malloc(size);
335 void *nba= alloc[ 1 ]->base_addr();
337 if (pool_base[ 1 ] == nba)
339 ACE_ERROR ((LM_ERROR,
340 ACE_TEXT ("MMAP Pool did not move base address as expected\n")));
341 for (i= 0; i<3; ++i)
343 alloc[ i ]->remove();
344 delete alloc[ i ];
346 return -1;
349 void *ba= 0;
350 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(nba, ba) == -1)
352 ACE_ERROR ((LM_ERROR,
353 ACE_TEXT ("Unable to find base address after remap of segment\n")));
354 for (i= 0; i<3; ++i)
356 alloc[ i ]->remove();
357 delete alloc[ i ];
359 return -1;
362 if (ba != nba)
364 ACE_ERROR ((LM_ERROR,
365 ACE_TEXT ("New base address not mapped after MMAP remap\n")));
366 for (i= 0; i<3; ++i)
368 alloc[ i ]->remove();
369 delete alloc[ i ];
371 return -1;
374 // Check old base address has been removed
375 // from the repository
376 if (ACE_BASED_POINTER_REPOSITORY::instance()->find( pool_base[ 1 ], ba ) == -1)
378 ACE_ERROR ((LM_ERROR,
379 ACE_TEXT ("Unable to find base address after remap of segment\n")));
380 for (i= 0; i<3; ++i)
382 alloc[ i ]->remove();
383 delete alloc[ i ];
385 return -1;
388 if (ba == pool_base[ 1 ])
390 ACE_ERROR ((LM_ERROR,
391 ACE_TEXT ("Old base address not removed after MMAP remap\n")));
392 for (i= 0; i<3; ++i)
394 alloc[ i ]->remove();
395 delete alloc[ i ];
397 return -1;
400 for (i= 0; i<3; ++i)
402 alloc[ i ]->remove();
403 delete alloc[ i ];
405 return 0;
410 run_main (int, ACE_TCHAR *[])
412 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
414 int retval = 0;
416 retval += singleton_test ();
417 retval += mmap_map_test();
418 retval += mmap_persistent_map_test();
419 retval += mmap_remap_test();
421 ACE_Based_Pointer_Basic<Foo> Foo_Ptr;
422 ACE_UNUSED_ARG (Foo_Ptr);
424 ACE_END_TEST;
425 return retval == 0 ? 0 : 1;
428 #else /* ! ACE_HAS_POSITION_INDEPENDENT_POINTERS */
429 // Nothing to test !
431 run_main (int, ACE_TCHAR *[])
433 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
434 ACE_Based_Pointer_Basic<Foo> Foo_Ptr;
435 ACE_UNUSED_ARG (Foo_Ptr);
436 ACE_END_TEST;
437 return 0;
439 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */