1 /*
2 *
3 * Copyright (C) 2000-2010, OFFIS e.V.
4 * All rights reserved. See COPYRIGHT file for details.
5 *
6 * This software and supporting documentation were developed by
7 *
8 * OFFIS e.V.
9 * R&D Division Health
10 * Escherweg 2
11 * D-26121 Oldenburg, Germany
12 *
13 *
14 * Module: ofstd
15 *
16 * Author: Marco Eichelberg
17 *
18 * Purpose: Define alias for cout, cerr and clog
19 *
20 */
21
22 #include "dcmtk/config/osconfig.h"
23 #include "dcmtk/ofstd/ofconsol.h"
24 #include "dcmtk/ofstd/ofthread.h"
25
26 #define INCLUDE_CASSERT
27 #include "dcmtk/ofstd/ofstdinc.h"
28
29
30 #ifdef DCMTK_GUI
31 OFOStringStream COUT;
32 OFOStringStream CERR;
33 #endif
34
OFConsole()35 OFConsole::OFConsole()
36 #ifdef DCMTK_GUI
37 : currentCout(&COUT)
38 , currentCerr(&CERR)
39 #else
40 : currentCout(&STD_NAMESPACE cout)
41 , currentCerr(&STD_NAMESPACE cerr)
42 #endif
43 , joined(0)
44 #ifdef WITH_THREADS
45 , coutMutex()
46 , cerrMutex()
47 #endif
48 {
49 }
50
setCout(STD_NAMESPACE ostream * newCout)51 STD_NAMESPACE ostream *OFConsole::setCout(STD_NAMESPACE ostream *newCout)
52 {
53 lockCout();
54 STD_NAMESPACE ostream *tmpCout = currentCout;
55 #ifdef DCMTK_GUI
56 if (newCout) currentCout = newCout; else currentCout = &COUT;
57 #else
58 if (newCout) currentCout = newCout; else currentCout = &STD_NAMESPACE cout;
59 #endif
60 unlockCout();
61 return tmpCout;
62 }
63
setCerr(STD_NAMESPACE ostream * newCerr)64 STD_NAMESPACE ostream *OFConsole::setCerr(STD_NAMESPACE ostream *newCerr)
65 {
66 lockCerr();
67 STD_NAMESPACE ostream *tmpCerr = currentCerr;
68 #ifdef DCMTK_GUI
69 if (newCerr) currentCerr = newCerr; else currentCerr = &CERR;
70 #else
71 if (newCerr) currentCerr = newCerr; else currentCerr = &STD_NAMESPACE cerr;
72 #endif
73 unlockCerr();
74 return tmpCerr;
75 }
76
join()77 void OFConsole::join()
78 {
79 lockCerr();
80 if (!joined)
81 {
82 // changing the state of "joined" requires that both mutexes are locked.
83 // Mutexes must always be locked in the same order to avoid deadlocks.
84 lockCout();
85 joined = 1;
86 }
87
88 // now status is joined, so unlockCerr implicitly unlocks both mutexes
89 unlockCerr();
90 return;
91 }
92
split()93 void OFConsole::split()
94 {
95 lockCerr();
96 if (joined)
97 {
98 // since status is joined, lockCerr() has locked both mutexes
99 joined = 0;
100
101 // now status is unjoined, we have to unlock both mutexes manually
102 unlockCout();
103 }
104 unlockCerr();
105 return;
106 }
107
isJoined()108 OFBool OFConsole::isJoined()
109 {
110 lockCerr();
111 // nobody will change "joined" if we have locked either mutex
112 int result = joined;
113 unlockCerr();
114 if (result) return OFTrue; else return OFFalse;
115 }
116
instance()117 OFConsole& OFConsole::instance()
118 {
119 static OFConsole instance_;
120 return instance_;
121 }
122
123
124 class OFConsoleInitializer
125 {
126 public:
OFConsoleInitializer()127 OFConsoleInitializer()
128 {
129 OFConsole::instance();
130 }
131 };
132
133 /* the constructor of this global object makes sure
134 * that ofConsole is initialized before main starts.
135 * Required to make ofConsole thread-safe.
136 */
137 OFConsoleInitializer ofConsoleInitializer;
138