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/LocalStream.cxx to src/LocalStream.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 : * LocalStream.cxx
14 : * ERS
15 : *
16 : * Created by Serguei Kolos on 21.01.05.
17 : * Copyright 2005 CERN. All rights reserved.
18 : *
19 : */
20 : #include <ers/LocalStream.hpp>
21 : #include <ers/StreamManager.hpp>
22 : #include <ers/internal/SingletonCreator.hpp>
23 :
24 : /** This method returns the singleton instance.
25 : * It should be used for every operation on the factory.
26 : * \return a reference to the singleton instance
27 : */
28 : ers::LocalStream &
29 40 : ers::LocalStream::instance()
30 : {
31 : /**Singleton instance
32 : */
33 40 : static ers::LocalStream * instance = ers::SingletonCreator<ers::LocalStream>::create();
34 :
35 40 : return *instance;
36 : }
37 :
38 : /** Private constructor - can not be called by user code, use the \c instance() method instead
39 : * \see instance()
40 : */
41 14 : ers::LocalStream::LocalStream( )
42 14 : : m_terminated( false )
43 14 : { }
44 :
45 0 : ers::LocalStream::~LocalStream( )
46 : {
47 0 : remove_issue_catcher();
48 0 : }
49 :
50 : void
51 0 : ers::LocalStream::remove_issue_catcher( )
52 : {
53 0 : std::unique_ptr<std::thread> catcher;
54 0 : {
55 0 : std::unique_lock lock( m_mutex );
56 0 : if ( !m_issue_catcher_thread.get() )
57 : {
58 0 : return ;
59 : }
60 0 : m_terminated = true;
61 0 : m_condition.notify_one();
62 0 : catcher.swap(m_issue_catcher_thread);
63 0 : }
64 :
65 0 : catcher -> join();
66 0 : }
67 :
68 : void
69 0 : ers::LocalStream::thread_wrapper()
70 : {
71 0 : std::unique_lock lock( m_mutex );
72 0 : m_catcher_thread_id = std::this_thread::get_id();
73 0 : while( !m_terminated )
74 : {
75 0 : m_condition.wait( lock, [this](){return !m_issues.empty() || m_terminated;} );
76 :
77 0 : while( !m_terminated && !m_issues.empty() )
78 : {
79 0 : ers::Issue * issue = m_issues.front();
80 0 : m_issues.pop();
81 :
82 0 : lock.unlock();
83 0 : m_issue_catcher( *issue );
84 0 : delete issue;
85 0 : lock.lock();
86 : }
87 : }
88 0 : m_catcher_thread_id = {};
89 0 : m_terminated = false;
90 0 : }
91 :
92 : ers::IssueCatcherHandler *
93 0 : ers::LocalStream::set_issue_catcher( const std::function<void ( const ers::Issue & )> & catcher )
94 : {
95 0 : std::unique_lock lock( m_mutex );
96 0 : if ( m_issue_catcher_thread.get() )
97 : {
98 0 : throw ers::IssueCatcherAlreadySet( ERS_HERE );
99 : }
100 0 : m_issue_catcher = catcher;
101 0 : m_issue_catcher_thread.reset( new std::thread( std::bind( &ers::LocalStream::thread_wrapper, this ) ) );
102 :
103 0 : return new ers::IssueCatcherHandler;
104 0 : }
105 :
106 : void
107 40 : ers::LocalStream::report_issue( ers::severity type, const ers::Issue & issue )
108 : {
109 40 : if ( m_issue_catcher_thread.get() && m_catcher_thread_id != std::this_thread::get_id() )
110 : {
111 0 : ers::Issue * clone = issue.clone();
112 0 : clone->set_severity( type );
113 0 : std::unique_lock lock( m_mutex );
114 0 : m_issues.push( clone );
115 0 : m_condition.notify_one();
116 0 : }
117 : else
118 : {
119 40 : StreamManager::instance().report_issue( type, issue );
120 : }
121 40 : }
122 :
123 : void
124 27 : ers::LocalStream::error( const ers::Issue & issue )
125 : {
126 27 : report_issue( ers::Error, issue );
127 27 : }
128 :
129 : void
130 0 : ers::LocalStream::fatal( const ers::Issue & issue )
131 : {
132 0 : report_issue( ers::Fatal, issue );
133 0 : }
134 :
135 : void
136 13 : ers::LocalStream::warning( const ers::Issue & issue )
137 : {
138 13 : report_issue( ers::Warning, issue );
139 13 : }
|