summaryrefslogtreecommitdiff
path: root/docs/tutorials/022
diff options
context:
space:
mode:
Diffstat (limited to 'docs/tutorials/022')
-rw-r--r--docs/tutorials/022/Acceptor_Service.cpp154
-rw-r--r--docs/tutorials/022/Acceptor_Service.h93
-rw-r--r--docs/tutorials/022/Makefile105
-rw-r--r--docs/tutorials/022/client/Makefile47
-rw-r--r--docs/tutorials/022/client/client.cpp216
-rw-r--r--docs/tutorials/022/client_handler.cpp225
-rw-r--r--docs/tutorials/022/client_handler.h100
-rw-r--r--docs/tutorials/022/page01.html40
-rw-r--r--docs/tutorials/022/page02.html98
-rw-r--r--docs/tutorials/022/page03.html123
-rw-r--r--docs/tutorials/022/page04.html177
-rw-r--r--docs/tutorials/022/page05.html130
-rw-r--r--docs/tutorials/022/server.cpp56
-rw-r--r--docs/tutorials/022/svc.conf9
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&lt;> 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&lt;> 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