Hi everyone, I am new to this online forum. I am a software engineer residing in Singapore doing software development for a living for past 9 years. Only recently am I introduced to the wonders of ACE. It is such a pity the ACE framework is not part of the C++ standard else any decent C++ compiler would have those classes built in as compared to now I got to download separately and add on. My ACE newbie questions are as below. Would appreciate some ACE experts to help me here.

Qn 1. Can we use C++ STL and ACE classes interchangeably? Since STL is part of the C++ standard can I say I use a vector<ACE_Event_Handler *> or list<ACE_Reactor *> for e.g ?

Qn 2. Can I have a portable graceful shutdown technique for the server program? Most tutorials I found online use the signal handling technique. That is, a client admin program is executed by sending a SIGINT or some other signal to the server program to indicate a graceful shutdown procedure is to be executed. The signal concept will not work in Windows environment I presume?

My approach to get my server program graceful shutdown feature to be portable is to dedicate one extra port meant only for admin client. Once connect request is received on this extra port, it indicates to my server program it is time to perform graceful shutdown. This approach should work on both Unix and Windows environment.

class Server_Daemon {
public:
  int open(...) { //called by main program Step 1
    reactor_.open(10); //max. 10 handles
    workerPool_.open();
    workerPool_.activate(THR_LWP, 10); //pre-spawn 10 threads
  }
  int close(...) { //called by main program Step 3
    workerPool_.close();
    reactor_.close();
  }
  int run(...) { //called by main program Step 2
    ACE_NEW_RETURN(admin_acceptor_, AdminAccept_Handler(this), -1); //only ONE instance of AdminAccept_Handler will be instantiated
    reactor_.register_handler(admin_acceptor_,ACE_Event_Handler::ACCEPT_MASK);
    reactor_.run_reactor_event_loop();
  }
  AdminAccept_Handler *admin_acceptor_; 
  ACE_Reactor reactor_;
  ACE_Task<ACE_MT_SYNCH> workerPool_;
}
class AdminAccept_Handler : public ACE_Event_Handler {
public:
  int AdminAccept_Handler(Server_Daemon *s) { //ctor
    src_ = s;
    reactor(src_->reactor_); // called parent class set the reactor    
  }
  int handle_input(...) { 
    //first accept call received presume Graceful Shutdown command
    src_->workerPool_.msg_queue()->deactivate(); //freeze ACE_Task msg queue, wake up all threads within to finish up and exit thread
    src_->workerPool_.msg_queue()->close(); //release ACE_Task msg queue resources
    src_->workerPool_.msg_queue()->wait(); //wait for all the threads within ACE_Task to exit

    src_->reactor_.purge_pending_notifications(0); //purge all handlers notification and handlers
    src_->reactor_.end_reactor_event_loop();
    return -1; // Will reactor_ called handle_close of this instance????
  }  
  int handle_close(...) {
    delete this;
  }
private:
  Server_Daemon *src_; 
}

Please note the handle_input method of AdminAccept_Handler class. For reactor_.purge_pending_notifications(0) I wanna remove all notifications for ALL handlers registered with reactor_ and also remove ALL handlers thereafter. If those reactor_ registered handlers are allocated dynamically previously, will I be leaking memory by just calling this purge_pending_notifications method?

What about the current handler that is executing the handle_input? Will it be purged also? Will I have some erratic behavior since I called purge_pending_notifications(0) within the handle_input method of a registered handler? I also called reactor_.end_reactor_event_loop within the handle_input method of the current handler. Will this behave erratically also?

Would appreciate other alternative suggestions if my proposed graceful shutdown approach above is flawed. Thanks.

Recommended Answers

All 2 Replies

Question 1: Yes you can.
Question 2: Even in windows you can handle it, check how MFC does it.

Question 2: Even in windows you can handle it, check how MFC does it.

I appreciate your response but it would be great if you can give more detailed advice. I'm afraid I do not know much about MFC which I presume are sets of wrapper class provided by MS to help Windows programmer do GUI development at a higher abstraction instead of using the Windows API directly?

My questions to my original question is

1. Will I be leaking memory by just calling reactor_.purge_pending_notifications on those previously dynamically allocated registered handlers? That is, I do not need to code a "delete this" on those registered handlers explicitly? All will be handled by the ACE_Reactor class internals?

2. According to the Doxygen ACE class documentation, purge_pending notifications will remove all notifications and the handlers registered with the reactor_. Now what about the current handler that issue this purge_pending notifications call? Will it be purge LAST since only when handle_input method exit do the reactor_has a chance to purge this current handler? Will reactor_ called the handle_close method first before purging?

Your further help will be greatly appreciated. Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.