diff options
Diffstat (limited to 'docs/tutorials/007/page05.html')
-rw-r--r-- | docs/tutorials/007/page05.html | 187 |
1 files changed, 0 insertions, 187 deletions
diff --git a/docs/tutorials/007/page05.html b/docs/tutorials/007/page05.html deleted file mode 100644 index d0995ca37a5..00000000000 --- a/docs/tutorials/007/page05.html +++ /dev/null @@ -1,187 +0,0 @@ -<!-- $Id$ --> -<HTML> -<HEAD> - <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> - <META NAME="GENERATOR" CONTENT="Mozilla/4.04 [en] (X11; I; Linux 2.0.32 i486) [Netscape]"> - <META NAME="Author" CONTENT="James CE Johnson"> - <META NAME="Description" CONTENT="A first step towards using ACE productively"> - <TITLE>ACE Tutorial 007</TITLE> -</HEAD> -<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 007</FONT></B></CENTER> - -<CENTER><B><FONT SIZE=+2>Creating a thread-pool server</FONT></B></CENTER> -<HR> - -<P>As you might expect, <A HREF="client_handler.h">client_handler.h</A> -is next. - -<P> -<HR WIDTH="100%"> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>CLIENT_HANDLER_H</font> -<font color=blue>#define</font> <font color=purple>CLIENT_HANDLER_H</font> - -<font color=red>/* Our client handler must exist somewhere in the ACE_Event_Handler - object hierarchy. This is a requirement of the ACE_Reactor because - it maintains ACE_Event_Handler pointers for each registered event - handler. You could derive our Client_Handler directly from - ACE_Event_Handler but you still have to have an ACE_SOCK_Stream for - the actually connection. With a direct derivative of - ACE_Event_Handler, you'll have to contain and maintain an - ACE_SOCK_Stream instance yourself. With ACE_Svc_Handler (which is - a derivative of ACE_Event_Handler) some of those details are - handled for you. */</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/Svc_Handler.h">ace/Svc_Handler.h</A>" - -<font color=blue>#if !defined</font> (<font color=purple>ACE_LACKS_PRAGMA_ONCE</font>) -<font color=blue># pragma</font> <font color=purple>once</font> -<font color=blue>#endif</font> <font color=red>/* ACE_LACKS_PRAGMA_ONCE */</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Stream.h">ace/SOCK_Stream.h</A>" - -class Client_Acceptor; -class Thread_Pool; - -<font color=red>/* Another feature of ACE_Svc_Handler is it's ability to present the - ACE_Task<> interface as well. That's what the ACE_NULL_SYNCH - parameter below is all about. That's beyond our scope here but - we'll come back to it in the next tutorial when we start looking at - concurrency options. */</font> -class Client_Handler : public ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH> -{ -public: - typedef ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH> inherited; - - <font color=red>// Constructor...</font> - Client_Handler (void); - - <font color=red>/* The destroy() method is our preferred method of destruction. We - could have overloaded the delete operator but that is neither easy - nor intuitive (at least to me). Instead, we provide a new method - of destruction and we make our destructor protected so that only - ourselves, our derivatives and our friends can delete us. It's a - nice compromise. */</font> - void destroy (void); - - <font color=red>/* Most ACE objects have an open() method. That's how you make them - ready to do work. ACE_Event_Handler has a virtual open() method - which allows us to create this overrride. ACE_Acceptor<> will - invoke this method after creating a new Client_Handler when a - client connects. Notice that the parameter to open() is a void*. - It just so happens that the pointer points to the acceptor which - created us. You would like for the parameter to be an - ACE_Acceptor<>* but since ACE_Event_Handler is generic, that would - tie it too closely to the ACE_Acceptor<> set of objects. In our - definition of open() you'll see how we get around that. */</font> - int open (void *acceptor); - - <font color=red>/* When an ACE_Task<> object falls out of the svc() method, the - framework will call the close() method. That's where we want to - cleanup ourselves if we're running in either thread-per-connection - or thread-pool mode. */</font> - int close (u_long flags = 0); - - <font color=red>/* When there is activity on a registered handler, the - handle_input() method of the handler will be invoked. If that - method returns an error code (eg -- -1) then the reactor will - invoke handle_close() to allow the object to clean itself - up. Since an event handler can be registered for more than one - type of callback, the callback mask is provided to inform - handle_close() exactly which method failed. That way, you don't - have to maintain state information between your handle_* method - calls. The <handle> parameter is explained below... As a - side-effect, the reactor will also invoke remove_handler() for the - object on the mask that caused the -1 return. This means that we - don't have to do that ourselves! */</font> - int handle_close (ACE_HANDLE handle, - ACE_Reactor_Mask mask); - - <font color=red>/* When we register with the reactor, we're going to tell it that we - want to be notified of READ events. When the reactor sees that - there is read activity for us, our handle_input() will be - invoked. The _handleg provided is the handle (file descriptor in - Unix) of the actual connection causing the activity. Since we're - derived from ACE_Svc_Handler<> and it maintains it's own peer - (ACE_SOCK_Stream) object, this is redundant for us. However, if - we had been derived directly from ACE_Event_Handler, we may have - chosen not to contain the peer. In that case, the <handle> would - be important to us for reading the client's data. */</font> - int handle_input (ACE_HANDLE handle); - -protected: - - <font color=red>/* If the Client_Acceptor which created us has chosen a - thread-per-connection strategy then our open() method will - activate us into a dedicate thread. The svc() method will then - execute in that thread performing some of the functions we used to - leave up to the reactor. */</font> - int svc (void); - - <font color=red>/* This has nothing at all to do with ACE. I've added this here as - a worker function which I will call from handle_input(). That - allows me to introduce concurrencly in later tutorials with a no - changes to the worker function. You can think of process() as - application-level code and everything elase as - application-framework code. */</font> - int process (char *rdbuf, int rdbuf_len); - - <font color=red>/* We don't really do anything in our destructor but we've declared - it to be protected to prevent casual deletion of this object. As - I said above, I really would prefer that everyone goes through the - destroy() method to get rid of us. */</font> - ~Client_Handler (void); - - <font color=red>/* When we get to the definition of Client_Handler we'll see that - there are several places where we go back to the Client_Acceptor - for information. It is generally a good idea to do that through - an accesor rather than using the member variable directly. */</font> - Client_Acceptor *client_acceptor (void) - { - return this->client_acceptor_; - } - - <font color=red>/* And since you shouldn't access a member variable directly, - neither should you set (mutate) it. Although it might seem silly - to do it this way, you'll thank yourself for it later. */</font> - void client_acceptor (Client_Acceptor *_client_acceptor) - { - this->client_acceptor_ = _client_acceptor; - } - - <font color=red>/* The concurrency() accessor tells us the current concurrency - strategy. It actually queries the Client_Acceptor for it but by - having the accessor in place, we could change our implementation - without affecting everything that needs to know. */</font> - int concurrency (void); - - <font color=red>/* Likewise for access to the Thread_Pool that we belong to. */</font> - Thread_Pool * thread_pool (void); - - Client_Acceptor *client_acceptor_; - - <font color=red>/* For some reason I didn't create accessor/mutator methods for - this. So much for consistency.... - - This variable is used to remember the thread in which we were - created: the "<font color=green>creator</font>" thread in other words. handle_input() - needs to know if it is operating in the main reactor thread (which - is the one that created us) or if it is operating in one of the - thread pool threads. More on this when we get to handle_input(). */</font> - ACE_thread_t creator_; -}; - -<font color=blue>#endif</font> <font color=red>/* CLIENT_HANDLER_H */</font> -</PRE> -<HR WIDTH="100%"> - -<P>Still, we're just not seeing a lot of changes due to introduction of -the thread pool. That's a good thing! You don't want to go turning -your application upside down just because you changed thread models. - -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page06.html">Continue This Tutorial</A>]</CENTER> |