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;
30 // Pointer to the buffer.
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
];
47 for (i
= 0; i
< MAX_HANDLES
; i
++)
49 poll_array
[i
].fd
= ACE_INVALID_HANDLE
;
50 poll_array
[i
].events
= POLLIN
;
55 init_buffer (size_t index
)
59 if (ACE::recv_n (poll_array
[index
].fd
,
61 sizeof (ACE_INT32
)) != sizeof (ACE_INT32
))
62 ACE_ERROR_RETURN ((LM_ERROR
,
70 "(%P|%t) reading messages of size %d from handle %d\n",
72 poll_array
[index
].fd
));
74 ACE_ALLOCATOR_RETURN (buffer_array
[index
].buf_
,
77 buffer_array
[index
].len_
= len
;
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)
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!
110 ACE_ERROR ((LM_ERROR
,
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;
128 ACE_DEBUG ((LM_DEBUG
,
131 buffer_array
[index
].buf_
));
137 handle_connections (ACE_SSL_SOCK_Acceptor
&peer_acceptor
,
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");
155 const char *s
= client
.get_host_name ();
158 ACE_DEBUG ((LM_DEBUG
,
159 "(%P|%t) client %s\n",
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 ();
179 poll_array
[0].fd
= s_handle
;
181 ACE_DEBUG ((LM_DEBUG
,
182 "(%P|%t) starting oneway server at port %d\n",
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
192 handle_data (n_handles
);
193 handle_connections (peer_acceptor
, n_handles
);
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");
206 #endif /* ACE_HAS_POLL */