diff options
Diffstat (limited to 'docs/tutorials/022')
-rw-r--r-- | docs/tutorials/022/Acceptor_Service.cpp | 154 | ||||
-rw-r--r-- | docs/tutorials/022/Acceptor_Service.h | 93 | ||||
-rw-r--r-- | docs/tutorials/022/Makefile | 105 | ||||
-rw-r--r-- | docs/tutorials/022/client/Makefile | 47 | ||||
-rw-r--r-- | docs/tutorials/022/client/client.cpp | 216 | ||||
-rw-r--r-- | docs/tutorials/022/client_handler.cpp | 225 | ||||
-rw-r--r-- | docs/tutorials/022/client_handler.h | 100 | ||||
-rw-r--r-- | docs/tutorials/022/page01.html | 40 | ||||
-rw-r--r-- | docs/tutorials/022/page02.html | 98 | ||||
-rw-r--r-- | docs/tutorials/022/page03.html | 123 | ||||
-rw-r--r-- | docs/tutorials/022/page04.html | 177 | ||||
-rw-r--r-- | docs/tutorials/022/page05.html | 130 | ||||
-rw-r--r-- | docs/tutorials/022/server.cpp | 56 | ||||
-rw-r--r-- | docs/tutorials/022/svc.conf | 9 |
14 files changed, 0 insertions, 1573 deletions
diff --git a/docs/tutorials/022/Acceptor_Service.cpp b/docs/tutorials/022/Acceptor_Service.cpp deleted file mode 100644 index aa4976cc228..00000000000 --- a/docs/tutorials/022/Acceptor_Service.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// $Id$ - -#include "Acceptor_Service.h" -#include "ace/Dynamic_Service.h" - -#include "client_handler.h" - -/* A server has to listen for clients at a known TCP/IP port. The - default ACE port is 10002 (at least on my system) and that's good - enough for what we want to do here. Obviously, a more robust - application would take a command line parameter or read from a - configuration file or do some other clever thing. Just like the - signal handler above, though, that's not what we want to focus on, - so we're taking the easy way out. */ - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -/* As in all our simple tutorials, our contructor also does nothing */ -Acceptor_Service::Acceptor_Service (void) -{ - // Constructor -} - -/* Same in the destructor case */ -Acceptor_Service::~Acceptor_Service (void) -{ - // Constructor -} - -/* This is the virtual method inherited from ACE_Service_Object. This - method is called to initialize the service. In a generic sense, we - initialize everything that is needed to initialize our service - here. Ofcourse we need to do that only if there are not already - initialized. One important point to note here is that we have to - make sure that everything that is initialized here is actually - removed when the service is shutdown */ -int -Acceptor_Service::init (int argc, char *argv[]) -{ - /* As you will see, we will not be using argc and argv here and - hence declare them to be unused variables. This helps us from the - complaints from the picky compilers about unused variables. */ - ACE_UNUSED_ARG (argc); - ACE_UNUSED_ARG (argv); - - /* Lets have a debug statement so that we can know that our - Acceptor_Service will be initialized soon */ - ACE_DEBUG ((LM_DEBUG, - "Starting the Acceptor_Service\n")); - - /* Create an ACE_INET_Addr that represents our endpoint of a - connection. We then open our acceptor object with that Addr. - Doing so tells the acceptor where to listen for connections. - Servers generally listen at "well known" addresses. If not, there - must be some mechanism by which the client is informed of the - server's address. */ - if (this->open (ACE_INET_Addr (PORT), - ACE_Reactor::instance ()) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "open"), - -1); - return 0; -} - -/* This virtual method will be invoked when we pass a directive to the - service configurator framework to remove our service. Remember the - threads and anything else that are initialized in the init - method and remove each of them. If we leave anything that we - initialized still running after this method is invoked ...well .. you - know what happens :-) */ -int -Acceptor_Service::fini (void) -{ - /* Lets have another debug statement to inform us the state of the - service. */ - ACE_DEBUG ((LM_DEBUG, - "Closing down the Acceptor_Service\n")); - - /* Now, lets see what did we start or initialize during the - initialization process. The only thing that we did was opening - our Acceptor to start listening for requests. So, lets close it - down. */ - this->close (); - - return 0; -} - -/* Now, lets see how we can suspend the service that we initialized - and is running. By suspension, we mean that the Reactor still knows - about the service and receives the requests. But, it just keeps - quite even if there are any requests. It actually queues the - requests and sends them to the service once it is resumed. */ -int -Acceptor_Service::suspend (void) -{ -/* You must be wondering, as I did, how we can simply suspend this - service without any complex method invocations. Thanks to our - ACE_Reactor class, we can actually suspend the service by just - invoking the following method and passing a pointer to ourself. - This method actually takes care of all the particulars for - suspending the services and keeps us happy. */ - ACE_Reactor::instance ()->suspend_handler (this); - return 0; -} - -int -Acceptor_Service::resume (void) -{ - /* I had the same question again ... how do I do this ?? As before, - our ACE_Reactor class came to a help with this method. ACE - classes do make life simpler .. don't they !! */ - ACE_Reactor::instance ()->resume_handler (this); - - return 0; -} - -/* The macro to be used to define the factory method and destructor - for our dynamically loadable service. */ -ACE_SVC_FACTORY_DEFINE (Acceptor_Service) - -/* This macro helps to register a statically linked service into the - service configurator. It is defined in ace/OS.h. All the parameters - needed by the service configurator to build and control the - statically linked servuce are configured in a single structure. An - instance of this structure is statically initialized using this - macro. The First parameter is SERVICE_CLASS i.e. the name of the - class that implements the service. As we did implicitly, this class - must derive from ACE_Service_Configurator. The second parameter is - the NAME of the service. This name is used by the service - configurator to match the configuration options provided in the - svc.conf file. The third parameter is the type of the object which - could be either streams or service objects. The next parameter is - the name of the factory function which we defined in our header - file and above using the macros ACE_FACTORY_DECLARE and - ACE_FACTORY_DEFINE. The fifth parameter are a set of options or - flags which are used to control the ownership and life cycle of the - object. The final argument helps us to choose if we want a new - thread for this service. If the argument is not 0, a thread will be - dedicated to this service. .. lots of parameters .. Huh !! */ -ACE_STATIC_SVC_DEFINE (Acceptor_Service, - ACE_TEXT ("Acceptor_Service"), - ACE_SVC_OBJ_T, - &ACE_SVC_NAME (Acceptor_Service), - ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, - 0) - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/docs/tutorials/022/Acceptor_Service.h b/docs/tutorials/022/Acceptor_Service.h deleted file mode 100644 index d21bd70a42d..00000000000 --- a/docs/tutorials/022/Acceptor_Service.h +++ /dev/null @@ -1,93 +0,0 @@ -//$Id$ - -#ifndef ACCEPTOR_SERVICE_H -#define ACCEPTOR_SERVICE_H -#include "ace/pre.h" - -/* The ACE_Acceptor<> template lives in the ace/Acceptor.h header - file. */ -#include "ace/Acceptor.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -/* Since we want to work with sockets, we'll need a SOCK_Acceptor to - allow the clients to connect to us. */ -#include "ace/SOCK_Acceptor.h" - -/* The Client_Handler object we develop will be used to handle clients - once they're connected. The ACE_Acceptor<> template's first - parameter requires such an object. In some cases, you can get by - with just a forward declaration on the class, in others you have to - have the whole thing. */ -#include "client_handler.h" - -/* In our original simple server, we instantiated a - ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> object. We can - make it much simpler and efficient by inheriting our - Acceptor_Service from ACE_Acceptor itself. - - Our Acceptor_Service class also needs to inherit from - ACE_Service_Object. ACE_Service_Object is an abstract class which - includes methods called by the Service Configurator framework to - start, remove, suspend or resume our service. - - You might have noticed that we didnt explicitly inherit from - ACE_Service_Object here. That is because, ACE_Acceptor derives from - ACE_Service_Object and hence there is no need to specify it again. */ - - /* TO Do: Describe what/why ACE_Svc_Export */ - -class ACE_Svc_Export Acceptor_Service : public ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> -{ - public: - // Constructor - Acceptor_Service (void); - - // Destructor - ~Acceptor_Service (void); - - /* This method is the one which is called by the Service - Configurator Framework to initialize or start the service. */ - virtual int init (int argc, char *argv[]); - - /* Called by the Service Configurator framework to remove this - Service. */ - virtual int fini (void); - - /* You could easily guess that this method is called to suspend the - service by the same Service Configurator Framework. When in the - suspend mode, the service is not removed completely and is *still - there*. The difference is that the service is not in a active - state and doesnot accept requests.*/ - virtual int suspend (void); - - /* And your guess that this method is called to resume the service - is also not wrong. This call brings the service back to the - active state and the service is all ready to accept requests */ - virtual int resume (void); - -}; - -/* The following macros and similar macros which we will use in the - implementation file later are used to define helper functions for - the Service Configurator. As we can easily guess, these macros are - intended to dynamically load ancd configure services using the - svc.conf file. These macros will also help to dynamically configure - even the statically linked services. */ - -/* This macro is used to declare a data structure required to register a - statically linked service into the service configurator. As you can - see it has only one argument which is the name of the class that - implements this service... so Acceptor_Service in our case. */ -ACE_STATIC_SVC_DECLARE (Acceptor_Service) - -/* Once the service implementation is dynamically loaded, the Service - Configurator uses a factory method to create the object. This - macro declares such a factory function with the proper interface - and export macros. */ -ACE_SVC_FACTORY_DECLARE (Acceptor_Service) - -#include "ace/post.h" -#endif /* ACCEPTOR_SERVICE_H */ diff --git a/docs/tutorials/022/Makefile b/docs/tutorials/022/Makefile deleted file mode 100644 index c164a653cac..00000000000 --- a/docs/tutorials/022/Makefile +++ /dev/null @@ -1,105 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -# You can generally find a Makefile in the ACE examples, tests or the library -# itself that will satisfy our application needs. This one was taken from -# one of the examples. - - # Define the name of the binary we want to create. There has to be - # a CPP file $(BIN).cpp but it doesn't necessarily have to have your - # main() in it. Most of the time, though, it will. -MAKEFILE = Makefile -BIN = server -LIBNAME = libAcceptor_Server -LIB = $(LIBNAME).a -SHLIB = $(LIBNAME).$(SOEXT) - # Few applications will have a single source file. We use the FILES - # macro to build up a list of additional files to compile. Notice - # that we leave off the extension just as with BIN -FILES = -FILES += Acceptor_Service client_handler - - # Here we use some GNU make extensions to build the SRC macro. Basically, - # we're just adding .cpp to the value of BIN and for each entry of the - # FILES macro. -PSRC = $(addsuffix .cpp,$(BIN)) -LSRC = $(addsuffix .cpp,$(FILES)) - -LDLIBS = - -LIBS += $(ACELIB) - - # The BUILD macro is used by the ACE makefiles. Basically, it tells - # the system what to build. I don't really know what VBIN is other - # than it is constructed from the value of BIN. Just go with it... -BUILD = $(VLIB) $(VSHLIB) $(SHLIBA) $(VBIN) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - - # This is where the real power lies! These included makefile components - # are similar to the C++ templates in ACE. That is, they do a tremendous - # amount of work for you and all you have to do is include them. - # As a matter of fact, in our project, I created a single file named - # "app.mk" that includes all of these. Our project makefiles then just - # need to include app.mk to get everything they need. - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.lib.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- - - # Sometimes I like to reformat my code to make it more readable. This is - # more useful for the comments than anything else. Unfortunately, the - # "indent" program doesn't quite grok C++ so I have to post-process it's - # output just a bit. -Indent : # - for i in $(SRC) $(HDR) ; do \ - indent -npsl -l80 -fca -fc1 -cli0 -cdb < $$i | \ - sed -e 's/: :/::/g' \ - -e 's/^.*\(public:\)/\1/' \ - -e 's/^.*\(protected:\)/\1/' \ - -e 's/^.*\(private:\)/\1/' \ - -e 's/:\(public\)/ : \1/' \ - -e 's/:\(protected\)/ : \1/' \ - -e 's/:\(private\)/ : \1/' \ - > $$i~ ;\ - mv $$i~ $$i ;\ - done - - # One of the targets in the ACE makefiles is "depend". It will invoke - # your compiler in a way that will generate a list of dependencies for - # you. This is a great thing! Unfortunately, it puts all of that mess - # directly into the Makefile. I prefer my Makefile to stay clean and - # uncluttered. The perl script referenced here pulls the dependency - # stuff back out of the Makefile and into a file ".depend" which we then - # include just like the makefile components above. - # - # NOTE: The 'depend' target expects to have GCC available. - # You can do the same thing with other compilers but the ACE - # makefiles and utilities are only wired up to work with GCC. -Depend : depend - perl ../fix.Makefile - -CLEAN : realclean - $(RM) hdr bodies *.pre *.pst .depend - -#---------------------------------------------------------------------------- -# Dependencies -#---------------------------------------------------------------------------- - - # Don't put anything below here. Between the "depend" target and fix.Makefile - # it's guaranteed to be lost! diff --git a/docs/tutorials/022/client/Makefile b/docs/tutorials/022/client/Makefile deleted file mode 100644 index 0bfc82e3bd5..00000000000 --- a/docs/tutorials/022/client/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -#---------------------------------------------------------------------------- -# $Id$ -# -# Makefile for client logging applications -#---------------------------------------------------------------------------- - -#---------------------------------------------------------------------------- -# Local macros -#---------------------------------------------------------------------------- - -BIN = client - -LSRC = $(addsuffix .cpp,$(BIN)) - -VLDLIBS = $(LDLIBS:%=%$(VAR)) - -BUILD = $(VBIN) - -#---------------------------------------------------------------------------- -# Include macros and targets -#---------------------------------------------------------------------------- - -include $(ACE_ROOT)/include/makeinclude/wrapper_macros.GNU -include $(ACE_ROOT)/include/makeinclude/macros.GNU -include $(ACE_ROOT)/include/makeinclude/rules.common.GNU -include $(ACE_ROOT)/include/makeinclude/rules.nonested.GNU -include $(ACE_ROOT)/include/makeinclude/rules.bin.GNU -include $(ACE_ROOT)/include/makeinclude/rules.local.GNU - - -HTML : # - [ -f hdr ] || $(MAKE) UNSHAR - perl ../combine *.pre ; chmod +r *.html - -SHAR : # - [ ! -f combine.shar ] || exit 1 - shar -T hdr bodies *.pre *.pst > combine.shar && $(RM) hdr bodies *.pre *.pst - -UNSHAR : # - sh combine.shar - -CLEAN : realclean - $(RM) hdr bodies *.pre *.pst .depend - -#---------------------------------------------------------------------------- -# Local targets -#---------------------------------------------------------------------------- diff --git a/docs/tutorials/022/client/client.cpp b/docs/tutorials/022/client/client.cpp deleted file mode 100644 index 54bcbc04fa0..00000000000 --- a/docs/tutorials/022/client/client.cpp +++ /dev/null @@ -1,216 +0,0 @@ -// $Id$ - -/* We need the connector object & we also bring in a simple string - class. */ -#include "ace/Log_Msg.h" -#include "ace/SOCK_Connector.h" -#include "ace/SString.h" - -/* In this tutorial, we extend SOCK_Stream by adding a few wrappers - around the send_n() method. */ -class Client : public ACE_SOCK_Stream -{ -public: - // Basic constructor - Client (void); - - /* Construct and open() in one call. This isn't generally a good - idea because you don't have a clean way to inform the caller when - open() fails. (Unless you use C++ exceptions.) */ - Client (const char *server, - u_short port); - - /* Open the connection to the server. Notice that this mirrors the - use of ACE_SOCK_Connector. By providing our own open(), we can - hide the connector from our caller & make it's interaction easier. */ - int open (const char *server, - u_short port); - - /* These are necessary if you're going to use the constructor that - invokes open(). */ - int initialized (void) { return initialized_; } - int error (void) { return error_; } - - /* This is where the coolness lies. Most C++ folks are familiar - with "cout << some-data." It's a very handy and easy way to toss - data around. By adding these method calls, we're able to do the - same thing with a socket connection. */ - Client &operator<< (ACE_SString &str); - Client &operator<< (char *str); - Client &operator<< (int n); - -protected: - u_char initialized_; - u_char error_; -}; - -/* The basic constructor just sets our flags to reasonable values. */ -Client::Client(void) -{ - initialized_ = 0; - error_ = 0; -} - -/* This constructor also sets the flags but then calls open(). If the - open() fails, the flags will be set appropriately. Use the two - inline method calls initialized() and error() to check the object - state after using this constructor. */ -Client::Client (const char *server, - u_short port) -{ - initialized_ = 0; - error_ = 0; - this->open (server, port); -} - -/* Open a connection to the server. This hides the use of - ACE_SOCK_Connector from our caller. Since our caller probably - doesn't care *how* we connect, this is a good thing. */ -int -Client::open (const char *server, - u_short port) -{ - /* This is right out of Tutorial 3. The only thing we've added is - to set the initialized_ member variable on success. */ - - ACE_SOCK_Connector connector; - ACE_INET_Addr addr (port, server); - - if (connector.connect (*this, addr) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "open"), - -1); - initialized_ = 1; - return 0; -} - -/* The first of our put operators sends a simple string object to the - peer. */ -Client & -Client::operator<< (ACE_SString &str) -{ - /* We have to be able to allow: server << foo << bar << stuff; - - To accomplish that, every << operator must check that the object - is in a valid state before doing work. */ - - if (initialized () && !error ()) - { - /* Get the actual data held in the string object */ - const char *cp = str.fast_rep (); - - /* Send that data to the peer using send_n() as before. If we - have a problem, we'll set error_ so that subsequent << - operations won't try to use a broken stream. */ - if (this->send_n (cp, - ACE_OS::strlen (cp)) == -1) - error_ = 1; - } - else - /* Be sure that error_ is set if somebody tries to use us when - we're not initialized. */ - error_ = 1; - - /* We have to return a reference to ourselves to allow chaining of - put operations (eg -- "server << foo << bar"). Without the - reference, you would have to do each put operation as a statement. - That's OK but doesn't have the same feel as standard C++ - iostreams. */ - return *this ; -} - -/* How do you put a char*? We'll take an easy way out and construct -an ACE_SString from the char* and then put that. It would have been -more efficient to implement this with the body of the -operator<<(ACE_SString&) method and then express that method in terms -of this one. There's always more than one way to do things! */ - -Client & -Client::operator<< (char *str) -{ - ACE_SString newStr (str); - - *this << newStr; - - return *this ; - - /* Notice that we could have been really clever and done: - - return *this << ACE_SString (str); - - That kind of thing just makes debugging a pain though! */ -} - -/* ACE_SString and char* are both about the same thing. What do you - do about different datatypes though? - - Do the same thing we did with char* and convert it to ACE_SString - where we already have a << operator defined. */ -Client & -Client::operator<< (int n) -{ - /* Create a character buffer large enough for the largest number. - That's a tough call but BUFSIZ should be quite enough. */ - char buf[BUFSIZ]; - - /* Put the number into our buffer... */ - ACE_OS::sprintf (buf, - "(%d)\n", - n); - - /* And create the ACE_SString that we know how to put. */ - ACE_SString newStr (buf); - - /* Send it and... */ - *this << newStr; - - /* return ourselves as usual. */ - return *this; -} - -/* Now we pull it all together. Like Tutorial 3, we'll allow command - line options. */ -int -main (int argc, char *argv[]) -{ - const char *server_host = argc > 1 ? argv[1] : ACE_DEFAULT_SERVER_HOST; - u_short server_port = argc > 2 ? ACE_OS::atoi (argv[2]) : ACE_DEFAULT_SERVER_PORT; - int max_iterations = argc > 3 ? ACE_OS::atoi (argv[3]) : 4; - - /* Use the basic constructor since the other isn't really very safe. */ - Client peer; - - /* Open the server connection. Notice how this is simpler than - Tutorial 3 since we only have to provide a host name and port - value. */ - if (peer.open (server_host, - server_port) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "open"), - -1); - - for (int i = 0; i < max_iterations; i++) - { - /* Tell the server which iteration we're on. No more mucking - aroudn with sprintf at this level! It's all hidden from us. */ - peer << "message = " << i+1; - - /* Everything OK? */ - if (peer.error ()) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "send"), - -1); - else - ACE_OS::sleep (1); - } - - if (peer.close () == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "close"), - -1); - return 0; -} diff --git a/docs/tutorials/022/client_handler.cpp b/docs/tutorials/022/client_handler.cpp deleted file mode 100644 index d1e51f0833c..00000000000 --- a/docs/tutorials/022/client_handler.cpp +++ /dev/null @@ -1,225 +0,0 @@ -// $Id$ - -/* In client_handler.h I alluded to the fact that we'll mess around - with a Client_Acceptor pointer. To do so, we need the - Client_Acceptor object declaration. - - We know that including client_handler.h is redundant because - client_acceptor.h includes it. Still, the sentry prevents - double-inclusion from causing problems and it's sometimes good to - be explicit about what we're using. - - On the other hand, we don't directly include any ACE header files - here. */ -#include "client_acceptor.h" -#include "client_handler.h" - -/* Our constructor doesn't do anything. That's generally a good idea. - Unless you want to start throwing exceptions, there isn't a really - good way to indicate that a constructor has failed. If I had my - way, I'd have a boolean return code from it that would cause new to - return 0 if I failed. Oh well... */ -Client_Handler::Client_Handler (void) -{ -} - -/* Our destructor doesn't do anything either. That is also by design. - Remember, we really want folks to use destroy() to get rid of us. - If that's so, then there's nothing left to do when the destructor - gets invoked. */ -Client_Handler::~Client_Handler (void) -{ - // Make sure that our peer closes when we're deleted. This - // will probably happened when the peer is deleted but it - // doesn't hurt to be explicit. - this->peer ().close (); -} - -/* The much talked about destroy() method! The reason I keep going on - about this is because it's just a Bad Idea (TM) to do real work - inside of a destructor. Although this method is void, it really - should return int so that it can tell the caller there was a - problem. Even as void you could at least throw an exception which - you would never want to do in a destructor. */ -void -Client_Handler::destroy (void) -{ - /* Tell the reactor to forget all about us. Notice that we use the - same args here that we use in the open() method to register - ourselves. In addition, we use the DONT_CALL flag to prevent - handle_close() being called. Since we likely got here due to - handle_close(), that could cause a bit of nasty recursion! */ - this->reactor ()->remove_handler (this, - ACE_Event_Handler:: READ_MASK | ACE_Event_Handler::DONT_CALL); - - /* This is how we're able to tell folks not to use delete. By - deleting our own instance, we take care of memory leaks after - ensuring that the object is shut down correctly. */ - delete this; -} - -/* As mentioned before, the open() method is called by the - Client_Acceptor when a new client connection has been accepted. - The Client_Acceptor instance pointer is cast to a void* and given - to us here. We'll use that to avoid some global data... */ -int -Client_Handler::open (void *_acceptor) -{ - /* Convert the void* to a Client_Acceptor*. You should probably use - those fancy ACE_*_cast macros but I can never remember how/when - to do so. Since you can cast just about anything around a void* - without compiler warnings be very sure of what you're doing when - you do this kind of thing. That's where the new-style cast - operators can save you. */ - Client_Acceptor *acceptor = (Client_Acceptor *) _acceptor; - - /* Our reactor reference will be set when we register ourselves but - I decided to go ahead and set it here. No good reason really... */ - this->reactor (acceptor->reactor ()); - - /* We need this to store the address of the client that we are now - connected to. We'll use it later to display a debug message. */ - ACE_INET_Addr addr; - - /* Our ACE_Svc_Handler baseclass gives us the peer() method as a way - to access our underlying ACE_SOCK_Stream. On that object, we can - invoke the get_remote_addr() method to get an ACE_INET_Addr - having our client's address information. As with most ACE - methods, we'll get back (and return) a -1 if there was any kind - of error. Once we have the ACE_INET_Addr, we can query it to - find out the clien's host name, TCP/IP address, TCP/IP port value - and so forth. One word of warning: the get_host_name() method of - ACE_INET_Addr may return you an empty string if your name server - can't resolve it. On the other hand, get_host_addr() will always - give you the dotted-decimal string representing the TCP/IP - address. */ - if (this->peer ().get_remote_addr (addr) == -1) - return -1; - - /* If we managed to get the client's address then we're connected to - a real and valid client. I suppose that in some cases, the - client may connect and disconnect so quickly that it is invalid - by the time we get here. In any case, the test above should - always be done to ensure that the connection is worth keeping. - - Now, register ourselves with a reactor and tell that reactor that - we want to be notified when there is something to read. - Remember, we took our reactor value from the acceptor which - created us in the first place. Since we're exploring a - single-threaded implementation, this is the correct thing to do. */ - if (this->reactor ()->register_handler (this, - ACE_Event_Handler::READ_MASK) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) can't register with reactor\n"), - -1); - - /* Here, we use the ACE_INET_Addr object to print a message with the - name of the client we're connected to. Again, it is possible - that you'll get an empty string for the host name if your DNS - isn't configured correctly or if there is some other reason that - a TCP/IP addreess cannot be converted into a host name. */ - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) connected with %s\n", - addr.get_host_name ())); - - /* Always return zero on success. */ - return 0; -} - -/* In the open() method, we registered with the reactor and requested - to be notified when there is data to be read. When the reactor - sees that activity it will invoke this handle_input() method on us. - As I mentioned, the _handle parameter isn't useful to us but it - narrows the list of methods the reactor has to worry about and the - list of possible virtual functions we would have to override. */ -int -Client_Handler::handle_input (ACE_HANDLE handle) -{ - /* Some compilers don't like it when you fail to use a parameter. - This macro will keep 'em quiet for you. */ - ACE_UNUSED_ARG (handle); - - /* Now, we create and initialize a buffer for receiving the data. - Since this is just a simple test app, we'll use a small buffer - size. */ - char buf[BUFSIZ]; - - /* Invoke the process() method with a pointer to our data area. - We'll let that method worry about interfacing with the data. You - might choose to go ahead and read the data and then pass the - result to process(). However, application logic may require that - you read a few bytes to determine what else to read... It's best - if we push that all into the application-logic level. */ - return this->process (buf, sizeof (buf)); -} - -/* If we return -1 out of handle_input() or if the reactor sees other - problems with us then handle_close() will be called. The reactor - framework will take care of removing us (due to the -1), so we - don't need to use the destroy() method. Instead, we just delete - ourselves directly. */ -int -Client_Handler::handle_close (ACE_HANDLE handle, - ACE_Reactor_Mask mask) -{ - ACE_UNUSED_ARG (handle); - ACE_UNUSED_ARG (mask); - - delete this; - return 0; -} - -/* And, at last, we get to the application-logic level. Out of - everything we've done so far, this is the only thing that really - has anything to do with what your application will do. In this - method we will read and process the client's data. In a real - appliation, you will probably have a bit more in main() to deal - with command line options but after that point, all of the action - takes place here. */ -int -Client_Handler::process (char *rdbuf, - int rdbuf_len) -{ - ssize_t bytes_read = -1; - - /* Using the buffer provided for us, we read the data from the - client. If there is a read error (eg -- recv() returns -1) then - it's a pretty good bet that the connection is gone. Likewise, if - we read zero bytes then something wrong has happened. The - reactor wouldn't have called us if there wasn't some kind of read - activity but there wouldn't be activity if there were no bytes to - read... - - On the other hand, if we got some data then we can display it in - a debug message for everyone to see. */ - switch ( (bytes_read = this->peer ().recv (rdbuf, rdbuf_len)) ) - { - case -1: // Complain and leave - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) %p bad read\n", - "client"), - -1); - case 0: // Complain and leave - ACE_ERROR_RETURN ((LM_ERROR, - "(%P|%t) closing daemon (fd = %d)\n", - this->get_handle ()), - -1); - default: // Show the data - // NULL-terminate the string before printing it. - rdbuf[bytes_read] = 0; - ACE_DEBUG ((LM_DEBUG, - "(%P|%t) from client: %s", - rdbuf)); - } - - /* It's also worth mentioning that recv() has a cousin: recv_n(). - recv_n() will receive exactly the number of bytes you provide it. - This is very good when you know exactly how much you expect to - receive. For the application here, unfortunately, we don't have - any idea how much the client will be sending. recv() will read - up-to-but-not-more-than the number of bytes we specify (e.g. -- - _rdbuf_len). That works well when we don't know how much the - client will provide. */ - - return 0; -} diff --git a/docs/tutorials/022/client_handler.h b/docs/tutorials/022/client_handler.h deleted file mode 100644 index 03d3b1a8e10..00000000000 --- a/docs/tutorials/022/client_handler.h +++ /dev/null @@ -1,100 +0,0 @@ -// $Id$ - -#ifndef CLIENT_HANDLER_H -#define CLIENT_HANDLER_H - -/* 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 actual 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. */ - -#include "ace/Svc_Handler.h" - -#if !defined (ACE_LACKS_PRAGMA_ONCE) -# pragma once -#endif /* ACE_LACKS_PRAGMA_ONCE */ - -#include "ace/SOCK_Stream.h" - -/* 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. */ -class Client_Handler : public ACE_Svc_Handler <ACE_SOCK_STREAM, ACE_NULL_SYNCH> -{ -public: - // Constructor... - Client_Handler (void); - - /* 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. */ - void destroy (void); - - /* 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 an override. 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. */ - int open (void *acceptor); - - /* 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! */ - int handle_close (ACE_HANDLE handle, - ACE_Reactor_Mask mask); - -protected: - - /* 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 _handle 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 its 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. */ - int handle_input (ACE_HANDLE handle); - - /* 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 concurrency in later tutorials with no - changes to the worker function. You can think of process() as - application-level code and everything else as - application-framework code. */ - int process (char *rdbuf, int rdbuf_len); - - /* 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. */ - ~Client_Handler (void); -}; - -#endif /* CLIENT_HANDLER_H */ diff --git a/docs/tutorials/022/page01.html b/docs/tutorials/022/page01.html deleted file mode 100644 index 4bbb6ff8c40..00000000000 --- a/docs/tutorials/022/page01.html +++ /dev/null @@ -1,40 +0,0 @@ -<!-- $Id$ --> -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>ACE Tutorial 022</title> - </head> - - <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 022</FONT></B></CENTER> -<CENTER> <h1>Using Service Configurator Framework</h1> </CENTER> - - <P>When building distributed systems, there will almost certainly - be multiple processes or services running at all - times. It is helpful if these services can (re)configured and - control at installation-time or run-time. In this tutorial, we - illustrate how to configure services in a fine-grained manner, - rather than having to stop and restart all services in an application. </P> - - <P>The examples we show are based on the <A HREF="http://www.cs.wustl.edu/~schmidt/POSA/">Component Configurator</A> pattern, - which enables a service to be started, removed, suspended or resumed - dynamically. This pattern decouples the implementation of a - service from its (re)configuration. Thus, new services can be added or unnecessary services - can be suspended or removed.</P> - - <P>In this tutorial, we will use the simple server and client - which we developed and used in our tutorial 005 as the base and - modify it as needed.</P> - <P> - <P><HR WIDTH="100%"> - <CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page02.html">Continue This Tutorial</A>]</CENTER> - - <hr> - <address><a href="mailto:pgontla@ece.uci.edu">Priyanka Gontla</a></address> -<!-- Created: Thu Dec 28 14:19:26 PST 2000 --> -<!-- hhmts start --> -Last modified: Sat Jan 20 10:18:42 CST 2001 -<!-- hhmts end --> - </body> -</html> diff --git a/docs/tutorials/022/page02.html b/docs/tutorials/022/page02.html deleted file mode 100644 index 144a28112fd..00000000000 --- a/docs/tutorials/022/page02.html +++ /dev/null @@ -1,98 +0,0 @@ -<!-- $Id$ --> -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>ACE Tutorial 022</title> - </head> - - <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 022</FONT></B></CENTER> - We begin with <a href="server.cpp">server.cpp</a> - <UL> - <P>Abstract: - - We begin with the server and the acceptor which we developed in - our ACE Tutorial 005. We modify these and add new - implementation files so as to make the acceptor service dynamically - (un)loadable. What we want to do is separate the implementation - of the service from its configuration. So, our server will - now just act as a daemon waiting for requests. - We again enroll the services of the ACE_Reactor to handle - events. Everything occurs in a single thread. <P> - - This tutorial helps us learn apply the service configurator - pattern and make services dynamically configurable. In that - process, we are trying to make the acceptor we have developed - previously as a dynamically configurable service. - </UL> - <P> - <HR WIDTH="100%"> - <P> - <PRE> - <font color=red>/* We try to keep the server much simpler than before and - remove any thing related to the acceptor from the main (). - This lets keep the server running irrespective of the - state of the acceptor service. */ - </font> - <font color=red>/* As always, we would need the - ACE_Service_Config to help run the server as a daemon. */ </font> - <font color=blue>#include </font><font color=green>"ace/Service_Config.h"</font> - - <font color=red>/* Since we are seperating the acceptor service class from the - server, we need to declare our Acceptor_Service */ </font> - <font color=blue>#include </font><font color=green>"Acceptor_Service.h"</font> - - int - main (int argc, char *argv []) - { - <font color=red> - /* Perform daemon services update ... this opens the svc.conf - file and reads the entries present in the svc.conf - file. We will later learn the syntax of making an entry - into a svc.conf file. But for now, remember that this is a - file which has the entries to load or unload a service - dynamically or statically. */ - - In case, the function call returns a (-1), which is - indicative of an error, we print out a debug statement - and return (-1) to indicate an failure.</font> - if (ACE_Service_Config::open (argc, - argv, - ACE_DEFAULT_LOGGER_KEY, - 0) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "ACE_Service_Config::open"), - -1); - - <font color=red> - /* Install our signal handler. As we already know, you can actually - register signal handlers with the reactor. You might do that - when the signal handler is responsible for performing "real" - work. Our simple flag-setter doesn't justify deriving from - ACE_Event_Handler and providing a callback function - though. */ </font> - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGHUP); - - <font color=red> - /* Start running the event loop so that it - listens for events and acts accordingly. This event loop will run - either the event loop is ended explicitly or an error - occurs. */ </font> - ACE_Reactor::run_event_loop (); - - <font color=red>/* NOT REACHED */</font> - } -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page03.html">Continue This Tutorial</A>]</CENTER> - - <hr> - <address><a href="mailto:pgontla@ece.uci.edu">Priyanka Gontla</a></address> -<!-- Created: Thu Dec 28 15:17:34 PST 2000 --> -<!-- hhmts start --> -Last modified: Sat Jan 20 10:19:22 CST 2001 -<!-- hhmts end --> - </body> -</html> diff --git a/docs/tutorials/022/page03.html b/docs/tutorials/022/page03.html deleted file mode 100644 index 4a095ae9a8f..00000000000 --- a/docs/tutorials/022/page03.html +++ /dev/null @@ -1,123 +0,0 @@ -<!-- $Id$ --> -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>ACE Tutorial 022</title> - </head> - - <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 022</FONT></B></CENTER> - Now, lets implement the Acceptor Service. As the first step, let - us take a look at <I><A HREF="Acceptor_Service.h">Acceptor_Service.h</A></I>. - -<P> -<HR WIDTH="100%"> -<PRE> -<font color=red>// $Id$</font> - -<font color=blue>#ifndef</font> <font color=purple>ACCEPTOR_SERVICE_H</font> -<font color=blue>#define</font> <font color=purple>ACCEPTOR_SERVICE_H</font> - -<font color=red>/* The ACE_Acceptor<> template lives in the ace/Acceptor.h header - file. */</font> - -<font color=blue>#include</font> "<A HREF="../../../ace/Acceptor.h">ace/Acceptor.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=red>/* Since we want to work with sockets, we'll need a SOCK_Acceptor to - allow the clients to connect to us. */</font> -<font color=blue>#include</font> "<A HREF="../../../ace/SOCK_Acceptor.h">ace/SOCK_Acceptor.h</A>" - -<font color=red>/* The Client_Handler object we develop will be used to handle clients - once they're connected. The ACE_Acceptor<> template's first - parameter requires such an object. In some cases, you can get by - with just a forward declaration on the class, in others you have to - have the whole thing. */</font> -<font color=blue>#include</font> "<font color=green>client_handler.h</font>" - -<font color=red>/* In our original simple server, we instantiated a - ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> object. We can - make it much simpler and efficient by inheriting our - Acceptor_Service from ACE_Acceptor itself. - - Our Acceptor_Service class also needs to inherit from - ACE_Service_Object. ACE_Service_Object is an abstract class which - includes methods called by the Service Configurator framework to - start, remove, suspend or resume our service. - - You might have noticed that we didnt explicitly inherit from - ACE_Service_Object here. That is because, ACE_Acceptor derives from - ACE_Service_Object and hence there is no explicitly specify it. */ - - /* TO Do: Describe what/why ACE_Svc_Export */ - We use the ACE_Svc_Export macro to export the symbols from the -library on Win.</font> -class ACE_Svc_Export Acceptor_Service : public ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> -{ - public: - <font color=red> // Constructor </font> - Acceptor_Service (void); - - <font color=red> // Destructor </font> - ~Acceptor_Service (void); - - <font color=red>/* This method is the one which is called by the Service - Configurator Framework to initialize or start the service. */ </font> - virtual int init (int argc, char *argv[]); - - <font color=red>/* Called by the Service Configurator framework to remove this - Service. */ </font> - virtual int fini (void); - - <font color=red>/* You could easily guess that this method is called to suspend the - service by the same Service Configurator Framework. When in the - suspend mode, the service is not removed completely and is *still - there*. The difference is that the service is not in a active - state and doesnot accept requests.*/ </font> - virtual int suspend (void); - - <font color=red> /* And your guess that this method is called to resume the service - is also right. This call brings the service back to the - active state and the service is all ready to accept requests */ </font> - virtual int resume (void); - -}; - -<font color=red>/* The following macros and similar macros which we - will use in the implementation file later are used to define helper - functions for the Service Configurator. As we can easily guess, these - macros are intended to dynamically load ancd configure services using - the svc.conf file. These macros will also help to dynamically configure - even the statically linked services. */</font> - -<font color=red>/* This macro is used to declare a data structure - required to register a statically linked service into the service - configurator. As you can see it has only one argument which is the - name of the class that implements this service... so - Acceptor_Service in our case. */</font> -ACE_STATIC_SVC_DECLARE (Acceptor_Service) - -<font color=red>/* Once the service implementation is dynamically loaded, the Service - Configurator uses a factory method to create the object. This - macro declares such a factory function with the proper interface - and export macros. */</font> -ACE_SVC_FACTORY_DECLARE (Acceptor_Service) - -#include "ace/post.h" -<font color=blue>#endif</font> <<font color=red> /* ACCEPTOR_SERVICE_H */</font> -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page04.html">Continue This Tutorial</A>]</CENTER> - - <hr> - <address><a href="mailto:pgontla@ece.uci.edu">Priyanka Gontla</a></address> -<!-- Created: Thu Jan 18 17:46:58 PST 2001 --> -<!-- hhmts start --> -Last modified: Fri Jan 19 11:38:39 PST 2001 -<!-- hhmts end --> - </body> -</html> diff --git a/docs/tutorials/022/page04.html b/docs/tutorials/022/page04.html deleted file mode 100644 index eae9d24fef4..00000000000 --- a/docs/tutorials/022/page04.html +++ /dev/null @@ -1,177 +0,0 @@ -<!-- $Id$ --> -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>ACE Tutorial 022</title> - </head> - - <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 022</FONT></B></CENTER> -<pre> -<font color=red>/* Now that we know the interface, lets proceed to its - implementation. We obviosuly want to include the corresponding header - file. */</font> -<font color=blue>#include</font> "<A - HREF="Acceptor_Service.h">Acceptor_Service.h</A>" - -<font color=red>/* A server has to listen for clients at a known - TCP/IP port. The default ACE port is 10002 (at least on my - system) and that's good enough for what we want to do here. - Obviously, a more robust application would take a command line - parameter or read from a configuration file or do some other - clever thing. Just like the signal handler above, though, - that's not what we want to focus on, so we're taking the easy - way out. */</font> - -static const u_short PORT = ACE_DEFAULT_SERVER_PORT; - -<font color=red>/* As in all our simple tutorials, our contructor also does nothing */</font> -Acceptor_Service::Acceptor_Service (void) -{ - <font color=red>// Constructor</font> -} - -<font color=red>/* Same in the destructor case */</font> -Acceptor_Service::~Acceptor_Service (void) -{ - <font color=red>// Destructor</font> -} - -<font color=red>/* This is the virtual method inherited from ACE_Service_Object. This - method is called to initialize the service. In a generic sense, we - initialize everything that is needed to initialize our service - here. Ofcourse we need to do that only if there are not already - initialized. One important point to note here is that we have to - make sure that everything that is initialized here is actually - removed when the service is shutdown */</font> -int -Acceptor_Service::init (int argc, char *argv[]) -{ - <font color=red>/* As you will see, we will not be using argc and - argv here and hence declare them to be unused variables. This - helps us from the complaints from the picky compilers about - unused variables. */</font> - ACE_UNUSED_ARG (argc); - ACE_UNUSED_ARG (argv); - - <font color=red>/* Lets have a debug statement so that we can know that our - Acceptor_Service will be initialized soon */</font> - ACE_DEBUG ((LM_DEBUG, - "Starting the Acceptor_Service\n")); - - <font color=red>/* Create an ACE_INET_Addr that represents our endpoint of a - connection. We then open our acceptor object with that Addr. - Doing so tells the acceptor where to listen for connections. - Servers generally listen at "well known" addresses. If not, there - must be some mechanism by which the client is informed of the - server's address. */</font> - if (this->open (ACE_INET_Addr (PORT), - ACE_Reactor::instance ()) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "open"), - -1); - return 0; -} - -<font color=red>/* This virtual method will be invoked when we pass - a directive to the service configurator framework to remove - our service. Remember the threads and anything else that are - initialized in the init method and remove each of them. If we - leave anything that we initialized still running after this - method is invoked ...well .. you know what happens :-) */ </font> -int -Acceptor_Service::fini (void) -{ - <font color=red> /* Lets have another debug statement to inform us the state of the - service. */</font> - ACE_DEBUG ((LM_DEBUG, - "Closing down the Acceptor_Service\n")); - - <font color=red> /* Now, lets see what did we start or initialize during the - initialization process. The only thing that we did was opening - our Acceptor to start listening for requests. So, lets close it - down. */</font> - this->close (); - - return 0; -} - - <font color=red>/* Now, lets see how we can suspend the service that we initialized - and is running. By suspension, we mean that the Reactor still knows - about the service and receives the requests. But, it just keeps - quite even if there are any requests. It actually queues the - requests and sends them to the service once it is resumed.*/</font> -int -Acceptor_Service::suspend (void) -{ - <font color=red>/* You must be wondering, as I did, how we can simply suspend this - service without any complex method invocations. Thanks to our - ACE_Reactor class, we can actually suspend the service by just - invoking the following method and passing a pointer to ourself. - This method actually takes care of all the particulars for - suspending the services and keeps us happy. */</font> - ACE_Reactor::instance ()->suspend_handler (this); - return 0; -} - -int -Acceptor_Service::resume (void) -{ - <font color=red> /* I had the same question again ... how do I do this ?? As before, - our ACE_Reactor class came to a help with this method. ACE - classes do make life simpler .. don't they !! */</font> - ACE_Reactor::instance ()->resume_handler (this); - - return 0; -} - -<font color=red>/* The macro to be used to define the factory method - and destructor for our dynamically loadable service. */ </font> -ACE_SVC_FACTORY_DEFINE (Acceptor_Service) - -<font color=red>/* This macro helps to register a statically linked - service into the service configurator. It is defined in ace/OS.h. All - the parameters needed by the service configurator to build and control the - statically linked servuce are configured in a single structure. An - instance of this structure is statically initialized using this - macro. The First parameter is SERVICE_CLASS i.e. the name of the - class that implements the service. As we did implicitly, this class - must derive from ACE_Service_Configurator. The second parameter is - the NAME of the service. This name is used by the service - configurator to match the configuration options provided in the - svc.conf file. The third parameter is the type of the object which - could be either streams or service objects. The next parameter is - the name of the factory function which we defined in our header - file and above using the macros ACE_FACTORY_DECLARE and - ACE_FACTORY_DEFINE. The fifth parameter are a set of options or - flags which are used to control the ownership and life cycle of the - object. The final argument helps us to choose if we want a new - thread for this service. If the argument is not 0, a thread will be - dedicated to this service. .. lots of parameters .. Huh !! */ </font> -ACE_STATIC_SVC_DEFINE (Acceptor_Service, - ACE_TEXT ("Acceptor_Service"), - ACE_SVC_OBJ_T, - &ACE_SVC_NAME (Acceptor_Service), - ACE_Service_Type::DELETE_THIS | ACE_Service_Type::DELETE_OBJ, - 0) - -#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) -template class ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR>; -template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>; -#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) -#pragma instantiate ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> -#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH> -#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ -</PRE> -<P><HR WIDTH="100%"> -<CENTER>[<A HREF="../online-tutorials.html">Tutorial Index</A>] [<A HREF="page05.html">Continue This Tutorial</A>]</CENTER> - <hr> - <address><a href="mailto:pgontla@ece.uci.edu">Priyanka Gontla</a></address> -<!-- Created: Thu Jan 18 18:24:15 PST 2001 --> -<!-- hhmts start --> -Last modified: Fri Jan 19 11:37:49 PST 2001 -<!-- hhmts end --> - </body> -</html> diff --git a/docs/tutorials/022/page05.html b/docs/tutorials/022/page05.html deleted file mode 100644 index 5b14622b2c4..00000000000 --- a/docs/tutorials/022/page05.html +++ /dev/null @@ -1,130 +0,0 @@ -<!-- $Id$ --> -<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> -<html> - <head> - <title>ACE Tutorial 022</title> - </head> - - <BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#000FFF" VLINK="#FF0F0F"> - -<CENTER><B><FONT SIZE=+2>ACE Tutorial 022</FONT></B></CENTER> - <p>So, by now we have implemented our Acceptor Service: known how to - initialize, remove, suspend and resume our service. We have the - server daemon set up to run to accept requests. The only thing - that is left is the client_handler. We need to declare and define - the Client_Handler object. We will use the same <I><A - HREF="../005/Client_Handler.h">Client_Handler.h</A></I> and - <I><A HREF="../005/Client_Hander.cpp">Client_Handler.cpp</A></I> - that we used in our ACE Tutorial 005.</p> - - <p>With this, we are done with everything that we want to get our - Acceptor Service dynamically configurable in addition to the - actual functionality of the Acceptor.</p> - - <p>To compile, we can use the same <I><A - HREF="../005/Makefile">Makefile</A></I> that we used - previously and make appropriate changes for the new files that - we added. You could use this <I><A HREF="Makefile">Makefile</A></I> - - <p>Now, lets compile it and be all set to configure our Acceptor - Service. Let us run our server to start acting as a daemon and - accept requests.</p> - - <pre>$ ./server </pre> - - <p>Obviously, we will want to load our service dynamically and see - if our Acceptor Service is running as we want it to. For this, - we need to make an entry in the svc.conf file. - - <p>The Service Configurator framework reads the entries in the - svc.conf file in the working directory by default. According to - the entries in the svc.con file, the framework does the - needful. You could use a different name for the file like - server.conf but in that case, we need to explicitly specify to - the application the configuration file that has to be read using - the <I>-ORBSvcconf</I> option. - - <p>Coming back to where we were, now we want to make an entry in - this svc.conf file to load our service. I will show you the - general format for this entry and then we will make our entry.</p> - - A dynamic service could be initialized as: - <pre>dynamic service_name type_of_service * location_of_shared_lib:name_of_object "parameters" </pre> - - and a static service is initialized as: -<pre> static service_name "parameters_sent_to_service_object" </pre> - - <p>Lets start making our entry. The first keyword specifies if this - is a dynamic service or a static one. Since we want our service - to be a dynamically configurable one, the first parameter in our - entry will be <I>dynamic</I>. The next parameter is the name of - the service that we want to be loaded. This is the same name - that we specified in the ACE_STATIC_SVC_DEFINE macro. Since our - service name is Acceptor_Service, that becomes the second - parameter of our entry. The next argument is the type of the - service .. as we know already, there are two options: - Stream or Service_Object. And, we declared our service to be a - <I>Service_Object</I> in the ACE_STATIC_SVC_DEFINE macro. So, that - becomes the next parameter. The next entry is the location of - the shared library which has our service and that is - Acceptor_Server according to our Makefile. The next parameter is - the name of the object and finally the list of parameters that - we want to pass to our service. So, we are now erady to make our - entry in the svc.conf file to initialize our service. - -<pre> dynamic Acceptor_Service Service_Object * ./Acceptor_Server:_make_Acceptor_Service () "" </pre> - - <p>Now, we want to reconfigure so that our service will be - initialized. This could be done by sending a signal which would - be received eventually by the Reactor listening for requests and - it would invoke the ACE_Service::reconfigure () method which - does the reconfiguration of the services. - - <pre>$ kill -1 PID_of_our_server </pre> - - Now, that we know how to initialize our service and actually - initialized the service .. we could check if our service is - working good. Ofcourse, the debug statements we left in the init - method would help .. but to double check !! For this purpose, we - can use the simple client which we used in our ACE Tutorial - 005. Just compile the <I><A - HREF="client/client.cpp">client.cpp</A></I> using this <A - HREF="client/Makefile">Makefile</A> and run it. You can see the - responses from the service. - - <p>Now, we can check if we can suspend and resume and finally - remove the service. The entries for these functionalities are - very simple unlike the initialization entry. - - <pre>$ suspend Acceptor_Service </pre> - <pre>$ resume Acceptor_Service </pre> - <pre>$ remove Acceptor_Service </pre> - - <p>Lets first suspend the service by commenting out the entry for - the initialization and making the new entry for suspension in - the svc.conf file. Now, send a signal as before. The Reactor - will receive this event and suspend the service. Just to double - check, you could run our client again and see the response. </p> - - <p>Now, to resume the service, the procedure is the same. Comment - out other entries and make the entry for the resumption of the - service. And finally, send a signal. Again, you could run the - client and see what is happening. But, even before running the - client, you must have noticed that as soon as you resumed the - service, you saw some response from the Acceptor_Service. This - is because, as I explained before, the Reactor will queue the - request when the service is in suspension mode and send the - service the queued requests as and when it is active again. - - <p>Finally, lets remove our service. - - <p>So, now we know how to implement a dynamically configurable - service and how to dynamically configure the service. </p> - <hr> - <address><a href="mailto:pgontla@ece.uci.edu">Priyanka Gontla</a></address> -<!-- Created: Fri Jan 19 10:19:46 PST 2001 --> -<!-- hhmts start --> -Last modified: Fri Jan 19 11:37:23 PST 2001 -<!-- hhmts end --> - </body> -</html> diff --git a/docs/tutorials/022/server.cpp b/docs/tutorials/022/server.cpp deleted file mode 100644 index 5c3bce4601e..00000000000 --- a/docs/tutorials/022/server.cpp +++ /dev/null @@ -1,56 +0,0 @@ -// $Id$ - -/* We try to keep the server much simpler than before and - remove any thing related to the acceptor or the handler - from the main (). This lets keep the server running irrespective of - the state of the acceptor service, in our case and any service in - the general case. */ - -/* We would need the ACE_Service_Config class as it provides an - application developers interface to the entire Service - Configuration Framework */ -#include "ace/Service_Config.h" - -/* Since we are seperating the acceptor service class from the - server, we need to declare our Acceptor_Service */ -#include "Acceptor_Service.h" - -extern "C" void handler (int) -{ - ACE_Service_Config::reconfig_occurred (1); -} - -int -main (int argc, char *argv[]) -{ - /* Perform daemon services update ... this opens the svc.conf - file and reads the entries present in the svc.conf - file. We will later learn the syntax of making an entry - into a svc.conf file. But for now, remember that this is a - file which has the entries to load or unload a service - dynamically or statically. */ - if (ACE_Service_Config::open (argc, - argv, - ACE_DEFAULT_LOGGER_KEY, - 0) == -1) - ACE_ERROR_RETURN ((LM_ERROR, - "%p\n", - "ACE_Service_Config::open"), - -1); - - /* Install our signal handler. As we already know, you can actually - register signal handlers with the reactor. You might do that - when the signal handler is responsible for performing "real" - work. Our simple flag-setter doesn't justify deriving from - ACE_Event_Handler and providing a callback function though. */ - ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGHUP); - - /* Start running the event loop so that it - listens for events and acts accordingly. This event loop will run - until either the event loop is ended explicitly or an error - occurs. */ - ACE_Reactor::run_event_loop (); - - /* NOT REACHED */ - -} diff --git a/docs/tutorials/022/svc.conf b/docs/tutorials/022/svc.conf deleted file mode 100644 index 1c3ae8eb8ce..00000000000 --- a/docs/tutorials/022/svc.conf +++ /dev/null @@ -1,9 +0,0 @@ -# $Id$ - - -#dynamic Acceptor_Service Service_Object * ./Acceptor_Server:_make_Acceptor_Service () "" - -#remove Acceptor_Service - -#suspend Acceptor_Service -#resume Acceptor_Service |