1 /*===========================================================================
2 *
3 *                            PUBLIC DOMAIN NOTICE
4 *               National Center for Biotechnology Information
5 *
6 *  This software/database is a "United States Government Work" under the
7 *  terms of the United States Copyright Act.  It was written as part of
8 *  the author's official duties as a United States Government employee and
9 *  thus cannot be copyrighted.  This software/database is freely available
10 *  to the public for use. The National Library of Medicine and the U.S.
11 *  Government have not placed any restriction on its use or reproduction.
12 *
13 *  Although all reasonable efforts have been taken to ensure the accuracy
14 *  and reliability of the software and data, the NLM and the U.S.
15 *  Government do not and cannot warrant the performance or results that
16 *  may be obtained by using this software or data. The NLM and the U.S.
17 *  Government disclaim all warranties, express or implied, including
18 *  warranties of performance, merchantability or fitness for any particular
19 *  purpose.
20 *
21 *  Please cite the author in any work or product based on this material.
22 *
23 * ===========================================================================
24 *
25 */
26 
27 #include <kfc/rsrc.hpp>
28 #include <kfc/callstk.hpp>
29 #include <kfc/except.hpp>
30 #include <kfc/caps.hpp>
31 #include <kfc/array.hpp>
32 #include <kfc/string.hpp>
33 #include "pmemmgr.hpp"
34 #include "ptimemgr.hpp"
35 #include "pfdmgr.hpp"
36 #include "plogger.hpp"
37 
38 #if UNIX
39 #include <kfc/fd.hpp>
40 #else
41 #error "unsupported target platform"
42 #endif
43 
44 #include <stdio.h>
45 
46 namespace vdb3
47 {
48 
49     __thread Rsrc const * rsrc;
50 
~RsrcBase()51     RsrcBase :: ~ RsrcBase ()
52     {
53         if ( rsrc == ( const Rsrc * ) this )
54             rsrc = 0;
55     }
56 
Rsrc(rcaps_t mgrs)57     Rsrc :: Rsrc ( rcaps_t mgrs )
58     {
59         if ( rsrc == 0 )
60         {
61             FUNC_ENTRY ();
62             CONST_THROW ( xc_program_state_violation, "at top of call stack" );
63         }
64 
65         mmgr = rsrc -> mmgr;
66 
67         if ( ( mgrs & RCAP_TMMGR ) != 0 )
68             tmmgr = rsrc -> tmmgr;
69 
70         if ( ( mgrs & RCAP_FDMGR ) != 0 )
71             fdmgr = rsrc -> fdmgr;
72 
73         if ( ( mgrs & RCAP_LOG ) != 0 )
74             log = rsrc -> log;
75 
76         if ( ( mgrs & RCAP_ERR ) != 0 )
77             err = rsrc -> err;
78     }
79 
80 
Rsrc(const Rsrc & rsrc)81     Rsrc :: Rsrc ( const Rsrc & rsrc )
82         : mmgr ( rsrc . mmgr )
83         , tmmgr ( rsrc . tmmgr )
84         , fdmgr ( rsrc . fdmgr )
85         , log ( rsrc . log )
86         , err ( rsrc . err )
87     {
88     }
89 
operator =(const Rsrc & rsrc)90     void Rsrc :: operator = ( const Rsrc & rsrc )
91     {
92         mmgr = rsrc . mmgr;
93         tmmgr = rsrc . tmmgr;
94         fdmgr = rsrc . fdmgr;
95         log = rsrc . log;
96         err = rsrc . err;
97     }
98 
~Rsrc()99     Rsrc :: ~ Rsrc ()
100     {
101     }
102 
Rsrc(const MemMgr & pmmgr,const char * ident)103     Rsrc :: Rsrc ( const MemMgr & pmmgr, const char * ident )
104         : mmgr ( pmmgr )
105     {
106         // one-shot latch
107         if ( rsrc != 0 )
108         {
109             assert ( callstk != 0 );
110             FUNC_ENTRY ();
111             CONST_THROW ( xc_program_state_violation, "not at top of call stack" );
112         }
113         rsrc = this;
114 
115         try
116         {
117             // create obligatory resources
118             tmmgr = PrimordTimeMgr :: make_primordial ();
119             fdmgr = PrimordFDMgr :: make_primordial ();
120             log = plogger_t :: make ( ident );
121 #if UNIX
122             FileDesc fd2 = fdmgr . make ( 2, CAP_WRITE );
123             err = Stream ( fd2 );
124 #endif
125         }
126         catch ( exception & x )
127         {
128             NULTermString what = x . what ();
129             fprintf ( stderr, "ERROR: %s:\n", ( const char * ) what );
130 #if _DEBUGGING
131             NULTermString stk = x . stack_trace ();
132             fprintf ( stderr, "%s\n", ( const char * ) stk );
133 #endif
134         }
135     }
136 
TopRsrc(const char * ident)137     TopRsrc :: TopRsrc ( const char * ident )
138         : Rsrc ( PrimordMemMgr :: make_primordial (), ident )
139     {
140     }
141 
142 }
143