1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
/*
* ACE reactor demonstration
*
* Date: 26-Jan-2006
*/
#include "common.h"
#include "AcceptHandler.h"
#include "ReadHandler.h"
#include <ace/INET_Addr.h>
#include <ace/Log_Msg.h>
#include <memory>
AcceptHandler:: AcceptHandler(ACE_Reactor *reactor) :
ACE_Event_Handler(),
mReactor(reactor == 0 ? ACE_Reactor::instance() : reactor),
mAcceptor() {
ACE_TRACE("AcceptHandler:: AcceptHandler(ACE_Reactor *)");
}
AcceptHandler::~AcceptHandler() {
ACE_TRACE("AcceptHandler::~AcceptHandler()");
}
int AcceptHandler::open() {
ACE_TRACE("AcceptHandler::open()");
// create the local address used for the service (PORT is from common.h)
ACE_INET_Addr addr(PORT);
// open a port using the acceptor; reuse the address later
if (mAcceptor.open(addr, 1) == -1)
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to open ")
ACE_TEXT ("listening socket. (errno = %i: %m)\n"), ACE_ERRNO_GET), -1);
// register the handler with the reactor
if (mReactor->register_handler(this,
ACE_Event_Handler::ACCEPT_MASK) == -1) {
ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to register accept ")
ACE_TEXT ("handler. (errno = %i: %m)\n"), ACE_ERRNO_GET));
// don't leave the acceptor open
if (mAcceptor.close() == -1)
ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to close the socket ")
ACE_TEXT ("after previous error. (errno = %i: %m)\n"),
ACE_ERRNO_GET));
return -1;
}
return 0;
}
ACE_HANDLE AcceptHandler::get_handle() const {
ACE_TRACE("AcceptHandler::get_handle()");
return mAcceptor.get_handle();
}
int AcceptHandler::handle_input(ACE_HANDLE) {
ACE_TRACE("AcceptHandler::handle_input(ACE_HANDLE)");
ACE_INET_Addr clientAddr;
// create a new ReadHandler
ReadHandler *reader = 0;
ACE_NEW_NORETURN (reader, ReadHandler());
if (reader == 0)
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to allocate ")
ACE_TEXT ("reader. (errno = %i: %m)\n"), ACE_ERRNO_GET), -1);
// put reader in an unique pointer so we can use ACE_ERROR_RETURN safely
std::unique_ptr<ReadHandler> pReader(reader);
// accept the connection using the reader's stream
if (mAcceptor.accept(reader->getStream(), &clientAddr) == -1)
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to accept ")
ACE_TEXT ("client connection. (errno = %i: %m)\n"), ACE_ERRNO_GET), -1);
// register the reader with the reactor
if (mReactor->register_handler(reader,
ACE_Event_Handler::READ_MASK) == -1)
ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%N:%l: Failed to register ")
ACE_TEXT ("read handler. (errno = %i: %m)\n"), ACE_ERRNO_GET), -1);
// from now on the read handler takes care of itself
pReader.release();
return 0; // keep going
}
int AcceptHandler::handle_close(ACE_HANDLE, ACE_Reactor_Mask) {
ACE_TRACE("AcceptHandler::handle_close(ACE_HANDLE, ACE_Reactor_Mask)");
// close the listening socket
if (mAcceptor.close() == -1)
ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to close the ")
ACE_TEXT ("socket. (errno = %i: %m)\n"), ACE_ERRNO_GET));
// no need to distinguish between error during close and normal close
// since ACE does not evaluate the return value of handle_close()
delete this;
return 0;
}
|