NCBI C++ ToolKit
ncbi_core.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_core.c 100000 2023-06-02 12:55:33Z lavr $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Author: Denis Vakatov, Anton Lavrentiev
27  *
28  * File Description:
29  * Types and code shared by all "ncbi_*.[ch]" modules.
30  *
31  */
32 
33 #include "ncbi_ansi_ext.h"
34 #include "ncbi_once.h"
35 #include "ncbi_priv.h"
36 #include <stdlib.h>
37 
38 #ifdef NCBI_OS_UNIX
39 # include <unistd.h>
40 #endif /*NCBI_OS_UNIX*/
41 
42 #ifdef NCBI_CXX_TOOLKIT
43 # if defined(NCBI_POSIX_THREADS)
44 # include <pthread.h>
45 # elif defined(NCBI_WIN32_THREADS)
46 # define WIN32_LEAN_AND_MEAN
47 # include <windows.h>
48 # endif
49 #endif /*NCBI_CXX_TOOLKIT*/
50 
51 
52 /******************************************************************************
53  * I/O status
54  */
55 
56 extern const char* IO_StatusStr(EIO_Status status)
57 {
58  static const char* kStatusStr[EIO_N_STATUS] = {
59  "Success",
60  "Timeout",
61  "",
62  "Interrupt",
63  "Invalid argument",
64  "Not supported",
65  "Unknown",
66  "Closed"
67  };
68 
69  assert(eIO_Success <= (int) status && (int) status < EIO_N_STATUS
70  && kStatusStr[status]);
71  return eIO_Success <= (int) status && (int) status < EIO_N_STATUS
72  ? kStatusStr[status]
73  : 0;
74 }
75 
76 
77 /******************************************************************************
78  * MT locking
79  */
80 
81 #define kMT_LOCK_magic 0x7A96283F
82 
83 /* Check the validity of an MT lock */
84 #define MT_LOCK_VALID(lk) assert((lk)->count && (lk)->magic == kMT_LOCK_magic)
85 
86 
87 /* MT-lock structure */
88 struct MT_LOCK_tag {
89  volatile unsigned int count; /* reference count */
90  void* data; /* for "handler()" and "cleanup()" */
91  FMT_LOCK_Handler handler; /* handler callback for [un]locking */
92  FMT_LOCK_Cleanup cleanup; /* cleanup callback for "data" */
93  unsigned int magic; /* internal consistency assurance */
94 };
95 
96 
97 #if defined(NCBI_CXX_TOOLKIT) && defined(NCBI_THREADS)
98 
99 # if defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER)
100 # define NCBI_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER
101 # elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP)
102 # define NCBI_RECURSIVE_MUTEX_INIT PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
103 # endif /*PTHREAD_RECURSIVE_MUTEX_INITIALIZER...*/
104 
105 /*ARGSUSED*/
106 static int/*bool*/ s_CORE_MT_Lock_default_handler(void* unused,
107  EMT_Lock action)
108 {
109 
110 # if defined(NCBI_POSIX_THREADS)
111 
112  static pthread_mutex_t sx_Mutex
113 # ifdef NCBI_RECURSIVE_MUTEX_INIT
114  = NCBI_RECURSIVE_MUTEX_INIT
115 # endif/*NCBI_RECURSIVE_MUTEX_INIT*/
116  ;
117 
118 # ifndef NCBI_RECURSIVE_MUTEX_INIT
119  static void* /*bool*/ sx_Init = 0/*false*/;
120  static int /*bool*/ sx_Inited = 0/*false*/;
121  if (CORE_Once(&sx_Init)) {
122  pthread_mutexattr_t attr;
123  pthread_mutexattr_init(&attr);
124  pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
125  pthread_mutex_init(&sx_Mutex, &attr);
126  pthread_mutexattr_destroy(&attr);
127  sx_Inited = 1; /*go!*/
128  } else while (!sx_Inited)
129  CORE_Msdelay(1/*ms*/); /*spin*/
130 # endif /*!NCBI_RECURSIVE_MUTEX_INIT*/
131 
132  switch (action) {
133  case eMT_Lock:
134  case eMT_LockRead:
135  return pthread_mutex_lock (&sx_Mutex) == 0 ? 1/*ok*/ : 0/*fail*/;
136  case eMT_Unlock:
137  return pthread_mutex_unlock (&sx_Mutex) == 0 ? 1/*ok*/ : 0/*fail*/;
138  case eMT_TryLock:
139  case eMT_TryLockRead:
140  return pthread_mutex_trylock(&sx_Mutex) == 0 ? 1/*ok*/ : 0/*fail*/;
141  }
142  return 0/*failure*/;
143 
144 # elif defined(NCBI_WIN32_THREADS)
145 
146  static CRITICAL_SECTION sx_Crit;
147  static LONG /*bool*/ sx_Init = 0/*false*/;
148  static int /*bool*/ sx_Inited = 0/*false*/;
149 
150  if (!InterlockedCompareExchange(&sx_Init, 1, 0)) {
151  InitializeCriticalSection(&sx_Crit);
152  sx_Inited = 1; /*go!*/
153  } else while (!sx_Inited)
154  CORE_Msdelay(1/*ms*/); /*spin*/
155 
156  switch (action) {
157  case eMT_Lock:
158  case eMT_LockRead:
159  EnterCriticalSection(&sx_Crit);
160  return 1/*success*/;
161  case eMT_Unlock:
162  LeaveCriticalSection(&sx_Crit);
163  return 1/*success*/;
164  case eMT_TryLock:
165  case eMT_TryLockRead:
166  return TryEnterCriticalSection(&sx_Crit) ? 1/*ok*/ : 0/*fail*/;
167  }
168  return 0/*failure*/;
169 
170 # else
171 
172  if (g_CORE_Log) {
173  static void* /*bool*/ sx_Once = 0/*false*/;
174  if (CORE_Once(&sx_Once))
175  CORE_LOG(eLOG_Critical, "Using uninitialized CORE MT-LOCK");
176  }
177  return -1/*not implemented*/;
178 
179 # endif /*NCBI_..._THREADS*/
180 }
181 
182 #endif /*NCBI_CXX_TOOLKIT && NCBI_THREADS*/
183 
184 
186  1/* ref count */,
187  0/* user data */,
188 #if defined(NCBI_CXX_TOOLKIT) && defined(NCBI_THREADS)
190 #else
191  0/* noop handler */,
192 #endif /*NCBI_CXX_TOOLKIT && NCBI_THREADS*/
193  0/* cleanup */,
195 };
196 
197 
199 (void* data,
202 {
203  MT_LOCK lk = (struct MT_LOCK_tag*) malloc(sizeof(struct MT_LOCK_tag));
204 
205  if (lk) {
206  lk->count = 1;
207  lk->data = data;
208  lk->handler = handler;
209  lk->cleanup = cleanup;
210  lk->magic = kMT_LOCK_magic;
211  // CORE_TRACEF(("MT_LOCK_Create(%p)", lk));
212  }
213  return lk;
214 }
215 
216 
218 {
219  if (lk) {
220  MT_LOCK_VALID(lk);
221  if (lk != &g_CORE_MT_Lock_default) {
222  // CORE_DEBUG_ARG(unsigned int count;)
223  MT_LOCK_Do(lk, eMT_Lock);
224  // CORE_DEBUG_ARG(count =)
225  ++lk->count;
226  MT_LOCK_Do(lk, eMT_Unlock);
227  // CORE_TRACEF(("MT_LOCK_AddRef(%p) = %u", lk, count));
228  } // CORE_DEBUG_ARG(else CORE_TRACE("MT_LOCK_AddRef(DEFAULT)");)
229  } // CORE_DEBUG_ARG(else CORE_TRACE("MT_LOCK_AddRef(NULL)");)
230  return lk;
231 }
232 
233 
235 {
236  if (lk) {
237  MT_LOCK_VALID(lk);
238  if (lk != &g_CORE_MT_Lock_default) {
239  unsigned int count;
240  if (lk->handler)
241  verify(lk->handler(lk->data, eMT_Lock));
242  count = --lk->count; /* NB: may invalidate MT_LOCK_VALID(lk) */
243  if (lk->handler)
244  verify(lk->handler(lk->data, eMT_Unlock));
245  // CORE_TRACEF(("MT_LOCK_Delete(%p) = %u", lk, count));
246  if (!count) {
247  if (lk->cleanup)
248  lk->cleanup(lk->data);
249 
250  lk->magic++;
251  free(lk);
252  lk = 0;
253  }
254  } // CORE_DEBUG_ARG(else CORE_TRACE("MT_LOCK_Delete(DEFAULT)");)
255  } // CORE_DEBUG_ARG(else CORE_TRACE("MT_LOCK_Delete(NULL)");)
256  return lk;
257 }
258 
259 
260 extern int/*bool*/ MT_LOCK_DoInternal(MT_LOCK lk, EMT_Lock how)
261 {
262  MT_LOCK_VALID(lk);
263  return lk->handler ? lk->handler(lk->data, how) : -1/*rightful non-doing*/;
264 }
265 
266 
267 
268 /******************************************************************************
269  * ERROR HANDLING and LOGGING
270  */
271 
272 #define kLOG_magic 0x3FB97156
273 
274 /* Check the validity of a logger */
275 #define LOG_VALID(lg) assert((lg)->count && (lg)->magic == kLOG_magic)
276 
277 /* Lock/unlock a logger */
278 #define LOG_LOCK_WRITE(lg) verify(MT_LOCK_Do((lg)->lock, eMT_Lock) != 0)
279 #define LOG_LOCK_READ(lg) verify(MT_LOCK_Do((lg)->lock, eMT_LockRead) != 0)
280 #define LOG_UNLOCK(lg) verify(MT_LOCK_Do((lg)->lock, eMT_Unlock) != 0)
281 
282 
283 /* Logger structure */
284 struct LOG_tag {
285  unsigned int count;
286  void* data;
290  unsigned int magic;
291 };
292 
293 
294 extern const char* LOG_LevelStr(ELOG_Level level)
295 {
296  static const char* kPostSeverityStr[eLOG_Fatal + 1] = {
297  "TRACE",
298  "NOTE",
299  "WARNING",
300  "ERROR",
301  "CRITICAL",
302  "FATAL"
303  };
304 
305  assert(eLOG_Trace <= level && level <= eLOG_Fatal);
306  return eLOG_Trace <= level && level <= eLOG_Fatal
307  ? kPostSeverityStr[level]
308  : 0;
309 }
310 
311 
313 (void* data,
316  MT_LOCK lock)
317 {
318  LOG lg = (struct LOG_tag*) malloc(sizeof(struct LOG_tag));
319 
320  if (lg) {
321  lg->count = 1;
322  lg->data = data;
323  lg->handler = handler;
324  lg->cleanup = cleanup;
325  lg->lock = MT_LOCK_AddRef(lock);
326  lg->magic = kLOG_magic;
327  }
328  return lg;
329 }
330 
331 
333 (LOG lg,
334  void* data,
337 {
338  LOG_LOCK_WRITE(lg);
339  LOG_VALID(lg);
340 
341  if (lg->cleanup)
342  lg->cleanup(lg->data);
343 
344  lg->data = data;
345  lg->handler = handler;
346  lg->cleanup = cleanup;
347 
348  LOG_UNLOCK(lg);
349  return lg;
350 }
351 
352 
353 extern LOG LOG_AddRef(LOG lg)
354 {
355  LOG_LOCK_WRITE(lg);
356  LOG_VALID(lg);
357 
358  lg->count++;
359 
360  LOG_UNLOCK(lg);
361  return lg;
362 }
363 
364 
365 extern LOG LOG_Delete(LOG lg)
366 {
367  if (lg) {
368  LOG_LOCK_WRITE(lg);
369  LOG_VALID(lg);
370 
371  if (lg->count > 1) {
372  lg->count--;
373  LOG_UNLOCK(lg);
374  return lg;
375  }
376 
377  LOG_UNLOCK(lg);
378 
379  LOG_Reset(lg, 0, 0, 0);
380  lg->count--;
381  lg->magic++;
382 
383  MT_LOCK_Delete(lg->lock);
384  lg->lock = 0;
385  free(lg);
386  }
387  return 0;
388 }
389 
390 
391 extern void LOG_WriteInternal
392 (LOG lg,
393  const SLOG_Message* mess
394  )
395 {
396  assert(!mess->raw_size || mess->raw_data);
397 
398  if (lg) {
399  LOG_LOCK_READ(lg);
400  LOG_VALID(lg);
401 
402  if (lg->handler)
403  lg->handler(lg->data, mess);
404 
405  LOG_UNLOCK(lg);
406  }
407 
408  if (mess->dynamic && mess->message)
409  free((void*) mess->message);
410 
411  /* unconditional exit/abort on fatal error */
412  if (mess->level == eLOG_Fatal) {
413 #ifdef NDEBUG
414  fflush(0);
415  _exit(255);
416 #else
417  abort();
418 #endif /*NDEBUG*/
419  }
420 }
421 
422 
423 extern void LOG_Write
424 (LOG lg,
425  int code,
426  int subcode,
427  ELOG_Level level,
428  const char* module,
429  const char* func,
430  const char* file,
431  int line,
432  const char* message,
433  const void* raw_data,
434  size_t raw_size
435  )
436 {
437  SLOG_Message mess;
438 
439  mess.dynamic = 0;
440  mess.message = message;
441  mess.level = level;
442  mess.module = module;
443  mess.func = func;
444  mess.file = file;
445  mess.line = line;
446  mess.raw_data = raw_data;
447  mess.raw_size = raw_size;
448  mess.err_code = code;
449  mess.err_subcode = subcode;
450 
451  LOG_WriteInternal(lg, &mess);
452 }
453 
454 
455 
456 /******************************************************************************
457  * REGISTRY
458  */
459 
460 #define kREG_magic 0xA921BC08
461 
462 /* Check the validity of a registry */
463 #define REG_VALID(rg) assert((rg)->count && (rg)->magic == kREG_magic)
464 
465 /* Lock/unlock a registry */
466 #define REG_LOCK_WRITE(rg) verify(MT_LOCK_Do((rg)->lock, eMT_Lock) != 0)
467 #define REG_LOCK_READ(rg) verify(MT_LOCK_Do((rg)->lock, eMT_LockRead) != 0)
468 #define REG_UNLOCK(rg) verify(MT_LOCK_Do((rg)->lock, eMT_Unlock) != 0)
469 
470 
471 /* Registry structure */
472 struct REG_tag {
473  unsigned int count;
474  void* data;
479  unsigned int magic;
480 };
481 
482 
484 (void* data,
485  FREG_Get get,
486  FREG_Set set,
488  MT_LOCK lock)
489 {
490  REG rg = (struct REG_tag*) malloc(sizeof(struct REG_tag));
491 
492  if (rg) {
493  rg->count = 1;
494  rg->data = data;
495  rg->get = get;
496  rg->set = set;
497  rg->cleanup = cleanup;
498  rg->lock = MT_LOCK_AddRef(lock);
499  rg->magic = kREG_magic;
500  }
501  return rg;
502 }
503 
504 
505 extern void REG_Reset
506 (REG rg,
507  void* data,
508  FREG_Get get,
509  FREG_Set set,
511  int/*bool*/ do_cleanup)
512 {
513  REG_LOCK_WRITE(rg);
514  REG_VALID(rg);
515 
516  if (rg->cleanup && do_cleanup)
517  rg->cleanup(rg->data);
518 
519  rg->data = data;
520  rg->get = get;
521  rg->set = set;
522  rg->cleanup = cleanup;
523 
524  REG_UNLOCK(rg);
525 }
526 
527 
528 extern REG REG_AddRef(REG rg)
529 {
530  REG_LOCK_WRITE(rg);
531  REG_VALID(rg);
532 
533  rg->count++;
534 
535  REG_UNLOCK(rg);
536  return rg;
537 }
538 
539 
540 extern REG REG_Delete(REG rg)
541 {
542  if (rg) {
543  REG_LOCK_WRITE(rg);
544  REG_VALID(rg);
545 
546  if (rg->count > 1) {
547  rg->count--;
548  REG_UNLOCK(rg);
549  return rg;
550  }
551 
552  REG_UNLOCK(rg);
553 
554  REG_Reset(rg, 0, 0, 0, 0, 1/*true*/);
555  rg->count--;
556  rg->magic++;
557 
558  MT_LOCK_Delete(rg->lock);
559  rg->lock = 0;
560  free(rg);
561  }
562  return 0;
563 }
564 
565 
566 extern const char* REG_Get
567 (REG rg,
568  const char* section,
569  const char* name,
570  char* value,
571  size_t value_size,
572  const char* def_value)
573 {
574  int rv;
575  if (!value || value_size <= 0)
576  return 0/*failed*/;
577 
578  *value = '\0';
579  if (rg) {
580  REG_LOCK_READ(rg);
581  REG_VALID(rg);
582 
583  rv = (rg->get
584  ? rg->get(rg->data, section, name, value, value_size)
585  : -1/*default*/);
586 
587  REG_UNLOCK(rg);
588  } else
589  rv = -1/*default*/;
590 
591  if ((rv < 0 || !*value) && def_value && *def_value) {
592  size_t len = strlen(def_value);
593  if (len >= value_size) {
594  len = value_size - 1;
595  rv = 0;
596  } else
597  rv = 1;
598  strncpy0(value, def_value, len);
599  }
600  return rv ? value : 0;
601 }
602 
603 
604 extern int/*bool*/ REG_Set
605 (REG rg,
606  const char* section,
607  const char* name,
608  const char* value,
609  EREG_Storage storage)
610 {
611  int/*bool*/ rv;
612 
613  if (rg) {
614  REG_LOCK_READ(rg);
615  REG_VALID(rg);
616 
617  rv = (rg->set
618  ? rg->set(rg->data, section, name, value, storage)
619  : 0/*failed*/);
620 
621  REG_UNLOCK(rg);
622  } else
623  rv = 0/*failed*/;
624 
625  return rv;
626 }
Definition: set.hpp:45
void(*)(CSeq_entry_Handle seh, IWorkbench *wb, const CSerialObject &obj) handler
static void cleanup(void)
Definition: ct_dynamic.c:30
char data[12]
Definition: iconv.c:80
int(* FREG_Set)(void *data, const char *section, const char *name, const char *value, EREG_Storage storage)
Registry setter callback.
Definition: ncbi_core.h:589
ELOG_Level
Log severity level.
Definition: ncbi_core.h:292
int MT_LOCK_DoInternal(MT_LOCK lk, EMT_Lock how)
Definition: ncbi_core.c:260
ELOG_Level level
Definition: ncbi_core.h:341
MT_LOCK MT_LOCK_AddRef(MT_LOCK lk)
Increment internal reference count by 1, then return "lk".
Definition: ncbi_core.c:217
size_t raw_size
Definition: ncbi_core.h:347
EMT_Lock
Set the lock/unlock callback function and its data for MT critical section.
Definition: ncbi_core.h:180
const void * raw_data
Definition: ncbi_core.h:346
void(* FLOG_Handler)(void *data, const SLOG_Message *mess)
Log post callback.
Definition: ncbi_core.h:362
const char * file
Definition: ncbi_core.h:344
const char * REG_Get(REG rg, const char *section, const char *name, char *value, size_t value_size, const char *def_value)
Copy the registry value stored in "section" under name "name" to buffer "value"; if the entry is foun...
Definition: ncbi_core.c:567
REG REG_Delete(REG rg)
Decrement internal reference count by 1, and if it reaches 0, then call "rg->cleanup(rg->data)",...
Definition: ncbi_core.c:540
const char * module
Definition: ncbi_core.h:342
EREG_Storage
Transient/Persistent storage.
Definition: ncbi_core.h:528
REG REG_Create(void *data, FREG_Get get, FREG_Set set, FREG_Cleanup cleanup, MT_LOCK lock)
Create a new registry (with an internal reference count set to 1).
Definition: ncbi_core.c:484
int(* FMT_LOCK_Handler)(void *data, EMT_Lock how)
MT locking callback (operates like a [recursive] mutex or RW-lock).
Definition: ncbi_core.h:205
const char * func
Definition: ncbi_core.h:343
EIO_Status
I/O status.
Definition: ncbi_core.h:132
int err_subcode
Definition: ncbi_core.h:349
void REG_Reset(REG rg, void *data, FREG_Get get, FREG_Set set, FREG_Cleanup cleanup, int do_cleanup)
Reset the registry handle to use the new "data", "set", "get", and "cleanup".
Definition: ncbi_core.c:506
LOG LOG_AddRef(LOG lg)
Increment internal reference count by 1, then return "lg".
Definition: ncbi_core.c:353
void LOG_WriteInternal(LOG lg, const SLOG_Message *mess)
Write message (perhaps with raw data attached) to the log by calling "lg->handler(lg->data,...
Definition: ncbi_core.c:392
const char * IO_StatusStr(EIO_Status status)
Get the text form of an enum status value.
Definition: ncbi_core.c:56
LOG LOG_Create(void *data, FLOG_Handler handler, FLOG_Cleanup cleanup, MT_LOCK lock)
Create a new LOG (with an internal reference count set to 1).
Definition: ncbi_core.c:313
void LOG_Write(LOG lg, int code, int subcode, ELOG_Level level, const char *module, const char *func, const char *file, int line, const char *message, const void *raw_data, size_t raw_size)
Upon having filled SLOG_Message data from parameters, write a message (perhaps with raw data attached...
Definition: ncbi_core.c:424
MT_LOCK MT_LOCK_Delete(MT_LOCK lk)
Decrement internal reference count by 1, and if it reaches 0, then destroy the handle,...
Definition: ncbi_core.c:234
void CORE_Msdelay(unsigned long ms)
Delay execution of the current thread by the specified number of milliseconds.
Definition: ncbi_util.c:1019
int(* FREG_Get)(void *data, const char *section, const char *name, char *value, size_t value_size)
Registry getter callback.
Definition: ncbi_core.h:562
MT_LOCK MT_LOCK_Create(void *data, FMT_LOCK_Handler handler, FMT_LOCK_Cleanup cleanup)
Create a new MT lock (with an internal reference count set to 1).
Definition: ncbi_core.c:199
const char * message
Definition: ncbi_core.h:340
#define EIO_N_STATUS
connection is / has been closed, EOF condition
Definition: ncbi_core.h:141
LOG LOG_Reset(LOG lg, void *data, FLOG_Handler handler, FLOG_Cleanup cleanup)
Reset the "lg" to use the new "data", "handler" and "cleanup".
Definition: ncbi_core.c:333
const char * LOG_LevelStr(ELOG_Level level)
Obtain verbal representation of an enum level value.
Definition: ncbi_core.c:294
void(* FREG_Cleanup)(void *data)
Registry cleanup callback.
Definition: ncbi_core.h:604
#define MT_LOCK_Do(lk, how)
Call "lk->handler(lk->data, how)".
Definition: ncbi_core.h:270
REG REG_AddRef(REG rg)
Increment internal reference count by 1, then return "rg".
Definition: ncbi_core.c:528
LOG LOG_Delete(LOG lg)
Decrement internal reference count by 1, and if it reaches 0, then call "lg->cleanup(lg->data)",...
Definition: ncbi_core.c:365
void(* FMT_LOCK_Cleanup)(void *data)
MT lock cleanup callback.
Definition: ncbi_core.h:216
void(* FLOG_Cleanup)(void *data)
Log cleanup callback.
Definition: ncbi_core.h:375
int REG_Set(REG rg, const char *section, const char *name, const char *value, EREG_Storage storage)
Store the "value" into the registry section "section" under the key "name", and according to "storage...
Definition: ncbi_core.c:605
@ eLOG_Critical
Definition: ncbi_core.h:298
@ eLOG_Trace
Definition: ncbi_core.h:293
@ eLOG_Fatal
Definition: ncbi_core.h:299
@ eMT_Unlock
unlock critical section
Definition: ncbi_core.h:183
@ eMT_Lock
lock critical section
Definition: ncbi_core.h:181
@ eMT_LockRead
lock critical section for reading
Definition: ncbi_core.h:182
@ eMT_TryLock
try to lock, return immediately
Definition: ncbi_core.h:184
@ eMT_TryLockRead
try to lock for reading, return immediately
Definition: ncbi_core.h:185
@ eIO_Success
everything is fine, no error occurred
Definition: ncbi_core.h:133
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
FILE * file
int len
static const CS_INT unused
Definition: long_binary.c:20
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
char * strncpy0(char *s1, const char *s2, size_t n)
Copy not more than "n" characters from string "s2" into "s1", and return the result,...
#define verify(expr)
Definition: ncbi_assert.h:51
#define MT_LOCK_VALID(lk)
Definition: ncbi_core.c:84
#define REG_UNLOCK(rg)
Definition: ncbi_core.c:468
#define kLOG_magic
Definition: ncbi_core.c:272
#define kMT_LOCK_magic
Definition: ncbi_core.c:81
#define LOG_LOCK_WRITE(lg)
Definition: ncbi_core.c:278
#define REG_LOCK_READ(rg)
Definition: ncbi_core.c:467
#define REG_LOCK_WRITE(rg)
Definition: ncbi_core.c:466
#define kREG_magic
Definition: ncbi_core.c:460
#define LOG_UNLOCK(lg)
Definition: ncbi_core.c:280
#define REG_VALID(rg)
Definition: ncbi_core.c:463
static int s_CORE_MT_Lock_default_handler(void *unused, EMT_Lock action)
Definition: ncbi_core.c:106
#define LOG_LOCK_READ(lg)
Definition: ncbi_core.c:279
#define LOG_VALID(lg)
Definition: ncbi_core.c:275
struct MT_LOCK_tag g_CORE_MT_Lock_default
Definition: ncbi_core.c:185
#define CORE_Once(once)
Return non-zero (true) if "*once" had a value of NULL, and set the value to non-NULL regardless (best...
Definition: ncbi_once.h:47
LOG g_CORE_Log
Definition: ncbi_priv.c:49
#define CORE_LOG(level, message)
Definition: ncbi_priv.h:154
void abort()
#define assert(x)
Definition: srv_diag.hpp:58
FLOG_Handler handler
Definition: ncbi_core.c:287
unsigned int count
Definition: ncbi_core.c:285
void * data
Definition: ncbi_core.c:286
MT_LOCK lock
Definition: ncbi_core.c:289
unsigned int magic
Definition: ncbi_core.c:290
FLOG_Cleanup cleanup
Definition: ncbi_core.c:288
volatile unsigned int count
Definition: ncbi_core.c:89
void * data
Definition: ncbi_core.c:90
FMT_LOCK_Handler handler
Definition: ncbi_core.c:91
unsigned int magic
Definition: ncbi_core.c:93
FMT_LOCK_Cleanup cleanup
Definition: ncbi_core.c:92
FREG_Set set
Definition: ncbi_core.c:476
MT_LOCK lock
Definition: ncbi_core.c:478
FREG_Get get
Definition: ncbi_core.c:475
unsigned int magic
Definition: ncbi_core.c:479
unsigned int count
Definition: ncbi_core.c:473
void * data
Definition: ncbi_core.c:474
FREG_Cleanup cleanup
Definition: ncbi_core.c:477
Message and miscellaneous data to pass to log post callback FLOG_Handler.
Definition: ncbi_core.h:338
Definition: inftrees.h:24
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Sun Apr 21 03:40:42 2024 by modify_doxy.py rev. 669887