/*
* Copyright (c) 2001-2007 Hypertriton, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* Core initialization routines.
*/
#include
#include
#include
#include
#include
#include
#include
#ifdef AG_THREADS
#include
#include
#include
#endif
#include "core.h"
#include "config.h"
#include "dso.h"
#ifdef AG_NETWORK
#include "rcs.h"
#endif
#include
#include
#include
#ifdef AG_THREADS
pthread_mutexattr_t agRecursiveMutexAttr; /* Recursive mutex attributes */
#endif
AG_Config *agConfig; /* Global Agar config data */
void (*agAtexitFunc)(void) = NULL; /* User exit function */
void (*agAtexitFuncEv)(AG_Event *) = NULL; /* User exit handler */
char *agProgName = NULL; /* User program name */
int agVerbose = 0; /* Verbose console output */
int agTerminating = 0; /* Application is exiting */
int
AG_InitCore(const char *progname, Uint flags)
{
if (flags & AG_VERBOSE)
agVerbose = 1;
agProgName = Strdup(progname);
#ifdef ENABLE_NLS
bindtextdomain("agar", LOCALEDIR);
bind_textdomain_codeset("agar", "UTF-8");
textdomain("agar");
#endif
AG_InitError();
AG_GetCPUInfo(&agCPU);
#ifdef AG_THREADS
pthread_mutexattr_init(&agRecursiveMutexAttr);
# if defined(HAVE_PTHREAD_MUTEX_RECURSIVE_NP)
pthread_mutexattr_settype(&agRecursiveMutexAttr,
PTHREAD_MUTEX_RECURSIVE_NP);
# else
pthread_mutexattr_settype(&agRecursiveMutexAttr,
PTHREAD_MUTEX_RECURSIVE);
# endif
AG_MutexInitRecursive(&agDSOLock);
#endif /* AG_THREADS */
AG_InitClassTbl();
AG_RegisterClass(&agConfigClass);
#if defined(HAVE_GETTIMEOFDAY)
AG_SetTimeOps(&agTimeOps_gettimeofday);
#elif defined(_WIN32)
AG_SetTimeOps(&agTimeOps_win32);
#else
AG_SetTimeOps(&agTimeOps_dummy);
#endif
AG_InitTimeouts();
AG_DataSourceInitSubsystem();
if ((agConfig = malloc(sizeof(AG_Config))) == NULL) {
AG_SetError("Out of memory");
return (-1);
}
if (AG_ConfigInit(agConfig, flags) == -1) {
return (-1);
}
(void)AG_ObjectLoad(agConfig);
#ifdef AG_NETWORK
AG_InitNetwork(0);
#endif
return (0);
}
#ifdef AG_NETWORK
int
AG_InitNetwork(Uint flags)
{
AG_RcsInit();
return (0);
}
#endif /* AG_NETWORK */
/* Register a function to invoke in AG_Quit(). */
void
AG_AtExitFunc(void (*func)(void))
{
agAtexitFunc = func;
}
void
AG_AtExitFuncEv(void (*func)(AG_Event *))
{
agAtexitFuncEv = func;
}
/* Immediately terminate the application. */
void
AG_Quit(void)
{
AG_Destroy();
exit(0);
}
/* Clean up the resources allocated by Agar-Core. */
void
AG_Destroy(void)
{
if (agAtexitFunc != NULL) { agAtexitFunc(); }
if (agAtexitFuncEv != NULL) { agAtexitFuncEv(NULL); }
#ifdef AG_NETWORK
AG_RcsDestroy();
#endif
AG_ObjectDestroy(agConfig);
AG_DataSourceDestroySubsystem();
AG_DestroyTimeouts();
AG_DestroyError();
AG_DestroyClassTbl();
Free(agProgName);
}
void
AG_GetVersion(AG_AgarVersion *ver)
{
ver->major = AGAR_MAJOR_VERSION;
ver->minor = AGAR_MINOR_VERSION;
ver->patch = AGAR_PATCHLEVEL;
ver->release = RELEASE;
}