Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / tests / FIFO_Test.cpp
blob7a2648516c6d70d7fa4ce5e0d653e144f232e995
2 //=============================================================================
3 /**
4 * @file FIFO_Test.cpp
6 * This is a test of basic ACE_FIFO_* class functionality.
7 * The test forks two processes or spawns two threads (depending
8 * upon the platform) and then tests various data exchange
9 * scenarios.
11 * @author Steve Huston <shuston@riverace.com>
13 //=============================================================================
15 #include "test_config.h"
16 #include "ace/OS_NS_string.h"
17 #include "ace/OS_NS_sys_stat.h"
18 #include "ace/OS_NS_sys_wait.h"
19 #include "ace/OS_NS_unistd.h"
20 #include "ace/ACE.h"
21 #include "ace/FIFO_Send_Msg.h"
22 #include "ace/FIFO_Recv_Msg.h"
23 #include "ace/Handle_Set.h"
24 #include "ace/Lib_Find.h"
25 #include "ace/Thread.h"
26 #include "ace/Thread_Manager.h"
28 #if !defined (ACE_LACKS_MKFIFO)
30 static const char ACE_ALPHABET[] = "abcdefghijklmnopqrstuvwxyz";
32 // This length is used for the "big buffer" send/receive.
33 static const size_t big_size = (BUFSIZ * 4);
35 static void *
36 client (void *arg)
38 ACE_TCHAR *fifo_path = reinterpret_cast <ACE_TCHAR *> (arg);
39 ACE_FIFO_Send_Msg fifo;
40 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) client opening %s\n"), fifo_path));
41 if (fifo.open (fifo_path) == -1)
42 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), fifo_path), 0);
44 // Try some transfers - the server part is expecting this data.
45 // First, try a nice, easy send.
46 ssize_t send_count;
47 ssize_t expect = static_cast <ssize_t> (ACE_OS::strlen (ACE_ALPHABET));
48 send_count = fifo.send (ACE_ALPHABET, ACE_OS::strlen (ACE_ALPHABET));
49 if (send_count == expect)
51 // Ok, so far so good. Now try one that will overflow the reader
52 // side to be sure it properly tosses the overflow. Then send another
53 // to be sure it finds the start of the next message ok.
54 char big[big_size];
55 for (size_t i = 0; i < big_size; ++i)
56 big[i] = (i % 2) ? 0x05 : 0x0A; // Make nice pattern in blown stack
57 expect = static_cast <ssize_t> (big_size);
58 send_count = fifo.send (big, big_size);
59 if (send_count == expect)
61 expect = static_cast <ssize_t> (ACE_OS::strlen (ACE_ALPHABET));
62 send_count = fifo.send (ACE_ALPHABET, ACE_OS::strlen (ACE_ALPHABET));
63 if (send_count != expect)
64 ACE_ERROR ((LM_ERROR,
65 ACE_TEXT ("(%P|%t) Final send; sent %d, expected %d")
66 ACE_TEXT ("%p\n"),
67 send_count, expect, ACE_TEXT ("send")));
68 else
69 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) All sends ok\n")));
71 else
73 ACE_ERROR
74 ((LM_ERROR,
75 ACE_TEXT ("(%P|%t) Second send expected %d; sent %d. %p\n"),
76 expect, send_count, ACE_TEXT ("send")));
79 else
81 ACE_ERROR ((LM_ERROR,
82 ACE_TEXT ("(%P|%t) First send expected %d; sent %d. %p\n"),
83 expect, send_count, ACE_TEXT ("send")));
86 if (fifo.close () != 0)
87 ACE_ERROR ((LM_ERROR, ACE_TEXT ("(%P|%t) %p\n"), ACE_TEXT ("fifo close")));
89 return 0;
92 static void *
93 server (void *arg)
95 ACE_FIFO_Recv_Msg *fifo = reinterpret_cast <ACE_FIFO_Recv_Msg *> (arg);
97 // Wait for the client to get going and open the FIFO.
98 errno = 0;
99 ACE_Handle_Set h;
100 ACE_Time_Value delay (10);
101 h.set_bit (fifo->get_handle ());
102 if (ACE::select (h.max_set () + 1, h, &delay) == -1)
103 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%P|%t) server %p\n"),
104 ACE_TEXT ("select")),
107 // Read the things the client is sending; alphabet, huge overflow, then
108 // alphabet.
109 char buf[BUFSIZ];
110 ssize_t recv_count;
111 ssize_t expect = static_cast <ssize_t> (ACE_OS::strlen (ACE_ALPHABET));
112 recv_count = fifo->recv (buf, sizeof (buf));
113 if (recv_count != expect)
114 ACE_ERROR_RETURN ((LM_ERROR,
115 ACE_TEXT ("(%P|%t) Recv 1 expected %d, got %d. %p\n"),
116 expect, recv_count, ACE_TEXT ("recv")),
118 buf[recv_count] = '\0';
119 if (ACE_OS::strcmp (buf, ACE_ALPHABET) != 0)
120 ACE_ERROR ((LM_ERROR,
121 ACE_TEXT ("(%P|%t) Recv 1 expected alphabet; got %s\n"),
122 buf));
124 // See documented return values for ACE_FIFO_Recv_Msg...
125 // We are being sent a message much longer than BUFSIZ.
126 // If this platform has STREAM pipes, the entire message will come
127 // through and we can grab it all. If not, then ACE_FIFO_Recv_Msg ditches
128 // the part of the message we don't read. This is rather a pain in the
129 // neck, but the API doesn't return info that more data is in the message
130 // (for STREAM pipes). When non-ACE_HAS_STREAM_PIPES discards data, the
131 // returned length will be larger than requested, though only the requested
132 // number of bytes are written to the buffer.
133 #if defined (ACE_HAS_STREAM_PIPES)
134 for (size_t remaining = big_size;
135 remaining > 0;
136 remaining -= recv_count)
138 #endif /* ACE_HAS_STREAM_PIPES */
140 // recv_count is sizeof(buf) on ACE_HAS_STREAM_PIPES; big_size on others.
141 #if defined (ACE_HAS_STREAM_PIPES)
142 expect = static_cast <ssize_t> (sizeof (buf));
143 #else
144 expect = static_cast <ssize_t> (big_size);
145 #endif /* ACE_HAS_STREAM_PIPES */
146 recv_count = fifo->recv (buf, sizeof (buf));
147 if (recv_count != expect)
148 ACE_ERROR_RETURN ((LM_ERROR,
149 ACE_TEXT ("(%P|%t) Recv 2 expected %d, ")
150 ACE_TEXT ("got %d. %p\n"),
151 expect, recv_count, ACE_TEXT ("recv")),
153 #if defined (ACE_HAS_STREAM_PIPES)
155 #endif /* ACE_HAS_STREAM_PIPES */
157 expect = static_cast <ssize_t> (ACE_OS::strlen (ACE_ALPHABET));
158 recv_count = fifo->recv (buf, sizeof (buf));
159 if (recv_count != expect)
160 ACE_ERROR_RETURN ((LM_ERROR,
161 ACE_TEXT ("(%P|%t) Recv 3 expected %d, got %d. %p\n"),
162 expect, recv_count, ACE_TEXT ("recv")),
164 buf[recv_count] = '\0';
165 if (ACE_OS::strcmp (buf, ACE_ALPHABET) != 0)
166 ACE_ERROR ((LM_ERROR,
167 ACE_TEXT ("(%P|%t) Recv 3 expected alphabet; got %s\n"),
168 buf));
169 else
170 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%P|%t) All receives ok\n")));
171 return 0;
174 static int
175 test_fifo_msg ()
177 // Reader side opens first - it may fail if fifo not supported on this
178 // platform.
179 ACE_TCHAR fifo_path[MAXPATHLEN];
180 if (ACE::get_temp_dir (fifo_path, MAXPATHLEN) == -1)
181 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
182 ACE_TEXT ("get_temp_dir")), 1);
183 ACE_OS::strcat (fifo_path, ACE_TEXT ("FIFO_Test"));
184 ACE_FIFO_Recv_Msg read_side;
185 // Open read only, not persistent (4th arg is 0)
186 if (-1 == read_side.open (fifo_path,
187 O_CREAT | O_RDONLY,
188 ACE_DEFAULT_FILE_PERMS,
191 #if defined (ACE_WIN32)
192 if (errno == ENOTSUP)
194 ACE_DEBUG ((LM_DEBUG,
195 ACE_TEXT ("FIFO not supported on Win32; ")
196 ACE_TEXT ("this is correct.\n")));
197 return 0;
199 #endif /* ACE_WIN32 */
200 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"),
201 ACE_TEXT ("ACE_FIFO_Recv_Msg::open")),
205 // Ok, the FIFO opened clean for read. Now it's safe to spawn a
206 // process/thread and test some transfers.
208 int status = 0; // Test status; innocent until proven guilty.
210 #if !defined (ACE_LACKS_FORK)
211 switch (ACE_OS::fork (ACE_TEXT ("child")))
213 case -1:
214 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("fork failed")));
215 status = 1;
216 break;
217 case 0:
218 client (fifo_path);
219 ACE_OS::exit (0);
220 /* NOTREACHED */
221 default:
222 server (&read_side);
223 ACE_OS::wait ();
225 #elif defined (ACE_HAS_THREADS)
226 if (ACE_Thread_Manager::instance ()->spawn
227 (ACE_THR_FUNC (server),
228 &read_side,
229 THR_NEW_LWP | THR_DETACHED) == -1)
231 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("server spawn")));
232 ++status;
235 if (ACE_Thread_Manager::instance ()->spawn
236 (ACE_THR_FUNC (client),
237 fifo_path,
238 THR_NEW_LWP | THR_DETACHED) == -1)
240 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("client spawn")));
241 ++status;
244 // Wait for the threads to exit.
245 ACE_Thread_Manager::instance ()->wait ();
246 #else
247 ACE_ERROR ((LM_INFO,
248 ACE_TEXT ("This test requires multiple threads ")
249 ACE_TEXT ("or processes.\n")));
250 #endif /* ACE_HAS_THREADS */
252 if (read_side.remove () != 0)
254 ACE_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("fifo remove")));
255 ++status;
258 ACE_stat fifo_stat;
259 if (ACE_OS::stat (fifo_path, &fifo_stat) == 0)
261 ACE_ERROR ((LM_ERROR, ACE_TEXT ("FIFO %s should be gone but isn't\n"),
262 fifo_path));
263 ++status;
264 ACE_OS::unlink (fifo_path); // Try to get rid of it.
267 return status;
271 run_main (int, ACE_TCHAR *[])
273 ACE_START_TEST (ACE_TEXT ("FIFO_Test"));
275 int errors = 0;
276 errors += test_fifo_msg ();
278 ACE_END_TEST;
279 return errors;
282 #else
285 run_main (int, ACE_TCHAR *[])
287 ACE_START_TEST (ACE_TEXT ("FIFO_Test"));
289 ACE_ERROR ((LM_INFO, ACE_TEXT ("FIFOs are not supported on this platform\n")));
291 ACE_END_TEST;
292 return 0;
295 #endif /* !ACE_LACKS_MKFIFO */