📄 ncbi_core.c
字号:
/* * =========================================================================== * PRODUCTION $Log: ncbi_core.c,v $ * PRODUCTION Revision 1000.0 2003/10/29 16:36:12 gouriano * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R6.14 * PRODUCTION * =========================================================================== *//* $Id: ncbi_core.c,v 1000.0 2003/10/29 16:36:12 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Author: Denis Vakatov * * File Description: * Types and code shared by all "ncbi_*.[ch]" modules. * */#include "ncbi_ansi_ext.h"#include <connect/ncbi_core.h>#include <stdlib.h>/****************************************************************************** * IO status */extern const char* IO_StatusStr(EIO_Status status){ static const char* s_StatusStr[eIO_Unknown+1] = { "Success", "Timeout", "Closed", "Interrupt", "Invalid argument", "Not supported", "Unknown" }; assert(status >= eIO_Success && status <= eIO_Unknown); return s_StatusStr[status];}/****************************************************************************** * MT locking *//* Check the validity of the MT locker */#define MT_LOCK_VALID \ assert(lk->ref_count && lk->magic_number == s_MT_LOCK_magic_number)/* MT locker data and callbacks */struct MT_LOCK_tag { unsigned int ref_count; /* reference counter */ void* user_data; /* for "handler()" and "cleanup()" */ FMT_LOCK_Handler handler; /* locking function */ FMT_LOCK_Cleanup cleanup; /* cleanup function */ unsigned int magic_number; /* used internally to make sure it's init'd */};static const unsigned int s_MT_LOCK_magic_number = 0x7A96283F;extern MT_LOCK MT_LOCK_Create(void* user_data, FMT_LOCK_Handler handler, FMT_LOCK_Cleanup cleanup){ MT_LOCK lk = (struct MT_LOCK_tag*) malloc(sizeof(struct MT_LOCK_tag)); lk->ref_count = 1; lk->user_data = user_data; lk->handler = handler; lk->cleanup = cleanup; lk->magic_number = s_MT_LOCK_magic_number; return lk;}extern MT_LOCK MT_LOCK_AddRef(MT_LOCK lk){ MT_LOCK_VALID; lk->ref_count++; return lk;}extern MT_LOCK MT_LOCK_Delete(MT_LOCK lk){ if ( !lk ) return 0; MT_LOCK_VALID; if ( --lk->ref_count ) return lk; if ( lk->handler ) { /* weak extra protection */ verify(lk->handler(lk->user_data, eMT_Lock)); verify(lk->handler(lk->user_data, eMT_Unlock)); } if ( lk->cleanup ) lk->cleanup(lk->user_data); lk->magic_number++; free(lk); return 0;}extern int/*bool*/ MT_LOCK_DoInternal(MT_LOCK lk, EMT_Lock how){ MT_LOCK_VALID; if ( lk->handler ) return lk->handler(lk->user_data, how); return -1 /* rightful non-doing */;}/****************************************************************************** * ERROR HANDLING and LOGGING *//* Lock/unlock the logger */#define LOG_LOCK_WRITE verify(MT_LOCK_Do(lg->mt_lock, eMT_Lock))#define LOG_LOCK_READ verify(MT_LOCK_Do(lg->mt_lock, eMT_LockRead))#define LOG_UNLOCK verify(MT_LOCK_Do(lg->mt_lock, eMT_Unlock))/* Check the validity of the logger */#define LOG_VALID \ assert(lg->ref_count && lg->magic_number == s_LOG_magic_number)/* Logger data and callbacks */struct LOG_tag { unsigned int ref_count; void* user_data; FLOG_Handler handler; FLOG_Cleanup cleanup; MT_LOCK mt_lock; unsigned int magic_number; /* used internally, to make sure it's init'd */};static const unsigned int s_LOG_magic_number = 0x3FB97156;extern const char* LOG_LevelStr(ELOG_Level level){ static const char* s_PostSeverityStr[eLOG_Fatal+1] = { "TRACE", "NOTE", "WARNING", "ERROR", "CRITICAL_ERROR", "FATAL_ERROR" }; return s_PostSeverityStr[level];}extern LOG LOG_Create(void* user_data, FLOG_Handler handler, FLOG_Cleanup cleanup, MT_LOCK mt_lock){ LOG lg = (struct LOG_tag*) malloc(sizeof(struct LOG_tag)); lg->ref_count = 1; lg->user_data = user_data; lg->handler = handler; lg->cleanup = cleanup; lg->mt_lock = mt_lock; lg->magic_number = s_LOG_magic_number; return lg;}extern void LOG_Reset(LOG lg, void* user_data, FLOG_Handler handler, FLOG_Cleanup cleanup){ LOG_LOCK_WRITE; LOG_VALID; if (lg->cleanup) lg->cleanup(lg->user_data); lg->user_data = user_data; lg->handler = handler; lg->cleanup = cleanup; LOG_UNLOCK;}extern LOG LOG_AddRef(LOG lg){ LOG_LOCK_WRITE; LOG_VALID; lg->ref_count++; LOG_UNLOCK; return lg;}extern LOG LOG_Delete(LOG lg){ if ( !lg ) return 0; LOG_LOCK_WRITE; LOG_VALID; if (lg->ref_count > 1) { lg->ref_count--; LOG_UNLOCK; return lg; } LOG_UNLOCK; LOG_Reset(lg, 0, 0, 0); lg->ref_count--; lg->magic_number++; if ( lg->mt_lock ) MT_LOCK_Delete(lg->mt_lock); free(lg); return 0;}extern void LOG_WriteInternal(LOG lg, ELOG_Level level, const char* module, const char* file, int line, const char* message, const void* raw_data, size_t raw_size){ if ( lg ) { LOG_LOCK_READ; LOG_VALID; assert(!raw_size || raw_data); if ( lg->handler ) { SLOG_Handler call_data; call_data.level = level; call_data.module = module; call_data.file = file; call_data.line = line; call_data.message = message; call_data.raw_data = raw_data; call_data.raw_size = raw_size; lg->handler(lg->user_data, &call_data); } LOG_UNLOCK; } /* unconditional exit/abort on fatal error */ if (level == eLOG_Fatal) {#if defined(NDEBUG) exit(1);#else abort();#endif }}/****************************************************************************** * REGISTRY *//* Lock/unlock the registry */#define REG_LOCK_WRITE verify(MT_LOCK_Do(rg->mt_lock, eMT_Lock))#define REG_LOCK_READ verify(MT_LOCK_Do(rg->mt_lock, eMT_LockRead))#define REG_UNLOCK verify(MT_LOCK_Do(rg->mt_lock, eMT_Unlock))/* Check the validity of the registry */#define REG_VALID \ assert(rg->ref_count && rg->magic_number == s_REG_magic_number)/* Logger data and callbacks */struct REG_tag { unsigned int ref_count; void* user_data; FREG_Get get; FREG_Set set; FREG_Cleanup cleanup; MT_LOCK mt_lock; unsigned int magic_number; /* used internally, to make sure it's init'd */};static const unsigned int s_REG_magic_number = 0xA921BC08;extern REG REG_Create(void* user_data, FREG_Get get, FREG_Set set, FREG_Cleanup cleanup, MT_LOCK mt_lock){ REG rg = (struct REG_tag*) malloc(sizeof(struct REG_tag)); rg->ref_count = 1; rg->user_data = user_data; rg->get = get; rg->set = set; rg->cleanup = cleanup; rg->mt_lock = mt_lock; rg->magic_number = s_REG_magic_number; return rg;}extern void REG_Reset(REG rg, void* user_data, FREG_Get get, FREG_Set set, FREG_Cleanup cleanup, int/*bool*/ do_cleanup){ REG_LOCK_WRITE; REG_VALID; if (do_cleanup && rg->cleanup) rg->cleanup(rg->user_data); rg->user_data = user_data; rg->get = get; rg->set = set; rg->cleanup = cleanup; REG_UNLOCK;}extern REG REG_AddRef(REG rg){ REG_LOCK_WRITE; REG_VALID; rg->ref_count++; REG_UNLOCK; return rg;}extern REG REG_Delete(REG rg){ if ( !rg ) return 0; REG_LOCK_WRITE; REG_VALID; if (rg->ref_count > 1) { rg->ref_count--; REG_UNLOCK; return rg; } REG_UNLOCK; REG_Reset(rg, 0, 0, 0, 0, 1/*true*/); rg->ref_count--; rg->magic_number++; if ( rg->mt_lock ) MT_LOCK_Delete(rg->mt_lock); free(rg); return 0;}extern char* REG_Get(REG rg, const char* section, const char* name, char* value, size_t value_size, const char* def_value){ if (value_size <= 0 || !value) return 0; if ( def_value ) strncpy0(value, def_value, value_size - 1); else *value = '\0'; if ( !rg ) return value; REG_LOCK_READ; REG_VALID; if ( rg->get ) rg->get(rg->user_data, section, name, value, value_size); REG_UNLOCK; return value;}extern void REG_Set(REG rg, const char* section, const char* name, const char* value, EREG_Storage storage){ if ( !rg ) return; REG_LOCK_READ; REG_VALID; if ( rg->set ) rg->set(rg->user_data, section, name, value, storage); REG_UNLOCK;}/* * --------------------------------------------------------------------------- * $Log: ncbi_core.c,v $ * Revision 1000.0 2003/10/29 16:36:12 gouriano * PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R6.14 * * Revision 6.14 2003/08/28 18:47:51 ucko * Revert previous hack (now handled another way) * * Revision 6.13 2003/08/27 12:32:30 ucko * Yet another attempt to work around the WorkShop lossage with k*Timeout. * * Revision 6.12 2003/05/05 20:17:17 lavr * LOG_WriteInternal() to require data ptr only if data size is not zero * * Revision 6.11 2003/02/20 17:52:12 lavr * Status verbal names changed not to have caps in the middle * * Revision 6.10 2002/10/28 15:42:48 lavr * Use "ncbi_ansi_ext.h" privately and use strncpy0() * * Revision 6.9 2002/08/13 19:30:13 lavr * Verbal representation of eIO_Interrupt; log moved to end * * Revision 6.8 2001/08/09 16:24:29 lavr * Remove last (unneeded) parameter from LOG_Reset() * * Revision 6.7 2001/04/25 20:52:29 vakatov * LOG_WriteInternal() -- abort on "eLOG_Fatal" even if no logging is set * * Revision 6.6 2001/01/11 16:42:32 lavr * Registry Get/Set methods got the 'user_data' argument, forgotten earlier * * Revision 6.5 2000/10/18 20:29:43 vakatov * REG_Get:: pass in the default value (rather than '\0') * * Revision 6.4 2000/06/23 19:34:43 vakatov * Added means to log binary data * * Revision 6.3 2000/05/30 23:21:36 vakatov * LOG_WriteInternal(): exit/abort on "eLOG_Fatal" * * Revision 6.2 2000/03/24 23:12:07 vakatov * Starting the development quasi-branch to implement CONN API. * All development is performed in the NCBI C++ tree only, while * the NCBI C tree still contains "frozen" (see the last revision) code. * * Revision 6.1 2000/02/23 22:36:16 vakatov * Initial revision * * =========================================================================== */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -