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 <fstream>
22 : #include <iostream>
23 : #include <mutex>
24 :
25 : #include <ers/SampleIssues.hpp>
26 :
27 : #include <ers/internal/FormattedStandardStream.hpp>
28 : #include <ers/internal/StandardStream.hpp>
29 :
30 : namespace {
31 : struct OutDevice
32 : {
33 1141 : explicit OutDevice(std::ostream& out)
34 1141 : : out_(out)
35 : {
36 1141 : ;
37 1141 : }
38 :
39 2164 : std::ostream& stream() const { return out_; }
40 :
41 0 : const OutDevice& device() { return *this; }
42 :
43 : private:
44 : OutDevice(const OutDevice&) = delete;
45 : OutDevice& operator=(const OutDevice&) = delete;
46 :
47 : private:
48 : std::ostream& out_;
49 : };
50 :
51 : struct ObjectLock
52 : {
53 : protected:
54 0 : ObjectLock() = default;
55 :
56 0 : std::mutex& mutex() { return mutex_; }
57 :
58 : private:
59 : ObjectLock(const ObjectLock&) = delete;
60 : ObjectLock& operator=(const ObjectLock&) = delete;
61 :
62 : private:
63 : std::mutex mutex_;
64 : };
65 :
66 : template<int LockDiscriminator>
67 : struct ClassLock
68 : {
69 : protected:
70 : ClassLock() = default;
71 :
72 1082 : std::mutex& mutex()
73 : {
74 1082 : static std::mutex* m = new std::mutex;
75 1082 : return *m;
76 : }
77 :
78 : private:
79 : ClassLock(const ClassLock&) = delete;
80 : ClassLock& operator=(const ClassLock&) = delete;
81 : };
82 :
83 : template<class L = ObjectLock>
84 : struct LockableDevice
85 : : public L
86 : , public OutDevice
87 : {
88 : using L::mutex;
89 :
90 : struct LockedDevice : public OutDevice
91 : {
92 1082 : LockedDevice(std::ostream& out, std::mutex& mutex)
93 : : OutDevice(out)
94 1082 : , m_lock(mutex)
95 : {
96 : ;
97 1082 : }
98 :
99 : private:
100 : LockedDevice(const LockedDevice&) = delete;
101 : LockedDevice& operator=(const LockedDevice&) = delete;
102 :
103 : private:
104 : std::unique_lock<std::mutex> m_lock;
105 : };
106 :
107 59 : LockableDevice(std::ostream& out)
108 59 : : OutDevice(out)
109 : {
110 : ;
111 59 : }
112 :
113 1082 : LockedDevice device() { return LockedDevice(stream(), mutex()); }
114 : };
115 :
116 : template<class D>
117 : struct OutputDevice : public D
118 : {
119 41 : OutputDevice(const std::string& = "")
120 41 : : D(std::cout)
121 : {
122 : ;
123 41 : }
124 : };
125 :
126 : template<class D>
127 : struct ErrorDevice : public D
128 : {
129 18 : ErrorDevice(const std::string& = "")
130 18 : : D(std::cerr)
131 : {
132 : ;
133 18 : }
134 : };
135 :
136 : template<class D>
137 : struct FileDevice : public D
138 : {
139 0 : FileDevice(const std::string& file_name)
140 : : D(out_)
141 0 : , out_(file_name.c_str())
142 : {
143 0 : if (!out_) {
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 43 : ERS_REGISTER_OUTPUT_STREAM(ers::StandardStream<FileDevice<OutDevice>>, "file", file_name)
154 43 : ERS_REGISTER_OUTPUT_STREAM(ers::StandardStream<OutputDevice<OutDevice>>, "stdout", ERS_EMPTY)
155 43 : ERS_REGISTER_OUTPUT_STREAM(ers::StandardStream<ErrorDevice<OutDevice>>, "stderr", ERS_EMPTY)
156 :
157 43 : ERS_REGISTER_OUTPUT_STREAM(ers::StandardStream<FileDevice<LockableDevice<>>>, "lfile", file_name)
158 84 : ERS_REGISTER_OUTPUT_STREAM(ers::StandardStream<OutputDevice<LockableDevice<ClassLock<1>>>>, "lstdout", ERS_EMPTY)
159 61 : ERS_REGISTER_OUTPUT_STREAM(ers::StandardStream<ErrorDevice<LockableDevice<ClassLock<2>>>>, "lstderr", ERS_EMPTY)
160 :
161 43 : ERS_REGISTER_OUTPUT_STREAM(ers::FormattedStandardStream<FileDevice<OutDevice>>, "ffile", format)
162 43 : ERS_REGISTER_OUTPUT_STREAM(ers::FormattedStandardStream<OutputDevice<OutDevice>>, "fstdout", format)
163 43 : ERS_REGISTER_OUTPUT_STREAM(ers::FormattedStandardStream<ErrorDevice<OutDevice>>, "fstderr", format)
164 :
165 43 : ERS_REGISTER_OUTPUT_STREAM(ers::FormattedStandardStream<FileDevice<LockableDevice<>>>, "lffile", format)
166 43 : ERS_REGISTER_OUTPUT_STREAM(ers::FormattedStandardStream<OutputDevice<LockableDevice<ClassLock<1>>>>, "lfstdout", format)
167 43 : ERS_REGISTER_OUTPUT_STREAM(ers::FormattedStandardStream<ErrorDevice<LockableDevice<ClassLock<2>>>>, "lfstderr", format)
|