GlobalManager

© 2007 John Abbott
GNU Free Documentation License, Version 1.2



index page

User Documentation for GlobalManager

A GlobalManager object does some very simple management of (certain) global values used by CoCoALib (i.e. initialization and eventually destruction). So that the operations in CoCoALib can work properly you should create an object of type GlobalManager before using any other feature of CoCoALib. Conversely, the GlobalManager object should be destroyed only after you have finished using CoCoALib features. An easy way to achieve this is to create a local variable of type GlobalManager at the start of a top level procedure (e.g. main). See the CoCoALib examples.

Currently the GlobalManager class has only a default ctor; later it may be possible to specify some global settings as ctor arguments -- this would be primarily to aid debugging during development.

An exception will be thrown if you attempt to create more than one GlobalManager object (without having destroyed all earlier GlobalManagers). The exception is of type CoCoA::ErrorInfo and has error code ERR::GlobalManager2.

The concept of GlobalManager was created to handle in a clean and coherent manner (almost) all global values used by CoCoALib; in particular it was prompted by the decision to make the ring of integers a global value. The tricky part was ensuring the proper destruction of RingZ before main exits. Recall that C++ normally destroys globals after main has completed, and that the order of destruction cannot easily be governed; destroying values in the wrong order can cause to the program to crash just before it terminates. Another advantage of forcing destruction before main exits is that it makes debugging very much simpler (e.g. the MemPool object inside RingZImpl will be destroyed, thus allowing the MemPool destructor to perform all its checks). And of course it is simply good manners to clean up properly at the end of the program.

Maintenance notes for GlobalManager

To implement the restriction that only one GlobalManager may exist at any one time, the first instruction in the ctor checks that the global variable GlobalManager::ourGlobalDataPtr is null. If it is null, it is immediately set to point the object being constructed -- it is important that ourGlobalDataPtr be set before attempting to construct the rationals!

I chose to use std::auto_ptrs for the data members because I needed to have created and "registered" the ring of integers before attempting to construct the rationals. The excludes initializing a data member of type FractionField outside the body of the ctor. Use of a pointer allows construction of Q to be deferred, and use of an auto_ptr makes clean-up automatic. For consistency, I chose to implement Z using the same mechanism -- it also allows me to be quite explicit about construction order of data members inside the body of the ctor for GlobalManager.

The two functions MakeUniqueCopyOfRingZ and MakeUniqueCopyOfRingQ are supposed to be accessible only to GlobalManager; they create the unique copies of those two rings which will be stored in the global data. The functions are defined in RingZ.C and RingQ.C respectively but do not appear in the corresponding header files (thus supposedly making them "inaccessible" to other users). Note that the ring representing Z must be created and made accessible via ourGlobalDataPtr before MakeUniqueCopyOfRingQ is called. I know, this is a bit dirty/delicate; too bad, I can't see any simple and clean way of achieving what I want.

Bugs, Shortcomings, etc

There is a potential bug in dtor for GlobalManager: the global values are deregistered before they are destroyed. Might it be better to use raw ptrs and call delete explicitly? -- this would also make the order of destruction explicit.

Should the ctor for GlobalManager initialize the CoCoALib i/o streams?

Perhaps the GlobalManager ctor should accept an argument which would cause it to create a GMPAllocator?

You cannot print out a GlobalManager object; is this really a bug?

Potential race condition, if you try to create two GlobalManagers in parallel.

Should the ctor for GlobalManager set the globals which control debugging and verbosity in MemPools?