summaryrefslogtreecommitdiff
path: root/docs/tutorials/005/server.brk
blob: ba3d878a1da4a1a1e28b928c69a09c524feb6084 (plain)
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
  
#include "ace/Acceptor.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Reactor.h"
#include "ace/Thread.h"


ACE_Reactor * g_reactor;

static sig_atomic_t finished = 0;
	
class Logging_Handler;

extern "C" void handler (int) { finished = 1; }



class Reactor_Derived : public ACE_Reactor
{	

public :
	Reactor_Derived() : ()
	{
		counter = 0;
	}
	
	virtual ~Reactor_Derived()
	{
		cout << "*****Calling the reactor destructor*****" << endl;
	}

private :
	friend class Logging_Handler;
	
	// counter is used to keep track of the number of service handlers
	// registered with this reactor (Surely theres a better way ;-)
	int counter;
};

class Logging_Handler : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{

public:

  Logging_Handler (void) { };

   virtual void destroy (void)
	{ 
          if (this->thread_reactorP->remove_handler(this,
		ACE_Event_Handler::READ_MASK | ACE_Event_Handler::DONT_CALL) == -1
	  )
  	        ACE_ERROR_RETURN ((LM_ERROR, "can'(%P|%t) t remove service from reactor\n"), -1);

	  // Decrement the handler tracking variable in the reactor to
	  // indicate this service handler has terminated
	  --thread_reactorP->counter;

	  this->peer ().close ();
	  delete this;
	}

  static void *run_thread(Logging_Handler *this_)
  	{
	  Reactor_Derived thread_reactor;     

	  this_->thread_reactorP = &thread_reactor;
	  
	  // Increment our handler counter to account for this service handler
	  ++thread_reactor.counter;

	  if (thread_reactor.register_handler(this_, ACE_Event_Handler::READ_MASK) == -1)
		  ACE_ERROR_RETURN ((LM_ERROR,"can'(%P|%t) t register with reactor\n"), -1);
	
	  while( thread_reactor.counter > 0 )
	  {
	        // If thread_reactor.counter = 0 then we have no more service
		// handlers connected to the reactor. We set a timeout value
		// of 1 second so that the handle_events loop break out every
		// second to check on the count ( because of it blocking 
		// even when there are no connections we need to do this)
		thread_reactor.handle_events(ACE_Time_Value(1,0));
	  }
	} 

 virtual int open (void *)
	{
          ACE_Thread::spawn(&Logging_Handler::run_thread,this);
	  return 0;
	}

  virtual int close (u_long)
	{
	  this->destroy ();
	  return 0;
	}

protected:

  virtual int handle_input (ACE_HANDLE)
        {
          char buf[128];
          memset(buf,0,sizeof(buf));

          switch( this->peer().recv(buf,sizeof buf) )
          {
          case -1:
            ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) %p bad read\n", "client logger"), -1);
          case 0:
            ACE_ERROR_RETURN ((LM_ERROR, "(%P|%t) closing log daemon (fd = %d)\n", this->get_handle ()), -1);
          default:
	    ACE_DEBUG ((LM_DEBUG, "(%p|%t) from client : %s",buf));
        }
          
          return 0;
        }


private:
  Reactor_Derived *thread_reactorP; 
};


typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Logging_Acceptor;


static const u_short PORT = ACE_DEFAULT_SERVER_PORT;

int main (int argc, char *argv[])
{
  g_reactor = new ACE_Reactor;

  // Acceptor factory.
  Logging_Acceptor peer_acceptor;

  if (peer_acceptor.open (ACE_INET_Addr (PORT)) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "open"), -1);

  else if (g_reactor->register_handler (&peer_acceptor, ACE_Event_Handler::READ_MASK) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "registering service with ACE_Reactor\n"), -1);

  ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);

  // Run forever, performing logging service.

  ACE_DEBUG ((LM_DEBUG, "(%P|%t) starting up server logging daemon\n"));

  // Perform logging service until QUIT_HANDLER receives SIGINT.
  while ( !finished )
    g_reactor->handle_events ();

  ACE_DEBUG ((LM_DEBUG, "(%P|%t) shutting down server logging daemon\n"));

  return 0;
}