[muscle] Re: CompleteSetupSystem questions.

  • From: "Jeremy Friesner" <jaf@xxxxxxxxxxxx>
  • To: muscle@xxxxxxxxxxxxx
  • Date: Tue, 26 Aug 2003 00:44:57 PDT (-0700)

> What does CompleteSetupSystem do=3F

Under some operating systems there are certain things that must be done
at program-startup-time and program-shutdown time.  For example,
under Windows it's important that WSAStartup() gets called before any
networking calls are made, and WSACleanup() is supposed to be called
when everything is done (okay, WSACleanup() isn't strictly necessary, but
it's a matter of principle with me ;^)).  

The easiest way to make sure these calls are made at the proper times
is to have a class with the startup calls in its constructor, and the shutdown
calls in its destructor.   Declaring an object of this class at the top of 
main()
ensures that the constructor and destructor are executed at the proper times.
 
> Say that you want an application that is both a server and a client running
> in separate threads. Where should you put your CompleteSetupSystem=3F 

It should always be declared as a local variable at the top of main().  
It doesn't need to be instantiated separately for other threads.  
(or at least, it shouldn't need to be)

> Is it
> common for both the client and the server, that is, should there be just one
> CompleteSetupSystem object in an application (or could we have as many as we
> want)=3F

There should always be exactly one SetupSystem object per process.
You can declare more than one, but there's no advantage to doing so
(if you look in SetupSystem.cpp, you'll see that there are static counter guards
set up so that the startup/shutdown calls are only executed once anyway)

> If there should be just one single instance of CompleteSetupSystem, why
> isn't it a Singleton=3F

A Singleton wouldn't work quite right AFAIK.   I know of two ways to
implement a Singleton.  Here is the first one:

// Hidden away in SetupSystem.cpp or somewhere....
static CompleteSetupSystem =5Fsystem;

The problem with the above is that the order in which =5Fsystem
will be initialized relative to other static variables is not well defined.
And since there is other MUSCLE code that depends on the proper
order-of-initialization, this doesn't work reliably.

The other way of doing a Singleton that I know if is this:

// Hidden away in SetupSystem.cpp or somewhere....
static CompleteSetupSystem * =5Fsystem =3D NULL;

CompleteSetupSystem * GetSetupSystem()
{
   if (=5Fsystem =3D=3D NULL) =5Fsystem =3D newnothrow CompleteSetupSystem;
   return =5Fsystem;
}

void FreeSetupSystem()
{
   delete =5Fsystem;
   =5Fsystem =3D NULL;
}

This is a bit better, but it means that the user has to remember to call 
GetSetupSystem() 
at the top of main(), and also he must remember to call FreeSetupSystem() at 
the end
of main().  That's two calls to remember instead of one, and also the user has 
to worry
about handling a possible out-of-memory condition in GetSetupSystem().  
Furthermore, some
programs might want to use just the threading API and not networking, or just
networking and not threading.  Under the current system, they could declare
a ThreadSetupSystem object or a NetworkSetupSystem object instead of a
CompleteSetupSystem object, and avoid the potential overhead of setup calls 
for features they won't be using anyway.  With a singleton pattern, that would 
be a 
little messier to implement.

Jeremy


Other related posts: