Also use Objects as part of an operation but as a result don't generate Any operation...
[ACE_TAO.git] / ACE / tests / SV_Shared_Memory_Test.cpp
blobff0b2dc2d3ce103c5cf40498585d93ec3a32a16f
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"
28 #if defined (ACE_HAS_SYSV_IPC) && !defined(ACE_LACKS_SYSV_SHMEM)
30 // The shared memory allocator, which uses up the ACE_DEFAULT_SEM_KEY.
31 // We hide the allocator inside this function so that it doesn't get
32 // constructed until after the ACE_Object_Manager gets constructed,
33 // even with ACE_HAS_NONSTATIC_OBJECT_MANAGER.
35 static
36 ACE_Malloc<ACE_SHARED_MEMORY_POOL, ACE_SV_Semaphore_Simple> &
37 myallocator (void)
39 static ACE_Malloc<ACE_SHARED_MEMORY_POOL,
40 ACE_SV_Semaphore_Simple> myallocator;
41 return myallocator;
44 // Create some more keys that are different from the
45 // ACE_DEFAULT_SEM_KEY used by the allocator.
46 static const int SEM_KEY_1 = ACE_DEFAULT_SEM_KEY + 1;
47 static const int SEM_KEY_2 = ACE_DEFAULT_SEM_KEY + 2;
49 static const int SHMSZ = 27;
50 static const char SHMDATA[SHMSZ] = "abcdefghijklmnopqrstuvwxyz";
52 static ACE_SV_Semaphore_Complex *parent_mutex = 0;
53 static ACE_SV_Semaphore_Complex *parent_synch = 0;
55 static int
56 parent (char *shm)
58 // This for loop executes in a critical section proteced by
59 // <parent_mutex>.
60 for (int i = 0; i < SHMSZ; i++)
61 shm[i] = SHMDATA[i];
63 int result;
64 result = parent_mutex->release ();
65 ACE_TEST_ASSERT (result != -1);
67 result = parent_synch->acquire ();
68 ACE_TEST_ASSERT (result != -1);
70 result = myallocator ().remove ();
71 ACE_TEST_ASSERT (result != -1);
73 result = parent_mutex->remove ();
74 ACE_TEST_ASSERT (result != -1);
76 result = parent_synch->remove ();
77 ACE_TEST_ASSERT (result != -1);
79 return 0;
82 static int
83 child (char *shm)
85 int result;
87 ACE_SV_Semaphore_Complex mutex;
89 // This semaphore is initially created with a count of 0, i.e., it
90 // is "locked."
91 result = mutex.open (SEM_KEY_1,
92 ACE_SV_Semaphore_Complex::ACE_CREATE,
93 0);
94 ACE_TEST_ASSERT (result != -1);
96 ACE_SV_Semaphore_Complex synch;
97 // This semaphore is initially created with a count of 0, i.e., it
98 // is "locked."
99 result = synch.open (SEM_KEY_2,
100 ACE_SV_Semaphore_Complex::ACE_CREATE,
102 ACE_TEST_ASSERT (result != -1);
104 // Perform "busy waiting" here until we acquire the semaphore. This
105 // isn't really a good design -- it's just to illustrate that you
106 // can do non-blocking acquire() calls with the ACE System V
107 // semaphore wrappers.
108 while ((result = mutex.tryacquire ()) == -1)
109 if (errno == EAGAIN)
110 ACE_DEBUG ((LM_DEBUG,
111 ACE_TEXT ("(%P) spinning in child!\n")));
112 else
114 ACE_ERROR ((LM_ERROR,
115 ACE_TEXT ("(%P) child mutex.tryacquire")));
116 ACE_TEST_ASSERT (result != -1);
119 for (int i = 0; i < SHMSZ; i++)
120 ACE_TEST_ASSERT (SHMDATA[i] == shm[i]);
122 result = synch.release ();
123 ACE_TEST_ASSERT (result != -1);
125 return 0;
128 #endif /* ACE_HAS_SYSV_IPC */
130 run_main (int, ACE_TCHAR *[])
132 ACE_START_TEST (ACE_TEXT ("SV_Shared_Memory_Test"));
134 #if defined (ACE_HAS_SYSV_IPC) && !defined (ACE_LACKS_FORK) && \
135 !defined(ACE_LACKS_SYSV_SHMEM)
137 // Check whether allocator was initialized.
138 if (myallocator ().bad ())
140 ACE_ERROR_RETURN ((LM_ERROR,
141 ACE_TEXT ("Unable to initialize allocator\n")),
142 -1);
145 char *shm = reinterpret_cast<char *> (myallocator ().malloc (SHMSZ));
147 // Create the mutex and synch before spawning the child process, to
148 // avoid race condition between their creation in the parent and use
149 // in the child.
150 ACE_NEW_RETURN (parent_mutex,
151 ACE_SV_Semaphore_Complex,
152 -1);
153 ACE_NEW_RETURN (parent_synch,
154 ACE_SV_Semaphore_Complex,
155 -1);
157 // This semaphore is initially created with a count of 0, i.e., it
158 // is "locked."
159 int result = parent_mutex->open (SEM_KEY_1,
160 ACE_SV_Semaphore_Complex::ACE_CREATE,
162 ACE_TEST_ASSERT (result != -1);
164 // This semaphore is initially created with a count of 0, i.e., it
165 // is "locked."
166 result = parent_synch->open (SEM_KEY_2,
167 ACE_SV_Semaphore_Complex::ACE_CREATE,
169 ACE_TEST_ASSERT (result != -1);
171 switch (ACE_OS::fork (ACE_TEXT ("SV_Shared_Memory_Test.cpp")))
173 case -1:
174 ACE_ERROR_RETURN ((LM_ERROR,
175 ACE_TEXT ("(%P) fork failed\n")),
176 -1);
177 /* NOTREACHED */
178 case 0:
179 child (shm);
180 break;
181 default:
182 parent (shm);
183 delete parent_mutex;
184 delete parent_synch;
185 break;
187 #else
188 ACE_ERROR ((LM_INFO,
189 ACE_TEXT ("SYSV IPC, SYSV SHMEM, or fork ")
190 ACE_TEXT ("are not supported on this platform\n")));
191 #endif /* ACE_HAS_SYSV_IPC */
192 ACE_END_TEST;
193 return 0;