Line data Source code
1 : /*
2 : * DUNE DAQ modification notice:
3 : * This file has been modified from the original ATLAS ers source for the DUNE DAQ project.
4 : * Fork baseline commit: 8267df82a4f6fe6bf02c4014923eba19eddc4614 (2020-04-14).
5 : * Renamed since fork: yes (from src/streams/StandardStream.cxx to plugins/StandardStream.cpp).
6 : *
7 : * Original copyright:
8 : * Copyright (C) 2001-2020 CERN for the benefit of the ATLAS collaboration.
9 : * Licensed under the Apache License, Version 2.0.
10 : */
11 :
12 : /*
13 : * StandardStream.cxx
14 : * ers
15 : *
16 : * Created by Serguei Kolos on 02.08.05.
17 : * Copyright 2004 CERN. All rights reserved.
18 : *
19 : */
20 :
21 : #include <iostream>
22 : #include <fstream>
23 : #include <mutex>
24 :
25 : #include <ers/SampleIssues.hpp>
26 :
27 : #include <ers/internal/StandardStream.hpp>
28 : #include <ers/internal/FormattedStandardStream.hpp>
29 :
30 : namespace
31 : {
32 : struct OutDevice
33 : {
34 1129 : explicit OutDevice( std::ostream & out )
35 1129 : : out_( out )
36 1129 : { ; }
37 :
38 2144 : std::ostream & stream() const
39 2144 : { return out_; }
40 :
41 0 : const OutDevice & device()
42 0 : { return *this; }
43 :
44 : private:
45 : OutDevice(const OutDevice &) = delete;
46 : OutDevice & operator=(const OutDevice &) = delete;
47 :
48 : private:
49 : std::ostream & out_;
50 : };
51 :
52 : struct ObjectLock
53 : {
54 : protected:
55 0 : ObjectLock() = default;
56 :
57 0 : std::mutex & mutex()
58 : {
59 0 : return mutex_;
60 : }
61 :
62 : private:
63 : ObjectLock(const ObjectLock &) = delete;
64 : ObjectLock & operator=(const ObjectLock &) = delete;
65 :
66 : private:
67 : std::mutex mutex_;
68 : };
69 :
70 : template <int LockDiscriminator>
71 : struct ClassLock
72 : {
73 : protected:
74 : ClassLock() = default;
75 :
76 1072 : std::mutex & mutex()
77 : {
78 1072 : static std::mutex * m = new std::mutex;
79 1072 : return *m;
80 : }
81 :
82 : private:
83 : ClassLock(const ClassLock &) = delete;
84 : ClassLock & operator=(const ClassLock &) = delete;
85 : };
86 :
87 : template <class L=ObjectLock>
88 : struct LockableDevice : public L,
89 : public OutDevice
90 : {
91 : using L::mutex;
92 :
93 : struct LockedDevice : public OutDevice
94 : {
95 1072 : LockedDevice( std::ostream & out, std::mutex & mutex )
96 : : OutDevice( out ),
97 1072 : m_lock(mutex)
98 1072 : { ; }
99 :
100 : private:
101 : LockedDevice( const LockedDevice & ) = delete;
102 : LockedDevice & operator=( const LockedDevice & ) = delete;
103 :
104 : private:
105 : std::unique_lock<std::mutex> m_lock;
106 : };
107 :
108 57 : LockableDevice( std::ostream & out )
109 57 : : OutDevice( out )
110 57 : { ; }
111 :
112 1072 : LockedDevice device()
113 : {
114 1072 : return LockedDevice( stream(), mutex() );
115 : }
116 : };
117 :
118 :
119 : template <class D>
120 : struct OutputDevice : public D
121 : {
122 40 : OutputDevice( const std::string & = "" )
123 40 : : D( std::cout )
124 40 : { ; }
125 : };
126 :
127 : template <class D>
128 : struct ErrorDevice : public D
129 : {
130 17 : ErrorDevice( const std::string & = "" )
131 17 : : D( std::cerr )
132 17 : { ; }
133 : };
134 :
135 : template <class D>
136 : struct FileDevice : public D
137 : {
138 0 : FileDevice( const std::string & file_name )
139 : : D( out_ ),
140 0 : out_( file_name.c_str() )
141 : {
142 0 : if ( !out_ )
143 : {
144 0 : throw ers::CantOpenFile( ERS_HERE, file_name.c_str() );
145 : }
146 0 : }
147 :
148 : private:
149 : std::ofstream out_;
150 : };
151 : }
152 :
153 42 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<FileDevice<OutDevice> >, "file", file_name )
154 42 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<OutputDevice<OutDevice> >, "stdout", ERS_EMPTY)
155 42 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<ErrorDevice<OutDevice> >, "stderr", ERS_EMPTY)
156 :
157 42 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<FileDevice<LockableDevice<> > >, "lfile", file_name )
158 82 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<OutputDevice<LockableDevice<ClassLock<1> > > >, "lstdout", ERS_EMPTY)
159 59 : ERS_REGISTER_OUTPUT_STREAM( ers::StandardStream<ErrorDevice<LockableDevice<ClassLock<2> > > >, "lstderr", ERS_EMPTY)
160 :
161 42 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<FileDevice<OutDevice> >, "ffile", format )
162 42 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<OutputDevice<OutDevice> >, "fstdout", format )
163 42 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<ErrorDevice<OutDevice> >, "fstderr", format )
164 :
165 42 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<FileDevice<LockableDevice<> > >, "lffile", format )
166 42 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<OutputDevice<LockableDevice<ClassLock<1> > > >, "lfstdout", format )
167 42 : ERS_REGISTER_OUTPUT_STREAM( ers::FormattedStandardStream<ErrorDevice<LockableDevice<ClassLock<2> > > >, "lfstderr", format )
|