We normally start by looking at main() and work our way out from there. This time, I want to start by showing you the ACE_Message_Block derivative but before that, I have to introduce you to the Work object and it's baseclass Unit_Of_Work
/* We'll start by defining a basic unit of work that can be put into the message queue. The threads in the pool will expect to find one of these in each message block and will invoke a method or two. */ class Unit_Of_Work { public: Unit_Of_Work (void) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work ctor 0x%x\n", (void *) this)); } virtual ~ Unit_Of_Work (void) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work dtor 0x%x\n", (void *) this)); } void who_am_i (void) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Unit_Of_Work instance 0x%x\n", (void *) this)); } virtual void what_am_i (void) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Unit_Of_Work object\n")); } }; /* Now, we specialize the Unit_Of_Work object to do something different. By overriding the virtual method, we can do whatever "real work" is needed but the thread pool doesn't have to know the specifics. */ class Work : public Unit_Of_Work { public: Work (void) : message_ (-1) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work ctor 0x%x\n", (void *) this)); } Work (int message) : message_ (message) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work ctor 0x%x for message %d\n", (void *) this, message_)); } virtual ~ Work (void) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) Work dtor 0x%x\n", (void *) this)); } void what_am_i (void) { ACE_DEBUG ((LM_DEBUG, "(%P|%t) I am a Work object for message %d\n", message_)); } protected: int message_; };
This is basically the same as the DataBase in the previous tutorial but I've changed the name to be more generic. The feeling is that a Data object would be a C struct but an Work object would be a class with methods.
Now that you know what we'll be putting into the queue, lets go to the next page where I specialize the ACE_Message_Block.