Merge pull request #2216 from jwillemsen/jwi-cxxversionchecks
[ACE_TAO.git] / ACE / examples / IPC_SAP / SSL_SAP / SSL-server-poll.cpp
blobf4094eaf5cd4c2b4907da69b2deca5632a8e4e6d
1 // IPC_SAP/poll server, which illustrates how to integrate the ACE
2 // SSL socket wrappers with the SVR4 <poll> system call to create a
3 // single-threaded concurrent server. This server program can be
4 // driven by the oneway test mode of SSL-client.cpp.
6 #include "ace/OS_NS_stdlib.h"
7 #include "ace/OS_NS_unistd.h"
8 #include "ace/Time_Value.h"
9 #include "ace/SSL/SSL_SOCK_Acceptor.h"
11 #if defined (ACE_HAS_POLL)
13 #include "ace/SSL/SSL_SOCK_Stream.h"
15 #include "ace/Log_Msg.h"
16 #include "ace/INET_Addr.h"
17 #include "ace/OS_NS_stdio.h"
18 #include "ace/OS_NS_poll.h"
21 // Should we be verbose?
22 static int verbose = 0;
24 // Max number of open handles.
25 static const int MAX_HANDLES = 200;
27 struct Buffer_Info
29 void *buf_;
30 // Pointer to the buffer.
32 size_t len_;
33 // Length of the buffer.
36 // Array of <pollfd>'s.
37 static struct pollfd poll_array[MAX_HANDLES];
39 // Array of <Buffer_Info>.
40 static Buffer_Info buffer_array[MAX_HANDLES];
42 static void
43 init_poll_array ()
45 int i;
47 for (i = 0; i < MAX_HANDLES; i++)
49 poll_array[i].fd = ACE_INVALID_HANDLE;
50 poll_array[i].events = POLLIN;
54 static int
55 init_buffer (size_t index)
57 ACE_INT32 len;
59 if (ACE::recv_n (poll_array[index].fd,
60 (void *) &len,
61 sizeof (ACE_INT32)) != sizeof (ACE_INT32))
62 ACE_ERROR_RETURN ((LM_ERROR,
63 "(%P|%t) %p\n",
64 "recv_n failed"),
65 -1);
66 else
68 len = ntohl (len);
69 ACE_DEBUG ((LM_DEBUG,
70 "(%P|%t) reading messages of size %d from handle %d\n",
71 len,
72 poll_array[index].fd));
74 ACE_ALLOCATOR_RETURN (buffer_array[index].buf_,
75 ACE_OS::malloc (len),
76 -1);
77 buffer_array[index].len_ = len;
79 return 0;
82 static void
83 handle_data (size_t &n_handles)
85 // Handle pending logging messages first (s_handle + 1 is guaranteed
86 // to be lowest client descriptor).
88 for (size_t index = 1; index < n_handles; index++)
90 if (ACE_BIT_ENABLED (poll_array[index].revents, POLLIN))
92 // First time in, we need to initialize the buffer.
93 if (buffer_array[index].buf_ == 0
94 && init_buffer (index) == -1)
96 ACE_ERROR ((LM_ERROR,
97 "(%P|%t) %p\n",
98 "init_buffer"));
99 continue;
102 // Read data from client (terminate on error).
104 ssize_t n = ACE::recv (poll_array[index].fd,
105 buffer_array[index].buf_,
106 buffer_array[index].len_);
107 // <recv> will not block in this case!
109 if (n == -1)
110 ACE_ERROR ((LM_ERROR,
111 "%p\n",
112 "read failed"));
113 else if (n == 0)
115 ACE_DEBUG ((LM_DEBUG,
116 "(%P|%t) closing oneway server at handle %d\n",
117 poll_array[index].fd));
119 // Handle client connection shutdown.
120 ACE_OS::close (poll_array[index].fd);
121 poll_array[index].fd = poll_array[--n_handles].fd;
123 ACE_OS::free ((void *) buffer_array[index].buf_);
124 buffer_array[index].buf_ = 0;
125 buffer_array[index].len_ = 0;
127 else if (verbose)
128 ACE_DEBUG ((LM_DEBUG,
129 "(%P|%t) %*s",
131 buffer_array[index].buf_));
136 static void
137 handle_connections (ACE_SSL_SOCK_Acceptor &peer_acceptor,
138 size_t &n_handles)
140 if (ACE_BIT_ENABLED (poll_array[0].revents, POLLIN))
142 ACE_SSL_SOCK_Stream new_stream;
144 ACE_INET_Addr client;
145 ACE_Time_Value nonblock (0, 0);
147 // Handle all pending connection requests (note use of "polling"
148 // feature that doesn't block).
150 while (ACE_OS::poll (poll_array, 1, nonblock) > 0)
151 if (peer_acceptor.accept (new_stream, &client) == -1)
152 ACE_OS::perror ("accept");
153 else
155 const char *s = client.get_host_name ();
157 ACE_ASSERT (s != 0);
158 ACE_DEBUG ((LM_DEBUG,
159 "(%P|%t) client %s\n",
160 s));
161 poll_array[n_handles++].fd = new_stream.get_handle ();
167 ACE_TMAIN (int, ACE_TCHAR *[])
169 u_short port = ACE_DEFAULT_SERVER_PORT + 1;
171 // Create a server end-point.
172 ACE_INET_Addr addr (port);
173 ACE_SSL_SOCK_Acceptor peer_acceptor (addr);
175 ACE_HANDLE s_handle = peer_acceptor.get_handle ();
177 init_poll_array ();
179 poll_array[0].fd = s_handle;
181 ACE_DEBUG ((LM_DEBUG,
182 "(%P|%t) starting oneway server at port %d\n",
183 port));
185 for (size_t n_handles = 1;;)
187 // Wait for client I/O events (handle interrupts).
188 while (ACE_OS::poll (poll_array, n_handles) == -1
189 && errno == EINTR)
190 continue;
192 handle_data (n_handles);
193 handle_connections (peer_acceptor, n_handles);
196 /* NOTREACHED */
197 return 0;
199 #else
200 #include "ace/OS_NS_stdio.h"
201 int ACE_TMAIN (int, ACE_TCHAR *[])
203 ACE_OS::fprintf (stderr, "This feature is not supported\n");
204 return 0;
206 #endif /* ACE_HAS_POLL */