You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
282 lines
8.9 KiB
282 lines
8.9 KiB
/* /////////////////////////////////////////////////////////////////////////
|
|
* File: src/backends/be.N.c
|
|
*
|
|
* Purpose: Implementation of the Pantheios be.N Stock Back-end API.
|
|
*
|
|
* Created: 18th October 2006
|
|
* Updated: 27th December 2010
|
|
*
|
|
* Home: http://www.pantheios.org/
|
|
*
|
|
* Copyright (c) 2006-2010, Matthew Wilson and Synesis Software
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
*
|
|
* - Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* - 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.
|
|
* - Neither the name(s) of Matthew Wilson and Synesis Software nor the
|
|
* names of any contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* 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 COPYRIGHT OWNER 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.
|
|
*
|
|
* ////////////////////////////////////////////////////////////////////// */
|
|
|
|
|
|
#include <pantheios/pantheios.h>
|
|
#include <pantheios/backend.h>
|
|
#include <pantheios/frontend.h>
|
|
#include <pantheios/backends/be.N.h>
|
|
|
|
#include <pantheios/init_codes.h>
|
|
#include <pantheios/quality/contract.h>
|
|
|
|
/* /////////////////////////////////////////////////////////////////////////
|
|
* Helper functions
|
|
*/
|
|
|
|
static size_t pantheios_be_N_countBackEnds_everytime_(void);
|
|
static size_t pantheios_be_N_countBackEnds_onetime_(void);
|
|
|
|
|
|
static size_t pantheios_be_N_countBackEnds_(void)
|
|
{
|
|
return pantheios_be_N_countBackEnds_onetime_();
|
|
}
|
|
|
|
static size_t pantheios_be_N_countBackEnds_onetime_(void)
|
|
{
|
|
size_t const numBackEnds = pantheios_be_N_countBackEnds_everytime_();
|
|
|
|
return numBackEnds;
|
|
}
|
|
|
|
static size_t pantheios_be_N_countBackEnds_everytime_(void)
|
|
{
|
|
size_t n = 0;
|
|
pan_be_N_t* backEnd;
|
|
|
|
for(backEnd = &PAN_BE_N_BACKEND_LIST[0]; NULL != backEnd->pfnInit; ++n, ++backEnd)
|
|
{
|
|
PANTHEIOS_CONTRACT_ENFORCE_STATIC_DATA_APPL_DEF(((NULL == backEnd->pfnInit) == (NULL == backEnd->pfnUninit)), "back-end descriptor must specify all functions or none");
|
|
PANTHEIOS_CONTRACT_ENFORCE_STATIC_DATA_APPL_DEF(((NULL == backEnd->pfnInit) == (NULL == backEnd->pfnLogEntry)), "back-end descriptor must specify all functions or none");
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
/* /////////////////////////////////////////////////////////////////////////
|
|
* API
|
|
*/
|
|
|
|
PANTHEIOS_CALL(int) pantheios_be_init(
|
|
PAN_CHAR_T const* processIdentity
|
|
, void* reserved
|
|
, void** ptoken
|
|
)
|
|
{
|
|
size_t const numBackEnds = pantheios_be_N_countBackEnds_();
|
|
size_t n;
|
|
size_t numSucceeded = 0;
|
|
int res;
|
|
pan_be_N_t* terminalBackEnd = &PAN_BE_N_BACKEND_LIST[numBackEnds];
|
|
|
|
STLSOFT_SUPPRESS_UNUSED(reserved);
|
|
|
|
PANTHEIOS_CONTRACT_ENFORCE_PRECONDITION_PARAMS_API(NULL != ptoken, "token pointer may not be null");
|
|
|
|
*ptoken = NULL;
|
|
|
|
if(0 == numBackEnds)
|
|
{
|
|
res = PANTHEIOS_BE_INIT_RC_NO_BACKENDS_SPECIFIED;
|
|
}
|
|
else
|
|
{
|
|
res = 0;
|
|
|
|
for(n = 0; n < numBackEnds; ++n)
|
|
{
|
|
pan_be_N_t* backEnd = &PAN_BE_N_BACKEND_LIST[n];
|
|
|
|
PANTHEIOS_CONTRACT_ENFORCE_STATIC_DATA_APPL_DEF(0 != backEnd->backEndId, "be.N requires non-0 backEndId for all back-ends");
|
|
|
|
if(-1 == backEnd->backEndId)
|
|
{
|
|
backEnd->backEndId = pantheios_getNextBackEndId();
|
|
}
|
|
|
|
if( PANTHEIOS_BE_N_F_INIT_ONLY_IF_PREVIOUS_FAILED == (PANTHEIOS_BE_N_F_INIT_ONLY_IF_PREVIOUS_FAILED & backEnd->flags) &&
|
|
0 != numSucceeded)
|
|
{
|
|
backEnd->flags |= PANTHEIOS_BE_N_F_IGNORE_INIT_FAILURE;
|
|
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
res = (*backEnd->pfnInit)(processIdentity, backEnd->backEndId, NULL, NULL, &backEnd->token);
|
|
}
|
|
|
|
if(0 == res)
|
|
{
|
|
/* Initialisation of the given back-end has succeeded, so
|
|
* remove PANTHEIOS_BE_N_F_IGNORE_INIT_FAILURE, if present.
|
|
*/
|
|
backEnd->flags &= ~(PANTHEIOS_BE_N_F_IGNORE_INIT_FAILURE);
|
|
|
|
++numSucceeded;
|
|
|
|
if(terminalBackEnd->severityCeiling < backEnd->severityCeiling)
|
|
{
|
|
terminalBackEnd->severityCeiling = backEnd->severityCeiling;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(PANTHEIOS_BE_N_F_IGNORE_INIT_FAILURE & backEnd->flags)
|
|
{
|
|
/* Ignore failure. */
|
|
res = 0;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(0 != res)
|
|
{
|
|
for(; 0 != n; --n)
|
|
{
|
|
pan_be_N_t* backEnd = &PAN_BE_N_BACKEND_LIST[n - 1];
|
|
|
|
if(PANTHEIOS_BE_N_F_IGNORE_INIT_FAILURE & backEnd->flags)
|
|
{
|
|
/* Was not initialised. */
|
|
}
|
|
else
|
|
{
|
|
(*backEnd->pfnUninit)(backEnd->token);
|
|
}
|
|
}
|
|
}
|
|
else if(0 == numSucceeded)
|
|
{
|
|
res = PANTHEIOS_BE_INIT_RC_ALL_BACKEND_INITS_FAILED;
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
PANTHEIOS_CALL(void) pantheios_be_uninit(void* token)
|
|
{
|
|
size_t const numBackEnds = pantheios_be_N_countBackEnds_();
|
|
size_t n;
|
|
|
|
STLSOFT_SUPPRESS_UNUSED(token);
|
|
|
|
for(n = 0; n < numBackEnds; ++n)
|
|
{
|
|
pan_be_N_t* backEnd = &PAN_BE_N_BACKEND_LIST[n];
|
|
|
|
if(PANTHEIOS_BE_N_F_IGNORE_INIT_FAILURE & backEnd->flags)
|
|
{
|
|
/* Was not initialised. */
|
|
}
|
|
else
|
|
{
|
|
(*backEnd->pfnUninit)(backEnd->token);
|
|
}
|
|
}
|
|
}
|
|
|
|
PANTHEIOS_CALL(int) pantheios_be_logEntry(
|
|
void* feToken
|
|
, void* beToken
|
|
, int severity
|
|
, PAN_CHAR_T const* entry
|
|
, size_t cchEntry
|
|
)
|
|
{
|
|
int res = 0;
|
|
pan_be_N_t* backEnd;
|
|
int const severity4 = severity & 0x0f;
|
|
int const custom28 = (severity >> 4) & 0x0fffffff;
|
|
|
|
STLSOFT_SUPPRESS_UNUSED(beToken);
|
|
|
|
for(backEnd = &PAN_BE_N_BACKEND_LIST[0]; NULL != backEnd->pfnInit; ++backEnd)
|
|
{
|
|
if(PANTHEIOS_BE_N_F_IGNORE_INIT_FAILURE & backEnd->flags)
|
|
{
|
|
/* Was not initialised. */
|
|
}
|
|
else if(severity4 > backEnd->severityCeiling)
|
|
{
|
|
/* Statically filtered out */
|
|
}
|
|
else
|
|
{
|
|
/*
|
|
custom28 must-match ignore non-match
|
|
|
|
0 skip ok
|
|
== id ok ok
|
|
!= id skip skip
|
|
*/
|
|
|
|
if(custom28 != backEnd->backEndId)
|
|
{
|
|
/* If the custom28 does not match the back-end's id, we need to
|
|
* see if the back-end has special instructions.
|
|
*/
|
|
|
|
/* Test for PANTHEIOS_BE_N_F_ID_MUST_MATCH_CUSTOM28: skip mismatch'd output if specified. */
|
|
if(PANTHEIOS_BE_N_F_ID_MUST_MATCH_CUSTOM28 & backEnd->flags)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
/* Test for PANTHEIOS_BE_N_F_IGNORE_NONMATCHED_CUSTOM28_ID: skip if mismatched, and custom != 0 */
|
|
if( PANTHEIOS_BE_N_F_IGNORE_NONMATCHED_CUSTOM28_ID == (PANTHEIOS_BE_N_F_IGNORE_NONMATCHED_CUSTOM28_ID & backEnd->flags) &&
|
|
0 != custom28)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if(pantheios_fe_isSeverityLogged(feToken, severity, backEnd->backEndId))
|
|
{
|
|
int r2 = (*backEnd->pfnLogEntry)(feToken, backEnd->token, severity, entry, cchEntry);
|
|
|
|
if(0 != r2)
|
|
{
|
|
res = r2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
/* ///////////////////////////// end of file //////////////////////////// */
|