ggExit(3) Initialize and uninitialize LibGG

Other Alias



#include <ggi/gg.h>
int ggInit();
int ggExit();


ggInit initializes LibGG for use, allocates resources, examines the runtime environment for options, and performs initializations necessary to provide the LibGG API. This function must be called by the application (or by proxy by another library used by the application) and must return successfully before using any other LibGG function; otherwise the results of invoking LibGG API functions will be undefined.

ggInit allows multiple invocations. Unless ggExit is called as described below, subsequent calls to ggInit will do nothing other than increment a reference counter which LibGG uses to keep track of how many times it has been initialized. This allows using multiple libraries which call ggInit together without conflict.

ggExit decrements the reference counter which ggInit increments. Until this counter indicates that ggExit has been called as many times as ggInit it will do nothing else.

That is, to free resources used by LibGG, ggExit must be called as many times as ggInit has been called beforehand (including any calls made by libraries that depend on LibGG.) After ggExit returns 0, indicating LibGG is deinitialized, ggInit may be called again to reinitialize LibGG.

When ggExit determines that it has been called as many times as ggInit it performs the following actions (order is not guaranteed.) Any tasks scheduled with ggAddTask(3) are canceled (no task handlers will be called after ggExit returns.) Any cleanup handlers registered with ggRegisterCleanup(3) are invoked (no cleanup handlers will be called after ggExit returns.) If any cleanup handlers invoked ggCleanupForceExit(3), the current process will be terminated before ggExit returns. Otherwise, all resources used by LibGG are released for use by the application or operating system before ggExit returns. After the "last" ggExit is so invoked, any GG functions (including ggExit and ggInit) invoked will result in undefined, and probably undesirable, behavior. After ggExit returns 0, it is again safe to invoke ggInit.

ggInit and ggExit are threadsafe functions with a few small exceptions. First, do not call ggInit at the same time from two threads unless LibGG is already initialized. This is easily avoided by calling ggInit once before threads that might call it are started. Secondly, it is illegal to call ggExit after the "last" ggExit is invoked (note specifically, "invoked," not "has returned"). Naturally you must prevent threads from doing so, which is easy if you never call ggExit more times than ggInit. Finally, it is not safe to cancel a thread while it is calling either of the two functions.

ggInit and ggExit are not guaranteed to be safe to call in any special context, such as a signal handler or asyncronous procedure call. They are not safe to use in LibGG task handlers.

Note that, if ggInit is used in a library (like LibGII or LibGGI) and the application also calls ggInit itself, cleanup handlers installed by ggRegisterCleanup(3) may not execute when expected. See the ggRegisterCleanup(3) manpage for more detail on this subject. The same applies to cancelation of tasks scheduled with ggAddTask(3). See the ggAddTask(3) manpage for more detail on that subject.


ggInit returns:
  • GGI_OK on success;
  • GGI_EARGINVAL if the GG_OPTS variable is defined but the options could not be parsed correctly;
  • GGI_EUNKNOWN if the global libgg lock could not be created.

ggExit returns:

  • GGI_OK when LibGG has been completely, successfully, deinitialized;
  • >0 the number of open ggInit calls, if there has been more than one call to ggInit. As ggInit and ggExit must be used in properly nested pairs, for example, the first ggExit after two giiInit(3)s will return 1;
  • GGI_ENOTALLOC if ggExit has been invoked more times than ggInit has.