Merge branch 'master' into jwi-bcc64xsingletonwarning
[ACE_TAO.git] / ACE / examples / Reactor / TP_Reactor / ReadHandler.cpp
blobcb688852485f712720896b4650292072b22cce05
1 /*
2 * ACE reactor demonstration
4 * Date: 26-Jan-2006
5 */
7 #include "common.h"
8 #include "ReadHandler.h"
10 #include <ace/streams.h>
11 #include <ace/Time_Value.h>
12 #include <ace/Log_Msg.h>
14 /**
15 * This macro is used to increase the invocation counter by one when entering
16 * handle_input(). It also checks wether the counter is greater than zero
17 * indicating, that handle_input() has been called before.
19 #define INVOCATION_ENTER() do { if (mInvocationCounter > 0) \
20 ACE_ERROR((LM_ERROR, ACE_TEXT("Multiple invocations detected.\n"))); \
21 mInvocationCounter++; } while (0)
23 /**
24 * THis macro is the counter part to INVOCATION_ENTER(). It decreases the
25 * invocation counter and then returns the given value. This macro is
26 * here for convenience to decrease the invocation counter also when returning
27 * due to errors.
29 #define INVOCATION_RETURN(retval) do { mInvocationCounter--; \
30 return retval; } while(0)
32 ReadHandler::ReadHandler() : ACE_Event_Handler(), mStream(), mDataSize(0),
33 mData(0), mCallCounter(0), mInvocationCounter(0) {
34 ACE_TRACE("ReadHandler::ReadHandler()");
37 ReadHandler::~ReadHandler() {
38 ACE_TRACE("ReadHandler::~ReadHandler()");
40 if (mStream.close() == -1)
41 ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to close socket. ")
42 ACE_TEXT ("(errno = %i: %m)\n"), ACE_ERRNO_GET));
44 delete[] mData;
47 ACE_SOCK_Stream &ReadHandler::getStream() {
48 ACE_TRACE("ReadHandler::getStream()");
49 return mStream;
52 ACE_HANDLE ReadHandler::get_handle() const {
53 ACE_TRACE("ReadHandler::get_handle()");
54 return mStream.get_handle();
57 int ReadHandler::handle_input(ACE_HANDLE) {
58 ACE_TRACE("ReadHandler::handle_input(ACE_HANDLE)");
60 INVOCATION_ENTER();
62 // the response sent to the client
63 char response = 0;
65 if (mCallCounter == 0) {
67 * This is the first request from the client.
70 // increase the call counter so the next client request goes to else-if
71 mCallCounter++;
73 // get the desired size from the client
74 // Note: only use the sizeof and pointer to int on compatible
75 // platforms (i.e. little-endian/big-endian, data type size)
76 if (mStream.recv_n(&mDataSize, sizeof(mDataSize),
77 &connTimeout) != (ssize_t) sizeof(mDataSize)) {
78 ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to receive ")
79 ACE_TEXT ("request. (errno = %i: %m)\n"), ACE_ERRNO_GET));
80 INVOCATION_RETURN(-1);
83 // The verbose debug output is replaced with some unintrusive dots.
84 // This increases visibility of the desired effect.
85 // ACE_DEBUG((LM_DEBUG, ACE_TEXT("%@: Data size: %i\n"), this, mDataSize));
86 ACE_DEBUG((LM_DEBUG, ACE_TEXT(".")));
88 // check mDataSize for plausability then allocate memory
89 if (mDataSize > 0) {
90 mData = new (std::nothrow) char[mDataSize];
91 if (mData == 0)
92 ACE_DEBUG((LM_DEBUG, ACE_TEXT("%N:%l: Failed to allocate ")
93 ACE_TEXT ("data buffer.\n")));
94 else
95 response = 'K';
98 // send the response to the client (which is still 0, if the
99 // allocation did not succeed)
100 if (mStream.send_n(&response, sizeof(response), &connTimeout) != 1) {
101 ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to send ")
102 ACE_TEXT ("response. (errno = %i: %m)\n"), ACE_ERRNO_GET));
103 INVOCATION_RETURN(-1);
106 if (response == 'K')
107 INVOCATION_RETURN(0); // get another request from the same client
108 else
109 INVOCATION_RETURN(-1); // the client will not send data if response != 'K'
111 } else if (mCallCounter == 1) {
113 * This is the second request from the client.
116 // increase the call counter, this read handler should not be called
117 // again
118 mCallCounter++;
120 // receive the data from the client
121 if (mStream.recv_n(mData, mDataSize, &connTimeout) != mDataSize) {
122 ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to receive data.")
123 ACE_TEXT ("(errno = %i: %m)\n"), ACE_ERRNO_GET));
124 INVOCATION_RETURN(-1);
127 response = 'K';
129 if (mStream.send_n(&response, 1, &connTimeout) != 1) {
130 ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: Failed to send ")
131 ACE_TEXT ("confirmation. (errno = %i: %m)\n"), ACE_ERRNO_GET));
132 INVOCATION_RETURN(-1);
135 INVOCATION_RETURN(-1); // ask for removal, since client does not send any more data
138 // this is to find strange actions with the call counter
139 ACE_ERROR((LM_ERROR, ACE_TEXT("%N:%l: We should not get here.")));
140 INVOCATION_RETURN(-1);
143 int ReadHandler::handle_close(ACE_HANDLE, ACE_Reactor_Mask) {
144 ACE_TRACE("ReadHandler::handle_close(ACE_HANDLE, ACE_Reactor_Mask)");
146 delete this;
147 return 0;