1 #include "ace/MEM_Acceptor.h"
2 #include "ace/Lib_Find.h"
4 #if (ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1)
6 #include "ace/OS_NS_stdio.h"
7 #include "ace/OS_NS_string.h"
8 #include "ace/OS_NS_sys_socket.h"
9 #include "ace/OS_NS_unistd.h"
11 #if !defined (__ACE_INLINE__)
12 #include "ace/MEM_Acceptor.inl"
13 #endif /* __ACE_INLINE__ */
15 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
17 ACE_ALLOC_HOOK_DEFINE(ACE_MEM_Acceptor
)
20 ACE_MEM_Acceptor::dump () const
22 #if defined (ACE_HAS_DUMP)
23 ACE_TRACE ("ACE_MEM_Acceptor::dump");
24 #endif /* ACE_HAS_DUMP */
27 // Do nothing routine for constructor.
29 ACE_MEM_Acceptor::ACE_MEM_Acceptor ()
31 malloc_options_ (ACE_DEFAULT_BASE_ADDR
, 0),
32 preferred_strategy_ (ACE_MEM_IO::Reactive
)
34 ACE_TRACE ("ACE_MEM_Acceptor::ACE_MEM_Acceptor");
37 ACE_MEM_Acceptor::~ACE_MEM_Acceptor ()
39 ACE_TRACE ("ACE_MEM_Acceptor::~ACE_MEM_Acceptor");
40 #if defined (ACE_HAS_ALLOC_HOOKS)
41 ACE_Allocator::instance()->free(this->mmap_prefix_
);
43 delete[] this->mmap_prefix_
;
44 #endif /* ACE_HAS_ALLOC_HOOKS */
47 // General purpose routine for performing server ACE_SOCK creation.
49 ACE_MEM_Acceptor::ACE_MEM_Acceptor (const ACE_MEM_Addr
&remote_sap
,
54 malloc_options_ (ACE_DEFAULT_BASE_ADDR
, 0),
55 preferred_strategy_ (ACE_MEM_IO::Reactive
)
57 ACE_TRACE ("ACE_MEM_Acceptor::ACE_MEM_Acceptor");
58 if (this->open (remote_sap
,
62 ACELIB_ERROR ((LM_ERROR
,
63 ACE_TEXT ("ACE_MEM_Acceptor::ACE_MEM_Acceptor")));
67 ACE_MEM_Acceptor::open (const ACE_MEM_Addr
&remote_sap
,
72 ACE_TRACE ("ACE_MEM_Acceptor::open");
73 return this->ACE_SOCK_Acceptor::open (remote_sap
.get_local_addr (),
80 // General purpose routine for accepting new connections.
83 ACE_MEM_Acceptor::accept (ACE_MEM_Stream
&new_stream
,
84 ACE_MEM_Addr
*remote_sap
,
85 ACE_Time_Value
*timeout
,
87 bool reset_new_handle
)
89 ACE_TRACE ("ACE_MEM_Acceptor::accept");
91 int in_blocking_mode
= 1;
92 if (this->shared_accept_start (timeout
,
94 in_blocking_mode
) == -1)
99 struct sockaddr_in inet_addr
;
105 addr
= reinterpret_cast<sockaddr
*> (&inet_addr
);
106 len
= sizeof (inet_addr
);
111 // On Win32 the third parameter to <accept> must be a NULL
112 // pointer if to ignore the client's address.
113 new_stream
.set_handle (ACE_OS::accept (this->get_handle (),
116 while (new_stream
.get_handle () == ACE_INVALID_HANDLE
123 ACE_INET_Addr
temp (&inet_addr
, len
);
124 remote_sap
->set_port_number (temp
.get_port_number ());
128 if (this->shared_accept_finish (new_stream
,
130 reset_new_handle
) == -1)
133 // Allocate 2 * MAXPATHLEN so we can accomodate the unique
134 // name that gets appended later
135 ACE_TCHAR buf
[2 * MAXPATHLEN
+ 1];
137 ACE_INET_Addr local_addr
;
138 if (new_stream
.get_local_addr (local_addr
) == -1)
141 if (this->mmap_prefix_
!= 0)
143 ACE_OS::snprintf (buf
, sizeof buf
/ sizeof buf
[0],
146 local_addr
.get_port_number ());
151 // - 24 is so we can append name to the end.
152 if (ACE::get_temp_dir (buf
, MAXPATHLEN
- 24) == -1)
154 ACELIB_ERROR ((LM_ERROR
,
155 ACE_TEXT ("Temporary path too long, ")
156 ACE_TEXT ("defaulting to current directory\n")));
160 ACE_OS::snprintf (name
, 25,
161 ACE_TEXT ("MEM_Acceptor_%d_"),
162 local_addr
.get_port_number ());
163 ACE_OS::strcat (buf
, name
);
165 ACE_TCHAR unique
[MAXPATHLEN
];
166 ACE_OS::unique_name (&new_stream
, unique
, MAXPATHLEN
);
168 ACE_OS::strcat (buf
, unique
);
170 // Make sure we have a fresh start.
171 ACE_OS::unlink (buf
);
173 new_stream
.disable (ACE_NONBLOCK
);
174 ACE_HANDLE new_handle
= new_stream
.get_handle ();
176 // Protocol negociation:
177 // Tell the client side what level of signaling strategy
179 ACE_MEM_IO::Signal_Strategy client_signaling
=
180 #if defined (ACE_WIN32) || !defined (_ACE_USE_SV_SEM)
181 this->preferred_strategy_
;
183 // We don't support MT.
184 ACE_MEM_IO::Reactive
;
185 #endif /* ACE_WIN32 || !_ACE_USE_SV_SEM */
186 if (ACE::send (new_handle
, &client_signaling
,
187 sizeof (ACE_INT16
)) == -1)
188 ACELIB_ERROR_RETURN ((LM_DEBUG
,
189 ACE_TEXT ("ACE_MEM_Acceptor::accept error sending strategy\n")),
192 // Now we get the signaling strategy the client support.
193 if (ACE::recv (new_handle
, &client_signaling
,
194 sizeof (ACE_INT16
)) == -1)
195 ACELIB_ERROR_RETURN ((LM_DEBUG
,
196 ACE_TEXT ("ACE_MEM_Acceptor::%p error receiving strategy\n"),
197 ACE_TEXT ("accept")),
200 // Ensure minimum buffer size
201 if (this->malloc_options_
.minimum_bytes_
< ACE_MEM_STREAM_MIN_BUFFER
)
202 this->malloc_options_
.minimum_bytes_
= ACE_MEM_STREAM_MIN_BUFFER
;
204 // Client will decide what signaling strategy to use.
206 // Now set up the shared memory malloc pool.
207 if (new_stream
.init (buf
,
208 static_cast<ACE_MEM_IO::Signal_Strategy
> (client_signaling
),
209 &this->malloc_options_
) == -1)
212 // @@ Need to handle timeout here.
213 ACE_UINT16 buf_len
= static_cast<ACE_UINT16
> ((ACE_OS::strlen (buf
) + 1) *
216 // No need to worry about byte-order because both parties should always
217 // be on the same machine.
218 if (ACE::send (new_handle
, &buf_len
, sizeof (ACE_UINT16
)) == -1)
221 // Now send the pathname of the mmap file.
222 if (ACE::send (new_handle
, buf
, buf_len
) == -1)
228 ACE_MEM_Acceptor::shared_accept_finish (ACE_MEM_Stream new_stream
,
229 int in_blocking_mode
,
230 bool reset_new_handle
) const
232 ACE_TRACE ("ACE_MEM_Acceptor::shared_accept_finish ()");
234 ACE_HANDLE new_handle
= new_stream
.get_handle ();
236 // Check to see if we were originally in blocking mode, and if so,
237 // set the <new_stream>'s handle and <this> handle to be in blocking
239 if (in_blocking_mode
)
241 // Save/restore errno.
242 ACE_Errno_Guard
error (errno
);
244 // Only disable ACE_NONBLOCK if we weren't in non-blocking mode
246 ACE::clr_flags (this->get_handle (),
248 ACE::clr_flags (new_handle
,
252 #if defined (ACE_HAS_WINSOCK2) && (ACE_HAS_WINSOCK2 != 0)
253 if (reset_new_handle
)
254 // Reset the event association inherited by the new handle.
255 ::WSAEventSelect ((SOCKET
) new_handle
, 0, 0);
257 ACE_UNUSED_ARG (reset_new_handle
);
258 #endif /* ACE_WIN32 */
259 if (new_handle
== ACE_INVALID_HANDLE
)
265 ACE_END_VERSIONED_NAMESPACE_DECL
267 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS == 1 */