Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / SV_Shared_Memory_Test.cpp
blob4a5348574456db07973587215d67828152fcc7ff
2 //=============================================================================
3 /**
4 * @file SV_Shared_Memory_Test.cpp
6 * This is a simple test of <ACE_SV_Shared_Memory> and
7 * <ACE_Malloc> using the <ACE_Shared_Memory_Pool>. The test
8 * forks two processes and then executes client and server
9 * allowing them to exchange data using shared memory. No user
10 * input is required as far as command line arguments are
11 * concerned.
13 * @author Prashant Jain <pjain@cs.wustl.edu> and Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
15 //=============================================================================
18 #include "test_config.h"
19 #include "ace/Malloc_T.h"
20 #include "ace/Shared_Memory_Pool.h"
21 #include "ace/SV_Semaphore_Simple.h"
22 #include "ace/SV_Semaphore_Complex.h"
23 #include "ace/OS_NS_unistd.h"
25 #if defined (ACE_HAS_SYSV_IPC) && !defined(ACE_LACKS_SYSV_SHMEM)
27 // The shared memory allocator, which uses up the ACE_DEFAULT_SEM_KEY.
28 // We hide the allocator inside this function so that it doesn't get
29 // constructed until after the ACE_Object_Manager gets constructed,
30 // even with ACE_HAS_NONSTATIC_OBJECT_MANAGER.
31 static
32 ACE_Malloc<ACE_SHARED_MEMORY_POOL, ACE_SV_Semaphore_Simple> &
33 myallocator ()
35 static ACE_Malloc<ACE_SHARED_MEMORY_POOL,
36 ACE_SV_Semaphore_Simple> myallocator;
37 return myallocator;
40 // Create some more keys that are different from the
41 // ACE_DEFAULT_SEM_KEY used by the allocator.
42 static const int SEM_KEY_1 = ACE_DEFAULT_SEM_KEY + 1;
43 static const int SEM_KEY_2 = ACE_DEFAULT_SEM_KEY + 2;
45 static const int SHMSZ = 27;
46 static const char SHMDATA[SHMSZ] = "abcdefghijklmnopqrstuvwxyz";
48 static ACE_SV_Semaphore_Complex *parent_mutex = 0;
49 static ACE_SV_Semaphore_Complex *parent_synch = 0;
51 static int
52 parent (char *shm)
54 // This for loop executes in a critical section proteced by
55 // <parent_mutex>.
56 for (int i = 0; i < SHMSZ; i++)
57 shm[i] = SHMDATA[i];
59 int result;
60 result = parent_mutex->release ();
61 ACE_TEST_ASSERT (result != -1);
63 result = parent_synch->acquire ();
64 ACE_TEST_ASSERT (result != -1);
66 result = myallocator ().remove ();
67 ACE_TEST_ASSERT (result != -1);
69 result = parent_mutex->remove ();
70 ACE_TEST_ASSERT (result != -1);
72 result = parent_synch->remove ();
73 ACE_TEST_ASSERT (result != -1);
75 return 0;
78 static int
79 child (char *shm)
81 int result;
83 ACE_SV_Semaphore_Complex mutex;
85 // This semaphore is initially created with a count of 0, i.e., it
86 // is "locked."
87 result = mutex.open (SEM_KEY_1,
88 ACE_SV_Semaphore_Complex::ACE_CREATE,
89 0);
90 ACE_TEST_ASSERT (result != -1);
92 ACE_SV_Semaphore_Complex synch;
93 // This semaphore is initially created with a count of 0, i.e., it
94 // is "locked."
95 result = synch.open (SEM_KEY_2,
96 ACE_SV_Semaphore_Complex::ACE_CREATE,
97 0);
98 ACE_TEST_ASSERT (result != -1);
100 // Perform "busy waiting" here until we acquire the semaphore. This
101 // isn't really a good design -- it's just to illustrate that you
102 // can do non-blocking acquire() calls with the ACE System V
103 // semaphore wrappers.
104 while ((result = mutex.tryacquire ()) == -1)
105 if (errno == EAGAIN)
106 ACE_DEBUG ((LM_DEBUG,
107 ACE_TEXT ("(%P) spinning in child!\n")));
108 else
110 ACE_ERROR ((LM_ERROR,
111 ACE_TEXT ("(%P) child mutex.tryacquire")));
112 ACE_TEST_ASSERT (result != -1);
115 for (int i = 0; i < SHMSZ; i++)
116 ACE_TEST_ASSERT (SHMDATA[i] == shm[i]);
118 result = synch.release ();
119 ACE_TEST_ASSERT (result != -1);
121 return 0;
124 #endif /* ACE_HAS_SYSV_IPC */
126 run_main (int, ACE_TCHAR *[])
128 ACE_START_TEST (ACE_TEXT ("SV_Shared_Memory_Test"));
130 #if defined (ACE_HAS_SYSV_IPC) && !defined (ACE_LACKS_FORK) && \
131 !defined(ACE_LACKS_SYSV_SHMEM)
133 // Check whether allocator was initialized.
134 if (myallocator ().bad ())
136 ACE_ERROR_RETURN ((LM_ERROR,
137 ACE_TEXT ("Unable to initialize allocator\n")),
138 -1);
141 char *shm = reinterpret_cast<char *> (myallocator ().malloc (SHMSZ));
143 // Create the mutex and synch before spawning the child process, to
144 // avoid race condition between their creation in the parent and use
145 // in the child.
146 ACE_NEW_RETURN (parent_mutex,
147 ACE_SV_Semaphore_Complex,
148 -1);
149 ACE_NEW_RETURN (parent_synch,
150 ACE_SV_Semaphore_Complex,
151 -1);
153 // This semaphore is initially created with a count of 0, i.e., it
154 // is "locked."
155 int result = parent_mutex->open (SEM_KEY_1,
156 ACE_SV_Semaphore_Complex::ACE_CREATE,
158 ACE_TEST_ASSERT (result != -1);
160 // This semaphore is initially created with a count of 0, i.e., it
161 // is "locked."
162 result = parent_synch->open (SEM_KEY_2,
163 ACE_SV_Semaphore_Complex::ACE_CREATE,
165 ACE_TEST_ASSERT (result != -1);
167 switch (ACE_OS::fork (ACE_TEXT ("SV_Shared_Memory_Test.cpp")))
169 case -1:
170 ACE_ERROR_RETURN ((LM_ERROR,
171 ACE_TEXT ("(%P) fork failed\n")),
172 -1);
173 /* NOTREACHED */
174 case 0:
175 child (shm);
176 break;
177 default:
178 parent (shm);
179 delete parent_mutex;
180 delete parent_synch;
181 break;
183 #else
184 ACE_ERROR ((LM_INFO,
185 ACE_TEXT ("SYSV IPC, SYSV SHMEM, or fork ")
186 ACE_TEXT ("are not supported on this platform\n")));
187 #endif /* ACE_HAS_SYSV_IPC */
188 ACE_END_TEST;
189 return 0;