NCBI C++ ToolKit
ncbi_core_cxx.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: ncbi_core_cxx.cpp 102997 2024-08-19 13: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: Anton Lavrentiev
27  *
28  * File Description:
29  * C++->C conversion tools for basic CORE connect stuff:
30  * Registry
31  * Logging
32  * Locking
33  *
34  */
35 
36 #include <ncbi_pch.hpp>
37 #include "ncbi_ansi_ext.h"
38 #include "ncbi_socketp.h"
39 #include <corelib/ncbiapp.hpp>
40 #include <corelib/ncbidbg.hpp>
41 #include <corelib/ncbi_param.hpp>
42 #include <corelib/request_ctx.hpp>
44 #include <connect/error_codes.hpp>
46 #include <connect/ncbi_monkey.hpp>
47 #include <connect/ncbi_util.h>
48 #include <common/ncbi_sanitizers.h>
49 
50 #ifdef NCBI_POSIX_THREADS
51 #include <pthread.h>
52 #endif // NCBI_POSIX_THREADS
53 
54 #define NCBI_USE_ERRCODE_X Connect_Core
55 
56 
58 
59 
60 NCBI_PARAM_DECL (bool, CONN, TRACE_REG);
61 NCBI_PARAM_DEF_EX(bool, CONN, TRACE_REG, false, eParam_Default, CONN_TRACE_REG);
62 using TTraceReg = NCBI_PARAM_TYPE(CONN, TRACE_REG);
64 
65 NCBI_PARAM_DECL (bool, CONN, TRACE_LOG);
66 NCBI_PARAM_DEF_EX(bool, CONN, TRACE_LOG, false, eParam_Default, CONN_TRACE_LOG);
67 using TTraceLog = NCBI_PARAM_TYPE (CONN, TRACE_LOG);
69 
70 NCBI_PARAM_DECL (bool, CONN, TRACE_LOCK);
71 NCBI_PARAM_DEF_EX(bool, CONN, TRACE_LOCK, false, eParam_Default, CONN_TRACE_LOCK);
72 using TTraceLock = NCBI_PARAM_TYPE (CONN, TRACE_LOCK);
74 
75 
76 static TCORE_Set s_CORE_Set = 0;
77 
78 
79 /***********************************************************************
80  * Registry *
81  ***********************************************************************/
82 
83 
84 static string x_Reg(const char* section, const char* name,
85  const char* value = 0,
86  EREG_Storage storage = eREG_Transient)
87 {
88  string x_section;
89  if (section)
90  x_section = '[' + string(section) + ']';
91  else
92  x_section = "<NULL>";
93  string x_name;
94  if (name)
95  x_name = '"' + string(name) + '"';
96  else
97  x_name = "<NULL>";
98  string x_value;
99  if (value)
100  x_value = "=\"" + string(value) + '"';
101  string x_storage;
102  if (value) {
103  switch (int(storage)) {
104  case eREG_Transient:
105  x_storage = ", <Transient>";
106  break;
107  case eREG_Persistent:
108  x_storage = ", <Persistent>";
109  break;
110  default:
111  x_storage = ", <#" + NStr::IntToString(int(storage)) + '>';
112  break;
113  }
114  }
115  return x_section + x_name + x_value + x_storage;
116 }
117 
118 
119 extern "C" {
120 static int s_REG_Get(void* user_data,
121  const char* section, const char* name,
122  char* value, size_t value_size) THROWS_NONE
123 {
124  if (s_TraceReg->Get()) {
125  _TRACE("s_REG_Get(" + NStr::PtrToString(user_data) + ", "
126  + x_Reg(section, name) + ')');
127  }
128  int result = 0/*assume failure, including truncation*/;
129  try {
130  string item
131  = static_cast<const IRegistry*> (user_data)->Get(section, name);
132  if (!item.empty()) {
133  size_t len = item.size();
134  if (len >= value_size)
135  len = value_size - 1;
136  else
137  result = 1/*success*/;
138  strncpy0(value, item.data(), len);
139 
140  if (s_TraceReg->Get()) {
141  _TRACE("s_REG_Get(" + NStr::PtrToString(user_data) + ", "
142  + x_Reg(section, name) + ") = \"" + string(value)
143  + (result ? "\"" : "\" <Truncated>"));
144  }
145  } else
146  result = -1/*success,unmodified*/;
147  }
148  NCBI_CATCH_ALL_X(1, "s_REG_Get(" + NStr::PtrToString(user_data) + ", "
149  + x_Reg(section, name) + ") failed");
150  return result;
151 }
152 }
153 
154 
155 extern "C" {
156 static int s_REG_Set(void* user_data,
157  const char* section, const char* name,
158  const char* value, EREG_Storage storage) THROWS_NONE
159 {
160  if (s_TraceReg->Get()) {
161  _TRACE("s_REG_" + string(value ? "Set" : "Unset") + '('
162  + NStr::PtrToString(user_data) + ", "
163  + x_Reg(section, name, value ? value : "", storage) + ')');
164  }
165  int result = 0/*assume failure*/;
166  try {
167  IRWRegistry* reg = static_cast<IRWRegistry*> (user_data);
168  result = value
169  ? reg->Set (section, name, value,
170  (storage == eREG_Persistent
174  : reg->Unset(section, name,
175  (storage == eREG_Persistent
178  }
179  NCBI_CATCH_ALL_X(2, "s_REG_" + string(value ? "Set" : "Unset") + '('
180  + NStr::PtrToString(user_data) + ", "
181  + x_Reg(section, name, value ? value : "", storage)
182  + ") failed");
183  return result;
184 }
185 }
186 
187 
188 extern "C" {
189 static void s_REG_Cleanup(void* user_data) THROWS_NONE
190 {
191 
192  if (s_TraceReg->Get())
193  _TRACE("s_REG_Cleanup(" + NStr::PtrToString(user_data) + ')');
194  try {
195  static_cast<const IRegistry*> (user_data)->RemoveReference();
196  }
197  NCBI_CATCH_ALL_X(3, "s_REG_Cleanup("
198  + NStr::PtrToString(user_data) + ") failed");
199 }
200 }
201 
202 
203 extern REG REG_cxx2c(IRWRegistry* reg, bool pass_ownership)
204 {
205  if (s_TraceReg->Get())
206  _TRACE("REG_cxx2c(" + NStr::PtrToString(reg) + ')');
207  if (!reg)
208  return 0;
209  if (pass_ownership)
210  reg->AddReference();
211  return REG_Create(reg,
213  pass_ownership ? s_REG_Cleanup : 0, 0);
214 }
215 
216 
217 extern REG REG_cxx2c(const IRWRegistry* reg, bool pass_ownership)
218 {
219  if (s_TraceReg->Get())
220  _TRACE("REG_cxx2c(const " + NStr::PtrToString(reg) + ')');
221  if (!reg)
222  return 0;
223  if (pass_ownership)
224  reg->AddReference();
225  return REG_Create(const_cast<IRWRegistry*> (reg),
226  s_REG_Get, 0/*no setter*/,
227  pass_ownership ? s_REG_Cleanup : 0, 0);
228 }
229 
230 
231 /***********************************************************************
232  * Logger *
233  ***********************************************************************/
234 
235 
236 static string x_Log(ELOG_Level level)
237 {
238  string x_level;
239  switch (int(level)) {
240  case eLOG_Trace:
241  x_level = "Trace";
242  break;
243  case eLOG_Note:
244  x_level = "Note";
245  break;
246  case eLOG_Warning:
247  x_level = "Warning";
248  break;
249  case eLOG_Error:
250  x_level = "Error";
251  break;
252  case eLOG_Critical:
253  x_level = "Critical";
254  break;
255  case eLOG_Fatal:
256  x_level = "Fatal";
257  break;
258  default:
259  x_level = '#' + NStr::IntToString(int(level));
260  break;
261  }
262  return x_level;
263 }
264 
265 
266 extern "C" {
267 static void s_LOG_Handler(void* /*data*/,
268  const SLOG_Message* mess) THROWS_NONE
269 {
270  static const char kOutOfMemory[] = "Ouch! Out of memory";
271 
272  if (s_TraceLog->Get())
273  _TRACE("s_LOG_Handler(" + x_Log(mess->level) + ')');
274  try {
275  EDiagSev level;
276  switch (int(mess->level)) {
277  case eLOG_Trace:
278  level = eDiag_Trace;
279  break;
280  case eLOG_Note:
281  level = eDiag_Info;
282  break;
283  case eLOG_Warning:
284  level = eDiag_Warning;
285  break;
286  case eLOG_Error:
287  level = eDiag_Error;
288  break;
289  case eLOG_Critical:
290  level = eDiag_Critical;
291  break;
292  case eLOG_Fatal:
293  /*FALLTHRU*/
294  default:
295  level = eDiag_Fatal;
296  break;
297  }
298  if (level != eDiag_Fatal && !IsVisibleDiagPostLevel(level))
299  return;
300 
301  CDiagCompileInfo info(mess->file,
302  mess->line,
303  mess->func,
304  mess->module);
305  CNcbiDiag diag(info, level);
306  diag.SetErrorCode(mess->err_code, mess->err_subcode);
307  size_t message_len;
308  if (mess->message && *mess->message) {
309  message_len = strlen(mess->message);
310  do {
311  if (!isspace((unsigned char) mess->message[message_len - 1]))
312  break;
313  } while (--message_len > 0);
314  } else
315  message_len = mess->message ? 0 : sizeof(kOutOfMemory) - 1;
316  if (message_len)
317  diag << string(mess->message ? mess->message : kOutOfMemory, message_len);
318  if (mess->raw_size) {
322  if (mess->raw_data) {
323  buf.reset(new char[UTIL_PrintableStringSize
324  ((const char*)
325  mess->raw_data,
326  mess->raw_size)]);
327  char* end = UTIL_PrintableStringEx((const char*)
328  mess->raw_data,
329  mess->raw_size,
330  buf.get(), 0/*flags*/,
332  data.assign(buf.get(), (size_t)(end - buf.get()));
333  }
334  diag << "\n#################### [BEGIN] Raw Data ("
335  << mess->raw_size
336  << " byte" << &"s"[!(mess->raw_size != 1)] << "):"
337  << CTempString(data.empty() ? " <NULL>" : "\n") << data
338  << "\n#################### [_END_] Raw Data";
339  }
340  diag << Endm;
341  if (level == eDiag_Fatal)
342  Abort();
343  }
344  NCBI_CATCH_ALL_X(4, "s_LOG_Handler(" + x_Log(mess->level) + ") failed");
345 }
346 }
347 
348 
349 extern LOG LOG_cxx2c(void)
350 {
351  if (s_TraceLog->Get())
352  _TRACE("LOG_cxx2c()");
353  return LOG_Create(0, s_LOG_Handler, 0, 0);
354 }
355 
356 
357 /***********************************************************************
358  * MT-Lock *
359  ***********************************************************************/
360 
361 
362 static string x_Lock(EMT_Lock how)
363 {
364  string x_how;
365  switch (int(how)) {
366  case eMT_Lock:
367  x_how = "Lock";
368  break;
369  case eMT_LockRead:
370  x_how = "ReadLock";
371  break;
372  case eMT_Unlock:
373  x_how = "Unlock";
374  break;
375  case eMT_TryLock:
376  x_how = "TryLock";
377  break;
378  case eMT_TryLockRead:
379  x_how = "TryLockRead";
380  break;
381  default:
382  x_how = '#' + NStr::IntToString(int(how));
383  break;
384  }
385  return x_how;
386 }
387 
388 
389 extern "C" {
390 static int/*bool*/ s_LOCK_Handler(void* user_data, EMT_Lock how) THROWS_NONE
391 {
392  if (s_TraceLock->Get()) {
393  _TRACE("s_LOCK_Handler(" + NStr::PtrToString(user_data) + ", "
394  + x_Lock(how) + ')');
395  }
396  try {
397  CRWLock* lock = static_cast<CRWLock*> (user_data);
398  switch (int(how)) {
399  case eMT_Lock:
400  lock->WriteLock();
401  return 1/*success*/;
402  case eMT_LockRead:
403  lock->ReadLock();
404  return 1/*success*/;
405  case eMT_Unlock:
406  lock->Unlock();
407  return 1/*success*/;
408  case eMT_TryLock:
409  if (lock->TryWriteLock())
410  return 1/*success*/;
411  break;
412  case eMT_TryLockRead:
413  if (lock->TryReadLock())
414  return 1/*success*/;
415  break;
416  default:
417  NCBI_THROW(CCoreException, eCore, "Lock used with unknown op #"
418  + NStr::IntToString(int(how)));
419  }
420  }
421  NCBI_CATCH_ALL_X(5, "s_LOCK_Handler(" + NStr::PtrToString(user_data) + ", "
422  + x_Lock(how) + ") failed");
423  return 0/*failure*/;
424 }
425 }
426 
427 
428 extern "C" {
429 static void s_LOCK_Cleanup(void* user_data) THROWS_NONE
430 {
431  if (s_TraceLock->Get())
432  _TRACE("s_LOCK_Cleanup(" + NStr::PtrToString(user_data) + ')');
433  try {
434  delete static_cast<CRWLock*> (user_data);
435  }
436  NCBI_CATCH_ALL_X(6, "s_LOCK_Cleanup("
437  + NStr::PtrToString(user_data) + ") failed");
438 }
439 }
440 
441 
442 extern MT_LOCK MT_LOCK_cxx2c(CRWLock* lock, bool pass_ownership)
443 {
444  if (s_TraceLock->Get())
445  _TRACE("MT_LOCK_cxx2c(" + NStr::PtrToString(lock) + ')');
446  return MT_LOCK_Create(static_cast<void*> (lock ? lock : new CRWLock),
448  !lock || pass_ownership ? s_LOCK_Cleanup : 0);
449 }
450 
451 
452 /***********************************************************************
453  * App Name *
454  ***********************************************************************/
455 
456 
457 extern "C" {
458 static const char* s_GetAppName(void)
459 {
461  return app ? app->GetProgramDisplayName().c_str() : 0;
462 }
463 }
464 
465 
466 /***********************************************************************
467  * Referer *
468  ***********************************************************************/
469 
470 
471 extern "C" {
472 static const char* s_GetReferer(void)
473 {
474  const string& referer
476  return referer.empty() ? 0 : strdup(referer.c_str());
477 }
478 }
479 
480 
481 /***********************************************************************
482  * NCBI Request ID *
483  ***********************************************************************/
484 
485 
486 extern "C" {
487 static char* s_GetRequestID(ENcbiRequestID reqid)
488 {
489  string id;
490  switch (reqid) {
491  case eNcbiRequestID_SID:
492  if (!CDiagContext::GetRequestContext().IsSetSessionID())
495  break;
498  break;
499  default:
500  return 0;
501  }
502  return id.empty() ? 0 : strdup(id.c_str());
503 }
504 }
505 
506 
507 /***********************************************************************
508  * NCBI Request DTab *
509  ***********************************************************************/
510 
511 
512 extern "C" {
513 static const char* s_GetRequestDTab(void)
514 {
515  if (!CDiagContext::GetRequestContext().IsSetDtab())
517  return CDiagContext::GetRequestContext().GetDtab().c_str();
518 }
519 }
520 
521 
522 /***********************************************************************
523  * CRAZY MONKEY CALLS *
524  ***********************************************************************/
525 
526 
527 #ifdef NCBI_MONKEY
528 extern "C" {
529  static MONKEY_RETTYPE
530  MONKEY_STDCALL s_MonkeySend(MONKEY_SOCKTYPE sock,
531  const MONKEY_DATATYPE data,
532  MONKEY_LENTYPE size,
533  int flags,
534  void* /* SOCK* */ sock_ptr)
535  {
536  return CMonkey::Instance()->Send(sock, data, size, flags,
537  (SOCK*)sock_ptr);
538  }
539 
540  static MONKEY_RETTYPE
541  MONKEY_STDCALL s_MonkeyRecv(MONKEY_SOCKTYPE sock,
542  MONKEY_DATATYPE buf,
543  MONKEY_LENTYPE size,
544  int flags,
545  void* /* SOCK* */ sock_ptr)
546  {
547  return CMonkey::Instance()->Recv(sock, buf, size, flags,
548  (SOCK*) sock_ptr);
549  }
550 
551 
552  static int MONKEY_STDCALL s_MonkeyConnect(MONKEY_SOCKTYPE sock,
553  const struct sockaddr* name,
554  MONKEY_SOCKLENTYPE namelen)
555  {
556  return CMonkey::Instance()->Connect(sock, name, namelen);
557  }
558 
559 
560  static int /*bool*/ s_MonkeyPoll(size_t* n,
561  void* /* SSOCK_Poll** */ polls,
562  EIO_Status* return_status)
563  {
564  return CMonkey::Instance()->
565  Poll(n, (SSOCK_Poll**) polls, return_status) ? 1 : 0;
566  }
567 
568 
569  static void s_MonkeyClose(SOCKET sock)
570  {
571  CMonkey::Instance()->Close(sock);
572  }
573 
574 
575  static void s_MonkeySockHasSocket(void* /* SOCK* */ sock,
576  MONKEY_SOCKTYPE socket)
577  {
578  CMonkey::Instance()->SockHasSocket((SOCK)sock, socket);
579  }
580 }
581 
582 
583 static int s_MONKEY_Poll_dummy(size_t* n,
584  void* polls,
585  EIO_Status* return_status)
586 {
587  return 0; /* call was not intercepted by Monkey*/
588 }
589 
590 
591 static void s_MONKEY_Close_dummy(SOCKET sock)
592 {
593  return; /* call was not intercepted by Monkey*/
594 }
595 
596 
597 /* Chaos Monkey hooks for Connect library*/
598 static void s_SetMonkeyHooks(EMonkeyHookSwitch hook_switch)
599 {
600  switch (hook_switch)
601  {
602  case eMonkeyHookSwitch_Disabled:
603  g_MONKEY_Send = 0;
604  g_MONKEY_Recv = 0;
605  g_MONKEY_Connect = 0;
606  g_MONKEY_Poll = 0;
607  g_MONKEY_Close = 0;
608  g_MONKEY_SockHasSocket = 0;
609  break;
610  case eMonkeyHookSwitch_Enabled:
611  g_MONKEY_Send = s_MonkeySend;
612  g_MONKEY_Recv = s_MonkeyRecv;
613  g_MONKEY_Connect = s_MonkeyConnect;
614  g_MONKEY_Poll = s_MonkeyPoll;
615  g_MONKEY_Close = s_MonkeyClose;
616  g_MONKEY_SockHasSocket = s_MonkeySockHasSocket;
617  break;
618  default:
619  _TROUBLE;
620  break;
621  }
622 }
623 #endif //NCBI_MONKEY
624 
625 
626 #ifdef NCBI_POSIX_THREADS
627 extern "C" {
628 static void x_PreFork(void)
629 {
631 }
632 
633 static void x_PostFork(void)
634 {
635  CORE_UNLOCK;
636 }
637 } // extern "C"
638 #endif // NCBI_POSIX_THREADS
639 
640 
642  eConnectInit_Weak = -1, ///< CConn_Initer
643  eConnectInit_Intact = 0, ///< Not yet visited
644  eConnectInit_Strong = 1, ///< User init detected
645  eConnectInit_Explicit = 2 ///< CONNECT_Init() called
646 };
647 
648 static atomic<EConnectInit> s_ConnectInit = eConnectInit_Intact;
649 
650 
651 /***********************************************************************
652  * Fini *
653  ***********************************************************************/
654 
655 
656 extern "C" {
657 static void s_Fini(void) THROWS_NONE
658 {
659  _TRACE("CONNECT::s_Fini()");
661  if (s_CORE_Set & eCORE_SetSSL)
662  SOCK_SetupSSL(0);
663  if (s_CORE_Set & eCORE_SetREG)
664  CORE_SetREG(0);
665  if (s_CORE_Set & eCORE_SetLOG)
666  CORE_SetLOG(0);
668  CORE_SetLOCK(0);
670  s_CORE_Set = 0;
671 }
672 }
673 
674 
675 /***********************************************************************
676  * Init *
677  ***********************************************************************/
678 
679 
680 DEFINE_STATIC_FAST_MUTEX(s_ConnectInitMutex);
681 
682 /* NB: gets called under a lock */
683 static void s_Init(const IRWRegistry* reg = 0,
684  FSSLSetup ssl = 0,
685  CRWLock* lock = 0,
686  TConnectInitFlags flag = 0,
688 {
689  _TRACE("CONNECT::s_Init(reg="
690  + NStr::PtrToString(reg) + ", ssl="
691  + NStr::PtrToString((void*) ssl) + "(), lock="
692  + NStr::PtrToString(lock) + ", flag=0x"
693  + NStr::UIntToString((unsigned int) flag, 0, 16) + ", how="
694  + NStr::IntToString(int(how)) + ')');
696 
697  auto connect_init = s_ConnectInit.load(memory_order_acquire);
698  if (connect_init == how && how == eConnectInit_Explicit)
699  ERR_POST_X(11, "CONNECT_Init() called more than once");
700 
701  TCORE_Set x_set = 0;
702  if (!(g_CORE_Set & eCORE_SetLOCK)) {
705  x_set |= eCORE_SetLOCK;
706  }
707  if (!(g_CORE_Set & eCORE_SetLOG)) {
709  x_set |= eCORE_SetLOG;
710  }
711  if (!(g_CORE_Set & eCORE_SetREG)) {
713  x_set |= eCORE_SetREG;
714  }
715  if (!(g_CORE_Set & eCORE_SetSSL)) {
716  EIO_Status status = SOCK_SetupSSLInternalEx(ssl, 1/*init*/);
717  if (status != eIO_Success) {
718  ERR_POST_X(10, Critical << "Failed to initialize SSL: "
719  << IO_StatusStr(status));
720  }
721  if (ssl)
722  x_set |= eCORE_SetSSL;
723  }
724  g_CORE_Set &= ~x_set;
725  s_CORE_Set |= x_set;
726 
727  if (connect_init == eConnectInit_Intact) {
728  int err = 0;
730  = (unsigned int) time(0) ^ NCBI_CONNECT_SRAND_ADDEND;
732  if (x_set && atexit(s_Fini) != 0)
733  err |= 1;
734 #ifdef NCBI_POSIX_THREADS
735  if (pthread_atfork(x_PreFork, x_PostFork, x_PostFork) != 0)
736  err |= 2;
737 #endif // NCBI_POSIX_THREADS
738  if (err) {
739  static const char* what[] = {0, "exit", "fork", "exit/fork"};
741  << "Failed to register "
742  << what[err] << " handler" << &"s"[!(err == 3)]);
743  }
744  }
745 
750 
751 #ifdef NCBI_MONKEY
752  /* Allow CMonkey to switch hooks to Connect library */
753  CMonkey::MonkeyHookSwitchSet(s_SetMonkeyHooks);
754  /* Create CMonkey instance. It loads config and sets hooks */
755  CMonkey::Instance();
756 #endif //NCBI_MONKEY
757 
758  if (how < eConnectInit_Strong && g_CORE_Set)
759  how = eConnectInit_Strong;
760  if (connect_init < how || connect_init == eConnectInit_Intact)
761  s_ConnectInit.store(how, memory_order_release);
762 }
763 
764 
765 /* PUBLIC */
766 extern void CONNECT_Init(const IRWRegistry* reg,
767  CRWLock* lock,
768  TConnectInitFlags flag,
769  FSSLSetup ssl)
770 {
771  CFastMutexGuard guard(s_ConnectInitMutex);
772  _TRACE("CONNECT_Init(reg="
773  + NStr::PtrToString(reg) + ", lock="
774  + NStr::PtrToString(lock) + ", flag=0x"
775  + NStr::UIntToString((unsigned int) flag, 0, 16) + ", ssl="
776  + NStr::PtrToString((void*) ssl) + "())");
777  try {
778  g_CORE_Set = 0;
779  s_Init(reg, flag & eConnectInit_NoSSL ? 0 :
780  ssl ? ssl : NcbiSetupTls,
781  lock, flag, eConnectInit_Explicit);
782  }
783  NCBI_CATCH_ALL_X(8, "CONNECT_Init() failed");
784 }
785 
786 
788 {
789  auto connect_init = s_ConnectInit.load(memory_order_relaxed);
790  if (connect_init != eConnectInit_Intact)
791  return;
792  CFastMutexGuard guard(s_ConnectInitMutex);
793  try {
794  connect_init = s_ConnectInit.load(memory_order_acquire);
795  if (connect_init == eConnectInit_Intact) {
797  s_Init(app ? &app->GetConfig() : 0, NcbiSetupTls,
799  }
800  }
801  NCBI_CATCH_ALL_X(7, "CConn_Initer::CConn_Initer() failed");
802 }
803 
804 
AutoPtr –.
Definition: ncbimisc.hpp:401
CCoreException –.
Definition: ncbiexpt.hpp:1476
Incapsulate compile time information such as __FILE__, __LINE__, NCBI_MODULE, current function.
Definition: ncbidiag.hpp:65
CNcbiDiag –.
Definition: ncbidiag.hpp:924
CRWLock –.
Definition: ncbimtx.hpp:953
CSafeStatic<>::
CTempString implements a light-weight string on top of a storage buffer whose lifetime management is ...
Definition: tempstr.hpp:65
IRWRegistry –.
Definition: ncbireg.hpp:407
IRegistry –.
Definition: ncbireg.hpp:73
static uch flags
char data[12]
Definition: iconv.c:80
static CNcbiApplicationGuard InstanceGuard(void)
Singleton method.
Definition: ncbiapp.cpp:133
const CNcbiRegistry & GetConfig(void) const
Get the application's cached configuration parameters (read-only).
const string & GetProgramDisplayName(void) const
Get the application's "display" name.
string
Definition: cgiapp.hpp:690
#define _TRACE(message)
Definition: ncbidbg.hpp:122
string GetSessionID(void) const
Session ID.
void SetSessionID(const string &session)
const string & GetProperty(const string &name) const
Get property value or empty string.
const CNcbiDiag & SetErrorCode(int code=0, int subcode=0) const
Set error code and subcode numbers.
const string & GetNextSubHitID(CTempString prefix=CTempString())
Get current hit id appended with auto-incremented sub-hit id.
void SetDtab(const string &dtab)
bool IsVisibleDiagPostLevel(EDiagSev sev)
Check if the specified severity is higher or equal to the currently selected post level and will be p...
Definition: ncbidiag.cpp:6169
static CRequestContext & GetRequestContext(void)
Shortcut to CDiagContextThreadData::GetThreadData().GetRequestContext()
Definition: ncbidiag.cpp:1901
NCBI_XNCBI_EXPORT void Abort(void)
Smart abort function.
Definition: ncbidiag.cpp:8150
const string & GetDtab(void) const
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
EDiagSev
Severity level for the posted diagnostics.
Definition: ncbidiag.hpp:650
@ eDiag_Trace
Trace message.
Definition: ncbidiag.hpp:657
@ eDiag_Info
Informational message.
Definition: ncbidiag.hpp:651
@ eDiag_Error
Error message.
Definition: ncbidiag.hpp:653
@ eDiag_Warning
Warning message.
Definition: ncbidiag.hpp:652
@ eDiag_Fatal
Fatal error – guarantees exit(or abort)
Definition: ncbidiag.hpp:655
@ eDiag_Critical
Critical error message.
Definition: ncbidiag.hpp:654
void Critical(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1203
#define NCBI_CATCH_ALL_X(err_subcode, message)
Definition: ncbiexpt.hpp:619
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
#define THROWS_NONE
Do not use 'throw' dynamic exception specification for C++11 compilers.
Definition: ncbiexpt.hpp:74
void AddReference(void) const
Add reference to object.
Definition: ncbiobj.hpp:489
#define NCBI_PARAM_TYPE(section, name)
Generate typename for a parameter from its {section, name} attributes.
Definition: ncbi_param.hpp:149
@ eParam_Default
Default flags.
Definition: ncbi_param.hpp:416
bool Unset(const string &section, const string &name, TFlags flags=0)
Fully unset the configuration parameter value, so that HasEntry returns false.
Definition: ncbireg.cpp:867
bool Set(const string &section, const string &name, const string &value, TFlags flags=0, const string &comment=kEmptyStr)
Set the configuration parameter value.
Definition: ncbireg.cpp:826
@ fTruncate
Leading, trailing blanks can be truncated.
Definition: ncbireg.hpp:87
@ fPersistent
Persistent – saved when file is written.
Definition: ncbireg.hpp:84
@ fTransient
Transient – not saved by default.
Definition: ncbireg.hpp:83
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
SOCKSSL NcbiSetupTls(void)
Setup a TLS (Transport Layer Security) provider library to support SSL in ncbi_socket....
Definition: ncbi_tls.c:115
void SOCK_SetupSSL(FSSLSetup setup)
Store SSL setup callback until actual initialization.
Definition: ncbi_socket.c:8999
SOCKSSL(* FSSLSetup)(void)
SSL setup callback.
Definition: ncbi_socket.h:2312
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5078
static void PtrToString(string &out_str, const void *ptr)
Convert pointer to string.
Definition: ncbistr.cpp:2762
static string UIntToString(unsigned int value, TNumToStringFlags flags=0, int base=10)
Convert UInt to string.
Definition: ncbistr.hpp:5103
void ReadLock(void)
Read lock.
Definition: ncbimtx.cpp:863
bool TryReadLock(void)
Try read lock.
Definition: ncbimtx.cpp:976
bool TryWriteLock(void)
Try write lock.
Definition: ncbimtx.cpp:1320
void WriteLock(void)
Write lock.
Definition: ncbimtx.cpp:1201
void Unlock(void)
Release the RW-lock.
Definition: ncbimtx.cpp:1558
LOG LOG_cxx2c(void)
Create LOG on top of C++ Toolkit CNcbiDiag.
#define UTIL_PRINTABLE_WIDTH
Definition: ncbi_util.h:718
ELOG_Level
Log severity level.
Definition: ncbi_core.h:292
char * UTIL_PrintableStringEx(const char *data, size_t size, char *buf, TUTIL_PrintableFlags flags, int width)
Create a printable representation of a block of data of the specified size (or, if size is 0,...
Definition: ncbi_util.c:219
void CORE_SetREG(REG rg)
Set the registry (no registry if "rg" is passed zero) – to be used by the core internals.
Definition: ncbi_util.c:696
REG REG_cxx2c(IRWRegistry *reg, bool pass_ownership)
Convert a C++ Toolkit registry object to a REG registry.
EMT_Lock
Set the lock/unlock callback function and its data for MT critical section.
Definition: ncbi_core.h:180
void CONNECT_Init(const IRWRegistry *reg, CRWLock *lock, TConnectInitFlags flag, FSSLSetup ssl)
Init [X]CONNECT library with the specified "reg" and "lock" (ownership for either or both can be deta...
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
void CORE_SetLOCK(MT_LOCK lk)
Set the MT critical section lock/unlock handler – to be used by the core internals for protection of ...
Definition: ncbi_util.c:100
MT_LOCK MT_LOCK_cxx2c(CRWLock *lock, bool pass_ownership)
Convert a C++ Toolkit lock object to an MT_LOCK lock.
EIO_Status
I/O status.
Definition: ncbi_core.h:132
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
unsigned int TConnectInitFlags
Bitwise OR of EConnectInitFlag.
size_t UTIL_PrintableStringSize(const char *data, size_t size)
Calculate size of buffer needed to store printable representation of the block of data of the specifi...
Definition: ncbi_util.c:198
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
void CORE_SetLOG(LOG lg)
Set the log handle (no logging if "lg" is passed zero) – to be used by the core internals (CORE LOG).
Definition: ncbi_util.c:123
ENcbiRequestID
NCBI request ID enumerator.
Definition: ncbi_util.h:441
@ eConnectInit_OwnLock
Lock ownership gets passed.
@ eConnectInit_NoSSL
Do NOT init secure socket layer (SSL)
@ eConnectInit_OwnRegistry
Registry ownership gets passed.
@ eLOG_Critical
Definition: ncbi_core.h:298
@ eLOG_Error
Definition: ncbi_core.h:297
@ eLOG_Note
Definition: ncbi_core.h:294
@ eLOG_Warning
Definition: ncbi_core.h:296
@ 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
@ eREG_Transient
only in-memory storage while program runs
Definition: ncbi_core.h:529
@ eREG_Persistent
hard-copy storage across program runs
Definition: ncbi_core.h:530
@ eIO_Success
everything is fine, no error occurred
Definition: ncbi_core.h:133
@ eNcbiRequestID_SID
NCBI Session ID.
Definition: ncbi_util.h:444
@ eNcbiRequestID_HitID
NCBI Hit ID.
Definition: ncbi_util.h:443
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
Definition of all error codes used in connect library (xconnect.lib, xconnext.lib etc).
char * buf
yy_size_t n
int len
static MDB_envinfo info
Definition: mdb_load.c:37
const TYPE & Get(const CNamedParameterList *param)
const struct ncbi::grid::netcache::search::fields::SIZE size
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 strdup
Definition: ncbi_ansi_ext.h:70
AutoPtr< char, CDeleter< char > > TTempCharPtr
NCBI_PARAM_DEF_EX(bool, CONN, TRACE_REG, false, eParam_Default, CONN_TRACE_REG)
static atomic< EConnectInit > s_ConnectInit
static CSafeStatic< TTraceLog > s_TraceLog
static char * s_GetRequestID(ENcbiRequestID reqid)
static void s_REG_Cleanup(void *user_data) THROWS_NONE
DEFINE_STATIC_FAST_MUTEX(s_ConnectInitMutex)
NCBI_PARAM_TYPE(CONN, TRACE_LOCK) TTraceLock
static TCORE_Set s_CORE_Set
static void x_PostFork(void)
static const char * s_GetAppName(void)
static void s_Fini(void) THROWS_NONE
static int s_REG_Get(void *user_data, const char *section, const char *name, char *value, size_t value_size) THROWS_NONE
static CSafeStatic< TTraceLock > s_TraceLock
static int s_LOCK_Handler(void *user_data, EMT_Lock how) THROWS_NONE
static int s_REG_Set(void *user_data, const char *section, const char *name, const char *value, EREG_Storage storage) THROWS_NONE
static CSafeStatic< TTraceReg > s_TraceReg
static void x_PreFork(void)
NCBI_PARAM_TYPE(CONN, TRACE_REG) TTraceReg
static void s_Init(const IRWRegistry *reg=0, FSSLSetup ssl=0, CRWLock *lock=0, TConnectInitFlags flag=0, EConnectInit how=eConnectInit_Weak)
static const char * s_GetReferer(void)
NCBI_PARAM_TYPE(CONN, TRACE_LOG) TTraceLog
static string x_Log(ELOG_Level level)
static void s_LOG_Handler(void *, const SLOG_Message *mess) THROWS_NONE
static string x_Lock(EMT_Lock how)
NCBI_PARAM_DECL(bool, CONN, TRACE_REG)
static string x_Reg(const char *section, const char *name, const char *value=0, EREG_Storage storage=eREG_Transient)
static void s_LOCK_Cleanup(void *user_data) THROWS_NONE
static const char * s_GetRequestDTab(void)
EConnectInit
@ eConnectInit_Strong
User init detected.
@ eConnectInit_Weak
CConn_Initer.
@ eConnectInit_Intact
Not yet visited.
@ eConnectInit_Explicit
CONNECT_Init() called.
unsigned int g_NCBI_ConnectRandomSeed
Definition: ncbi_priv.c:51
FNcbiGetRequestDtab g_CORE_GetRequestDtab
Definition: ncbi_priv.c:55
TCORE_Set g_CORE_Set
Definition: ncbi_priv.c:47
FNcbiGetRequestID g_CORE_GetRequestID
Definition: ncbi_priv.c:54
FNcbiGetAppName g_CORE_GetAppName
Definition: ncbi_priv.c:52
FNcbiGetReferer g_CORE_GetReferer
Definition: ncbi_priv.c:53
@ eCORE_SetLOCK
Definition: ncbi_priv.h:329
@ eCORE_SetLOG
Definition: ncbi_priv.h:328
@ eCORE_SetSSL
Definition: ncbi_priv.h:326
@ eCORE_SetREG
Definition: ncbi_priv.h:327
#define CORE_LOCK_WRITE
Definition: ncbi_priv.h:269
#define NCBI_CONNECT_SRAND_ADDEND
Definition: ncbi_priv.h:343
#define CORE_UNLOCK
Definition: ncbi_priv.h:273
unsigned int TCORE_Set
Definition: ncbi_priv.h:331
Static variables safety - create on demand, destroy on application termination.
Common macro to detect used sanitizers and suppress memory leaks if run under LeakSanitizer.
#define NCBI_LSAN_DISABLE_GUARD
EIO_Status SOCK_SetupSSLInternalEx(FSSLSetup setup, int init)
Definition: ncbi_socket.c:9005
Defines the CNcbiApplication and CAppException classes for creating NCBI applications.
int isspace(Uchar c)
Definition: ncbictype.hpp:69
NCBI C++ auxiliary debug macros.
static int message_len(const char *message, int offset)
Definition: pcre2posix.c:166
Defines CRequestContext class for NCBI C++ diagnostic API.
const Int2 kOutOfMemory
Failure due to out-of-memory condition.
Definition: split_query.c:38
Message and miscellaneous data to pass to log post callback FLOG_Handler.
Definition: ncbi_core.h:338
I/O polling structure.
Definition: ncbi_socket.h:966
#define _TROUBLE
#define _ASSERT
else result
Definition: token2.c:20
Modified on Fri Sep 20 14:57:33 2024 by modify_doxy.py rev. 669887