|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/connect/ncbi_core.h |
source navigation diff markup identifier search freetext search file search |
1 #ifndef CONNECT___NCBI_CORE__H
2 #define CONNECT___NCBI_CORE__H
3
4 /* $Id: ncbi_core.h,v 6.36 2008/12/01 16:34:35 kazimird Exp $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Denis Vakatov
30 *
31 * @file
32 * File Description:
33 * Types and code shared by all "ncbi_*.[ch]" modules.
34 *
35 * I/O status and direction:
36 * enum: EIO_ReadMethod
37 * enum: EIO_WriteMethod
38 * enum: EIO_Status, verbal: IO_StatusStr()
39 * enum: EIO_Event
40 *
41 * Critical section (basic multi-thread synchronization):
42 * handle: MT_LOCK
43 * enum: EMT_Lock
44 * callbacks: (*FMT_LOCK_Handler)(), (*FMT_LOCK_Cleanup)()
45 * methods: MT_LOCK_Create(), MT_LOCK_AddRef(), MT_LOCK_Delete(),
46 * MT_LOCK_Do()
47 *
48 * Tracing and logging:
49 * handle: LOG
50 * enum: ELOG_Level, verbal: LOG_LevelStr()
51 * flags: TLOG_FormatFlags, ELOG_FormatFlags
52 * callbacks: (*FLOG_Handler)(), (*FLOG_Cleanup)()
53 * methods: LOG_Create(), LOG_Reset(), LOG_AddRef(), LOG_Delete(),
54 * LOG_WriteInternal()
55 *
56 * Registry:
57 * handle: REG
58 * enum: EREG_Storage
59 * callbacks: (*FREG_Get)(), (*FREG_Set)(), (*FREG_Cleanup)()
60 * methods: REG_Create(), REG_Reset(), REG_AddRef(), REG_Delete(),
61 * REG_Get(), REG_Set()
62 *
63 */
64
65 #include <connect/ncbi_types.h>
66
67
68 /** @addtogroup UtilityFunc
69 *
70 * @{
71 */
72
73
74 #ifdef __cplusplus
75 extern "C" {
76 #endif
77
78
79 /******************************************************************************
80 * I/O
81 */
82
83
84 /** I/O read method.
85 * @sa
86 * EIO_WriteMethod
87 */
88 typedef enum {
89 eIO_ReadPlain, /**< read presently available data only */
90 eIO_ReadPeek, /**< same eIO_ReadPlain but leave data in input queue */
91 eIO_ReadPersist, /**< try to read exactly "n" bytes; wait for enough data*/
92 /* deprecated */
93 eIO_Plain = eIO_ReadPlain,
94 eIO_Peek = eIO_ReadPeek,
95 eIO_Persist = eIO_ReadPersist
96 } EIO_ReadMethod;
97
98
99 /** I/O write method.
100 * @sa
101 * EIO_ReadMethod
102 */
103 typedef enum {
104 eIO_WritePlain, /**< write as much as possible, report back how much */
105 eIO_WritePersist, /**< write exactly as much as specified */
106 eIO_WriteOutOfBand /**< write out-of-band chunk of urgent data */
107 } EIO_WriteMethod;
108
109
110 /** I/O event (or direction).
111 * @par <b>NOTE:</b>
112 * Internally, these constants are used as bit-values,
113 * and thus should not be changed in this header. However, user code
114 * should not rely on the values of these constants.
115 * @sa
116 * SOCK_Wait, SOCK_Poll, CONN_Wait, SOCK_SetTimeout, CONN_SetTimeout
117 */
118 typedef enum {
119 eIO_Open = 0x0, /**< also serves as no-event indicator in SOCK_Poll */
120 eIO_Read = 0x1,
121 eIO_Write = 0x2,
122 eIO_ReadWrite = 0x3, /**< eIO_Read | eIO_Write */
123 eIO_Close = 0x4 /**< also serves as an error indicator in SOCK_Poll */
124 } EIO_Event;
125
126
127 /** I/O status.
128 */
129 typedef enum {
130 eIO_Success = 0, /**< everything is fine, no errors occurred */
131 eIO_Timeout, /**< timeout expired before any I/O succeeded */
132 eIO_Closed, /**< peer has closed the connection */
133 eIO_Interrupt, /**< signal received while an I/O was in progress */
134 eIO_InvalidArg, /**< bad argument value(s) */
135 eIO_NotSupported, /**< the requested operation is not supported */
136
137 eIO_Unknown /**< unknown (most probably -- fatal) error */
138 } EIO_Status;
139
140
141 /** Get the text form of an enum status value.
142 * @param status
143 * An enum value to get the text form for
144 * @return
145 * Verbal description of the I/O status
146 * @sa
147 * EIO_Status
148 */
149 extern NCBI_XCONNECT_EXPORT const char* IO_StatusStr(EIO_Status status);
150
151
152
153 /******************************************************************************
154 * MT locking
155 */
156
157
158 /** Lock handle -- keeps all data needed for the locking and for the cleanup.
159 * The following are the minimal requirements for the lock:
160 * - if lock for read is available, then the lock must allow one nested lock
161 * for read when it has been already locked for write (naturally, by the
162 * same thread);
163 * - if lock for read is not available (i.e. the read lock is implemented
164 * as a write lock), the lock must allow recursive locking (by the same
165 * thread) of the depth of 2.
166 */
167 struct MT_LOCK_tag;
168 typedef struct MT_LOCK_tag* MT_LOCK;
169
170
171 /** Set the lock/unlock callback function and its data for MT critical section.
172 * @par <b>TIP:</b>
173 * If the RW-lock functionality is not provided by the
174 * callback, then: eMT_LockRead <==> eMT_Lock
175 *
176 */
177 typedef enum {
178 eMT_Lock, /**< lock critical section */
179 eMT_LockRead, /**< lock critical section for reading */
180 eMT_Unlock, /**< unlock critical section */
181 eMT_TryLock, /**< try to lock, return immediately */
182 eMT_TryLockRead /**< try to lock for reading, return immediately */
183 } EMT_Lock;
184
185
186 /** MT locking callback (operates like a [recursive] mutex or RW-lock).
187 * @param user_data
188 * See "user_data" in MT_LOCK_Create()
189 * @param how
190 * As passed to MT_LOCK_Do()
191 * @return
192 * Non-zero value if the requested operation was successful.
193 * @par <b>NOTE:</b>
194 * The "-1" value is reserved for unset handler; you also
195 * may want to return "-1" if your locking function does no locking, and
196 * you don't consider it as an error, but still want the caller to be
197 * ware of this "rightful non-doing" as opposed to the "rightful doing".
198 * @sa
199 * MT_LOCK_Create, MT_LOCK_Delete
200 */
201 typedef int/*bool*/ (*FMT_LOCK_Handler)
202 (void* user_data,
203 EMT_Lock how
204 );
205
206 /** MT lock cleanup callback.
207 * @param user_data
208 * See "user_data" in MT_LOCK_Create()
209 * @sa
210 * MT_LOCK_Create, MT_LOCK_Delete
211 */
212 typedef void (*FMT_LOCK_Cleanup)
213 (void* user_data
214 );
215
216
217 /** Create new MT lock (with an internal reference counter set to 1).
218 * @param user_data
219 * Unspecified data to call "handler" and "cleanup" with
220 * @param handler
221 * Locking callback
222 * @param cleanup
223 * Cleanup callback
224 * @sa
225 * FMT_LOCK_Handler, FMT_LOCK_Cleanup, MT_LOCK_Delete
226 */
227 extern NCBI_XCONNECT_EXPORT MT_LOCK MT_LOCK_Create
228 (void* user_data,
229 FMT_LOCK_Handler handler,
230 FMT_LOCK_Cleanup cleanup
231 );
232
233
234 /** Increment internal reference counter by 1, then return "lk".
235 * @param lk
236 * A handle previously obtained from MT_LOCK_Create
237 * @sa
238 * MT_LOCK_Create, MT_LOCK_Delete
239 */
240 extern NCBI_XCONNECT_EXPORT MT_LOCK MT_LOCK_AddRef(MT_LOCK lk);
241
242
243 /** Decrement internal reference counter by 1, and if it reaches 0, then
244 * destroy the handle, call "lk->cleanup(lk->user_data)", and return NULL;
245 * otherwise (if the reference counter is still > 0), return "lk".
246 * @param lk
247 * A handle previously obtained from MT_LOCK_Create
248 * @sa
249 * MT_LOCK_Create, FMT_LOCK_Cleanup
250 */
251 extern NCBI_XCONNECT_EXPORT MT_LOCK MT_LOCK_Delete(MT_LOCK lk);
252
253
254 /** Call "lk->handler(lk->user_data, how)".
255 * @param lk
256 * A handle previously obtained from MT_LOCK_Create
257 * @param how
258 * Whether to lock (and how: read, write) or to unlock
259 * @return
260 * Value returned by the lock handler ("handler" in MT_LOCK_Create()).
261 * If lock handler is not specified then always return "-1".
262 * @par <b>NOTE:</b>
263 * Use MT_LOCK_Do to avoid overhead!
264 * @sa
265 * MT_LOCK_Create, FMT_LOCK_Handler, EMT_Lock
266 */
267 #define MT_LOCK_Do(lk, how) (lk ? MT_LOCK_DoInternal(lk, how) : -1)
268 extern NCBI_XCONNECT_EXPORT int/*bool*/ MT_LOCK_DoInternal
269 (MT_LOCK lk,
270 EMT_Lock how
271 );
272
273
274 /******************************************************************************
275 * ERROR HANDLING and LOGGING
276 */
277
278
279 /** Log handle -- keeps all data needed for the logging and for the cleanup.
280 */
281 struct LOG_tag;
282 typedef struct LOG_tag* LOG;
283
284
285 /** Log severity level.
286 */
287 typedef enum {
288 eLOG_Trace = 0,
289 eLOG_Note,
290 eLOG_Warning,
291 eLOG_Error,
292 eLOG_Critical,
293 eLOG_Fatal
294 } ELOG_Level;
295
296
297 /** Obtain verbal representation of an enum level value.
298 * @param level
299 * An enum value to get the text form for
300 * @return
301 * Verbal description of the log level
302 * @sa
303 * ELOG_Level
304 */
305 extern NCBI_XCONNECT_EXPORT const char* LOG_LevelStr(ELOG_Level level);
306
307
308 /** Message and miscellaneous data to pass to log post callback FLOG_Handler.
309 * @param dynamic
310 * if non-zero then LOG_WriteInternal() will call free(message) before return
311 * @param message
312 * A message to post, can be NULL
313 * @param level
314 * A message level
315 * @param module
316 * A module string to post, can be NULL
317 * @param file
318 * A file name to post, can be NULL
319 * @param line
320 * A line number within the file (above) to post, can be 0
321 * @param raw_data
322 * Raw data to log (usually NULL)
323 * @param raw_size
324 * Size of the raw data (usually zero)
325 * @param err_code
326 * Error code of the message
327 * @param err_subcode
328 * Error subcode of the message
329 * @sa
330 * FLOG_Handler, LOG_Create, LOG_WriteInternal, LOG_Write
331 */
332 typedef struct {
333 int/*bool*/ dynamic;
334 const char* message;
335 ELOG_Level level;
336 const char* module;
337 const char* file;
338 int line;
339 const void* raw_data;
340 size_t raw_size;
341 int err_code;
342 int err_subcode;
343 } SLOG_Handler;
344
345
346 /** Log post callback.
347 * @param user_data
348 * Unspeficied data as passed to LOG_Create() or LOG_Reset()
349 * @param call_data
350 * Composed from arguments passed to LOG_WriteInternal()
351 * @sa
352 * SLOG_Handler, LOG_Create, LOG_Reset, LOG_WriteInternal
353 */
354 typedef void (*FLOG_Handler)
355 (void* user_data,
356 SLOG_Handler* call_data
357 );
358
359
360 /** Log cleanup callback.
361 * @param user_data
362 * Unspeficied data as passed to LOG_Create() or LOG_Reset()
363 * @sa
364 * LOG_Create, LOG_Reset
365 *
366 */
367 typedef void (*FLOG_Cleanup)
368 (void* user_data
369 );
370
371
372 /** Create new LOG (with an internal reference counter set to 1).
373 * @par <b>ATTENTION:</b>
374 * If non-NULL "mt_lock" is specified then
375 * MT_LOCK_Delete() will be called on it when this LOG gets deleted
376 * -- be aware of it (hence, if the lock is also to be used with something
377 * else, then call MT_LOCK_AddRef() on it before passing to LOG_Create)!
378 * @param user_data
379 * Unspecified data to call "handler" and "cleanup" with
380 * @param handler
381 * Log post callback
382 * @param cleanup
383 * Cleanup callback
384 * @param mt_lock
385 * Protective MT lock (can be NULL)
386 * @sa
387 * MT_LOCK, MT_LOCK_AddRef, FLOG_Handler, FLOG_Cleanup, LOG_Reset, LOG_Delete
388 */
389 extern NCBI_XCONNECT_EXPORT LOG LOG_Create
390 (void* user_data,
391 FLOG_Handler handler,
392 FLOG_Cleanup cleanup,
393 MT_LOCK mt_lock
394 );
395
396
397 /** Reset the "lg" to use the new "user_data", "handler" and "cleanup".
398 * @par <b>NOTE:</b>
399 * It does not change the reference counter of the log.
400 * @param lg
401 * A log handle previously obtained from LOG_Create
402 * @param user_data
403 * New user data
404 * @param handler
405 * New log post callback
406 * @param cleanup
407 * New cleanup callback
408 * @return
409 * lg (as passed in the first parameter)
410 * @sa
411 * LOG_Create
412 */
413 extern NCBI_XCONNECT_EXPORT LOG LOG_Reset
414 (LOG lg,
415 void* user_data,
416 FLOG_Handler handler,
417 FLOG_Cleanup cleanup
418 );
419
420
421 /** Increment internal reference counter by 1, then return "lg".
422 * @param lg
423 * A log handle previously obtained from LOG_Create
424 * @sa
425 * LOG_Create
426 */
427 extern NCBI_XCONNECT_EXPORT LOG LOG_AddRef(LOG lg);
428
429
430 /** Decrement internal reference counter by 1, and if it reaches 0, then
431 * call "lg->cleanup(lg->user_data)", destroy the handle, and return NULL;
432 * otherwise (if reference counter is still > 0), return "lg".
433 * @param lg
434 * A log handle previously obtained from LOG_Create
435 * @sa
436 * LOG_Create
437 */
438 extern NCBI_XCONNECT_EXPORT LOG LOG_Delete(LOG lg);
439
440
441 /** Write message (perhaps with raw data attached) to the log by calling
442 * "lg->handler(lg->user_data, call_data)".
443 * @par <b>NOTE:</b>
444 * Do not call this function directly, if possible.
445 * Instead, use LOG_WRITE() and LOG_DATA() macros from <ncbi_util.h>!
446 * @param lg
447 * A log handle previously obtained from LOG_Create
448 * @sa
449 * LOG_Create, ELOG_Level, FLOG_Handler, LOG_WRITE, LOG_DATA
450 */
451 extern NCBI_XCONNECT_EXPORT void LOG_WriteInternal
452 (LOG lg,
453 SLOG_Handler* call_data
454 );
455
456
457 /** Write message (perhaps with raw data attached) to the log by calling
458 * LOG_WriteInternal() upon filling up SLOG_Handler data from parameters.
459 * @par <b>NOTE:</b>
460 * Do not call this function directly, if possible.
461 * Instead, use LOG_WRITE() and LOG_DATA() macros from <ncbi_util.h>!
462 * @param code
463 * Error code of the message
464 * @param subcode
465 * Error subcode of the message
466 * @param level
467 * The message severity
468 * @param module
469 * Module name (can be NULL)
470 * @param file
471 * Source file name (can be NULL)
472 * @param line
473 * Source line within the file (can be 0 to omit the line number)
474 * @param message
475 * Message content
476 * @param raw_data
477 * Raw data to log (can be NULL)
478 * @param raw_size
479 * Size of the raw data (can be zero)
480 * @sa
481 * LOG_Create, ELOG_Level, FLOG_Handler, LOG_WriteInternal
482 */
483 extern NCBI_XCONNECT_EXPORT void LOG_Write
484 (LOG lg,
485 int code,
486 int subcode,
487 ELOG_Level level,
488 const char* module,
489 const char* file,
490 int line,
491 const char* message,
492 const void* raw_data,
493 size_t raw_size
494 );
495
496
497 /******************************************************************************
498 * REGISTRY
499 */
500
501
502 /** Registry handle (keeps all data needed for the registry get/set/cleanup).
503 */
504 struct REG_tag;
505 typedef struct REG_tag* REG;
506
507
508 /** Transient/Persistent storage.
509 * @sa
510 * REG_Get, REG_Set
511 */
512 typedef enum {
513 eREG_Transient = 0, /**< only in-memory storage while program runs */
514 eREG_Persistent /**< hard-copy storage across program runs */
515 } EREG_Storage;
516
517
518 /** Registry getter callback.
519 * Copy registry value stored in "section" under name "name" to buffer "value".
520 * Look for the matching entry first in the transient storage, and then in
521 * the persistent storage. Do not modify the "value" (leave it "as is",
522 * i.e. default) if the requested entry is not found in the registry.
523 * @par <b>NOTE:</b>
524 * Always terminate value by '\0'.
525 * @par <b>NOTE:</b>
526 * Do not put more than "value_size" bytes to "value".
527 * @param user_data
528 * Unspecified data as passed to REG_Create or REG_Reset
529 * @param section
530 * Section name to search
531 * @param name
532 * Key name to search within the section
533 * @param value
534 * Default value passed in (cut to "value_size") symbols, found value out
535 * @param value_size
536 * Size of "value" storage, must be greater than 0
537 * @sa
538 * REG_Create, REG_Reset
539 */
540 typedef void (*FREG_Get)
541 (void* user_data,
542 const char* section,
543 const char* name,
544 char* value,
545 size_t value_size
546 );
547
548
549 /** Registry setter callback.
550 * Store the "value" to the registry section "section" under name "name",
551 * and according to "storage".
552 * @param user_data
553 * Unspecified data as passed to REG_Create or REG_Reset
554 * @param section
555 * Section name to add the key to
556 * @param name
557 * Key name to add to the section
558 * @param value
559 * Key value to associate with the key
560 * @param storage
561 * How to store the new setting, temporarily or permanently
562 * @return
563 * Non-zero if successful (including replacing a value with itself)
564 * @sa
565 * REG_Create, REG_Reset, EREG_Storage
566 */
567 typedef int (*FREG_Set)
568 (void* user_data,
569 const char* section,
570 const char* name,
571 const char* value,
572 EREG_Storage storage
573 );
574
575
576 /** Registry cleanup callback.
577 * @param user_data
578 * Unspecified data as passed to REG_Create or REG_Reset
579 * @sa
580 * REG_Reset, REG_Delete
581 */
582 typedef void (*FREG_Cleanup)
583 (void* user_data
584 );
585
586
587 /** Create new registry (with an internal reference counter set to 1).
588 * @par <b>ATTENTION:</b>
589 * if non-NULL "mt_lock" is specified then
590 * MT_LOCK_Delete() will be called on it when this REG gets destroyed
591 * -- be aware of it (hence, if the lock is also to be used with something
592 * else, then call MT_LOCK_AddRef() on it before passing to REG_Create)!
593 * Passing NULL callbacks below causes limiting the functionality
594 * only to those operations that have the callbacks set.
595 * @param user_data
596 * Unspecified data to call "set", "get" and "cleanup" with
597 * @param get
598 * Getter callback
599 * @param set
600 * Setter callback
601 * @param cleanup
602 * Cleanup callback
603 * @param mt_lock
604 * Protective MT lock (can be NULL)
605 * @sa
606 * MT_LOCK, MT_LOCK_AddRef, REG_Get, REG_Set, REG_Reset, REG_Delete
607 */
608 extern NCBI_XCONNECT_EXPORT REG REG_Create
609 (void* user_data,
610 FREG_Get get,
611 FREG_Set set,
612 FREG_Cleanup cleanup,
613 MT_LOCK mt_lock
614 );
615
616
617 /** Reset the registry handle to use the new "user_data", "set", "get",
618 * and "cleanup".
619 * @par <b>NOTE:</b>
620 * No change to the internal reference counter.
621 * @param rg
622 * Registry handle as previously obtained from REG_Create
623 * @param user_data
624 * New user data
625 * @param get
626 * New getter callback
627 * @param set
628 * New setter callback
629 * @param cleanup
630 * New cleanup callback
631 * @param do_cleanup
632 * Whether to call old cleanup (if any specified) for old data
633 * @sa
634 * REG_Create, REG_Delete
635 */
636 extern NCBI_XCONNECT_EXPORT void REG_Reset
637 (REG rg,
638 void* user_data,
639 FREG_Get get,
640 FREG_Set set,
641 FREG_Cleanup cleanup,
642 int/*bool*/ do_cleanup
643 );
644
645
646 /** Increment internal reference counter by 1, then return "rg".
647 * @param rg
648 * Registry handle as previously obtained from REG_Create
649 * @sa
650 * REG_Create
651 */
652 extern NCBI_XCONNECT_EXPORT REG REG_AddRef(REG rg);
653
654
655 /** Decrement internal referecne counter by 1, and if it reaches 0, then
656 * call "rg->cleanup(rg->user_data)", destroy the handle, and return NULL;
657 * otherwise (if the reference counter is still > 0), return "rg".
658 * @param rg
659 * Registry handle as previously obtained from REG_Create
660 * @sa
661 * REG_Create
662 */
663 extern NCBI_XCONNECT_EXPORT REG REG_Delete(REG rg);
664
665
666 /** Copy the registry value stored in "section" under name "name"
667 * to buffer "value"; if the entry is found in both transient and persistent
668 * storages, then copy the one from the transient storage.
669 * If the specified entry is not found in the registry (or if there is
670 * no registry defined), and "def_value" is not NULL, then copy "def_value"
671 * to "value" (although, only up to "value_size" characters).
672 * @param rg
673 * Registry handle as previously obtained from REG_Create
674 * @param section
675 * Registry section name
676 * @param name
677 * Registry entry name
678 * @param value
679 * Buffer to put the value of the requested entry to
680 * @param value_size
681 * Maximal size of buffer "value"
682 * @param def_value
683 * Default value (none if passed NULL)
684 * @return
685 * Return "value" (however, if "value_size" is zero, then return NULL).
686 * If non-NULL, the returned "value" will be terminated by '\0'.
687 * @sa
688 * REG_Create, REG_Set
689 */
690 extern NCBI_XCONNECT_EXPORT const char* REG_Get
691 (REG rg,
692 const char* section,
693 const char* name,
694 char* value,
695 size_t value_size,
696 const char* def_value
697 );
698
699
700 /** Store the "value" to the registry section "section" under name "name",
701 * and according with "storage".
702 * @param rg
703 * Registry handle as previously obtained from REG_Create
704 * @param section
705 * Section name to store the value into
706 * @param name
707 * Name to store the value under
708 * @param value
709 * The value to store
710 * @param storage
711 * Whether to store temporarily or permanently
712 * @return
713 * Non-zero if successful (including replacing a value with itself)
714 * @sa
715 * REG_Create, EREG_Storage, REG_Get
716 */
717 extern NCBI_XCONNECT_EXPORT int REG_Set
718 (REG rg,
719 const char* section,
720 const char* name,
721 const char* value,
722 EREG_Storage storage
723 );
724
725
726 #ifdef __cplusplus
727 } /* extern "C" */
728 #endif
729
730
731 /* @} */
732
733 #endif /* CONNECT___NCBI_CORE__H */
734 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |