summaryrefslogtreecommitdiff
path: root/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp')
-rw-r--r--ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp
new file mode 100644
index 00000000000..f3388d2e0f1
--- /dev/null
+++ b/ACE/examples/IPC_SAP/SSL_SAP/SSL-server-poll.cpp
@@ -0,0 +1,208 @@
+// $Id$
+
+// IPC_SAP/poll server, which illustrates how to integrate the ACE
+// SSL socket wrappers with the SVR4 <poll> system call to create a
+// single-threaded concurrent server. This server program can be
+// driven by the oneway test mode of SSL-client.cpp.
+
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_unistd.h"
+#include "ace/Time_Value.h"
+#include "ace/SSL/SSL_SOCK_Acceptor.h"
+
+#if defined (ACE_HAS_POLL)
+
+#include "ace/SSL/SSL_SOCK_Stream.h"
+
+#include "ace/Log_Msg.h"
+#include "ace/INET_Addr.h"
+#include "ace/OS_NS_stdio.h"
+#include "ace/OS_NS_poll.h"
+
+
+// Should we be verbose?
+static int verbose = 0;
+
+// Max number of open handles.
+static const int MAX_HANDLES = 200;
+
+struct Buffer_Info
+{
+ void *buf_;
+ // Pointer to the buffer.
+
+ size_t len_;
+ // Length of the buffer.
+};
+
+// Array of <pollfd>'s.
+static struct pollfd poll_array[MAX_HANDLES];
+
+// Array of <Buffer_Info>.
+static Buffer_Info buffer_array[MAX_HANDLES];
+
+static void
+init_poll_array (void)
+{
+ int i;
+
+ for (i = 0; i < MAX_HANDLES; i++)
+ {
+ poll_array[i].fd = ACE_INVALID_HANDLE;
+ poll_array[i].events = POLLIN;
+ }
+}
+
+static int
+init_buffer (size_t index)
+{
+ ACE_INT32 len;
+
+ if (ACE::recv_n (poll_array[index].fd,
+ (void *) &len,
+ sizeof (ACE_INT32)) != sizeof (ACE_INT32))
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "recv_n failed"),
+ -1);
+ else
+ {
+ len = ntohl (len);
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) reading messages of size %d from handle %d\n",
+ len,
+ poll_array[index].fd));
+
+ ACE_ALLOCATOR_RETURN (buffer_array[index].buf_,
+ ACE_OS::malloc (len),
+ -1);
+ buffer_array[index].len_ = len;
+ }
+ return 0;
+}
+
+static void
+handle_data (size_t &n_handles)
+{
+ // Handle pending logging messages first (s_handle + 1 is guaranteed
+ // to be lowest client descriptor).
+
+ for (size_t index = 1; index < n_handles; index++)
+ {
+ if (ACE_BIT_ENABLED (poll_array[index].revents, POLLIN))
+ {
+ // First time in, we need to initialize the buffer.
+ if (buffer_array[index].buf_ == 0
+ && init_buffer (index) == -1)
+ {
+ ACE_ERROR ((LM_ERROR,
+ "(%P|%t) %p\n",
+ "init_buffer"));
+ continue;
+ }
+
+ // Read data from client (terminate on error).
+
+ ssize_t n = ACE::recv (poll_array[index].fd,
+ buffer_array[index].buf_,
+ buffer_array[index].len_);
+ // <recv> will not block in this case!
+
+ if (n == -1)
+ ACE_ERROR ((LM_ERROR,
+ "%p\n",
+ "read failed"));
+ else if (n == 0)
+ {
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) closing oneway server at handle %d\n",
+ poll_array[index].fd));
+
+ // Handle client connection shutdown.
+ ACE_OS::close (poll_array[index].fd);
+ poll_array[index].fd = poll_array[--n_handles].fd;
+
+ ACE_OS::free ((void *) buffer_array[index].buf_);
+ buffer_array[index].buf_ = 0;
+ buffer_array[index].len_ = 0;
+ }
+ else if (verbose)
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) %*s",
+ n,
+ buffer_array[index].buf_));
+ }
+ }
+}
+
+static void
+handle_connections (ACE_SSL_SOCK_Acceptor &peer_acceptor,
+ size_t &n_handles)
+{
+ if (ACE_BIT_ENABLED (poll_array[0].revents, POLLIN))
+ {
+ ACE_SSL_SOCK_Stream new_stream;
+
+ ACE_INET_Addr client;
+ ACE_Time_Value nonblock (0, 0);
+
+ // Handle all pending connection requests (note use of "polling"
+ // feature that doesn't block).
+
+ while (ACE_OS::poll (poll_array, 1, nonblock) > 0)
+ if (peer_acceptor.accept (new_stream, &client) == -1)
+ ACE_OS::perror ("accept");
+ else
+ {
+ const char *s = client.get_host_name ();
+
+ ACE_ASSERT (s != 0);
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) client %s\n",
+ s));
+ poll_array[n_handles++].fd = new_stream.get_handle ();
+ }
+ }
+}
+
+int
+ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ u_short port = ACE_DEFAULT_SERVER_PORT + 1;
+
+ // Create a server end-point.
+ ACE_INET_Addr addr (port);
+ ACE_SSL_SOCK_Acceptor peer_acceptor (addr);
+
+ ACE_HANDLE s_handle = peer_acceptor.get_handle ();
+
+ init_poll_array ();
+
+ poll_array[0].fd = s_handle;
+
+ ACE_DEBUG ((LM_DEBUG,
+ "(%P|%t) starting oneway server at port %d\n",
+ port));
+
+ for (size_t n_handles = 1;;)
+ {
+ // Wait for client I/O events (handle interrupts).
+ while (ACE_OS::poll (poll_array, n_handles) == -1
+ && errno == EINTR)
+ continue;
+
+ handle_data (n_handles);
+ handle_connections (peer_acceptor, n_handles);
+ }
+
+ /* NOTREACHED */
+ return 0;
+}
+#else
+#include "ace/OS_NS_stdio.h"
+int ACE_TMAIN (int, ACE_TCHAR *[])
+{
+ ACE_OS::fprintf (stderr, "This feature is not supported\n");
+ return 0;
+}
+#endif /* ACE_HAS_POLL */