1 // IPC_SAP/poll server, which illustrates how to integrate the ACE
2 // 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 CPP-inclient.cpp.
6 #include "ace/OS_main.h"
7 #include "ace/SOCK_Acceptor.h"
8 #include "ace/SOCK_Stream.h"
9 #include "ace/INET_Addr.h"
10 #include "ace/Log_Msg.h"
11 #include "ace/OS_NS_poll.h"
12 #include "ace/OS_NS_stdio.h"
15 #if defined (ACE_HAS_POLL)
17 // Should we be verbose?
18 static int verbose
= 0;
20 // Max number of open handles.
21 static const int MAX_HANDLES
= 200;
26 // Pointer to the buffer.
29 // Length of the buffer.
32 // Array of <pollfd>'s.
33 static struct pollfd poll_array
[MAX_HANDLES
];
35 // Array of <Buffer_Info>.
36 static Buffer_Info buffer_array
[MAX_HANDLES
];
43 for (i
= 0; i
< MAX_HANDLES
; i
++)
45 poll_array
[i
].fd
= ACE_INVALID_HANDLE
;
46 poll_array
[i
].events
= POLLIN
;
51 init_buffer (size_t index
)
55 if (ACE::recv_n (poll_array
[index
].fd
,
57 sizeof (ACE_INT32
)) != sizeof (ACE_INT32
))
58 ACE_ERROR_RETURN ((LM_ERROR
,
66 "(%P|%t) reading messages of size %d from handle %d\n",
68 poll_array
[index
].fd
));
70 ACE_ALLOCATOR_RETURN (buffer_array
[index
].buf_
,
73 buffer_array
[index
].len_
= len
;
79 handle_data (size_t &n_handles
)
81 // Handle pending logging messages first (s_handle + 1 is guaranteed
82 // to be lowest client descriptor).
84 for (size_t index
= 1; index
< n_handles
; index
++)
86 if (ACE_BIT_ENABLED (poll_array
[index
].revents
, POLLIN
))
88 // First time in, we need to initialize the buffer.
89 if (buffer_array
[index
].buf_
== 0
90 && init_buffer (index
) == -1)
98 // Read data from client (terminate on error).
100 ssize_t n
= ACE::recv (poll_array
[index
].fd
,
101 buffer_array
[index
].buf_
,
102 buffer_array
[index
].len_
);
103 // <recv> will not block in this case!
106 ACE_ERROR ((LM_ERROR
,
111 ACE_DEBUG ((LM_DEBUG
,
112 "(%P|%t) closing oneway server at handle %d\n",
113 poll_array
[index
].fd
));
115 // Handle client connection shutdown.
116 ACE_OS::close (poll_array
[index
].fd
);
117 poll_array
[index
].fd
= poll_array
[--n_handles
].fd
;
119 ACE_OS::free ((void *) buffer_array
[index
].buf_
);
120 buffer_array
[index
].buf_
= 0;
121 buffer_array
[index
].len_
= 0;
124 ACE_DEBUG ((LM_DEBUG
,
127 buffer_array
[index
].buf_
));
133 handle_connections (ACE_SOCK_Acceptor
&peer_acceptor
,
136 if (ACE_BIT_ENABLED (poll_array
[0].revents
, POLLIN
))
138 ACE_SOCK_Stream new_stream
;
140 ACE_INET_Addr client
;
141 ACE_Time_Value
nonblock (0, 0);
143 // Handle all pending connection requests (note use of "polling"
144 // feature that doesn't block).
146 while (ACE_OS::poll (poll_array
, 1, nonblock
) > 0)
147 if (peer_acceptor
.accept (new_stream
, &client
) == -1)
148 ACE_OS::perror ("accept");
151 const char *s
= client
.get_host_name ();
154 ACE_DEBUG ((LM_DEBUG
,
155 "(%P|%t) client %s\n",
157 poll_array
[n_handles
++].fd
= new_stream
.get_handle ();
163 ACE_TMAIN (int, ACE_TCHAR
*[])
165 u_short port
= ACE_DEFAULT_SERVER_PORT
+ 1;
167 // Create a server end-point.
168 ACE_INET_Addr
addr (port
);
169 ACE_SOCK_Acceptor
peer_acceptor (addr
);
171 ACE_HANDLE s_handle
= peer_acceptor
.get_handle ();
175 poll_array
[0].fd
= s_handle
;
177 ACE_DEBUG ((LM_DEBUG
,
178 "(%P|%t) starting oneway server at port %d\n",
181 for (size_t n_handles
= 1;;)
183 // Wait for client I/O events (handle interrupts).
184 while (ACE_OS::poll (poll_array
, n_handles
) == -1
188 handle_data (n_handles
);
189 handle_connections (peer_acceptor
, n_handles
);
197 int ACE_TMAIN (int, ACE_TCHAR
*[])
199 ACE_OS::fprintf (stderr
, "This feature is not supported\n");
202 #endif /* ACE_HAS_POLL */