KiCad PCB EDA Suite
Loading...
Searching...
No Matches
db_backend_support.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or (at your
9 * option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20#ifndef KICAD_DB_BACKEND_SUPPORT_H
21#define KICAD_DB_BACKEND_SUPPORT_H
22
23#include <chrono>
24#include <functional>
25#include <future>
26#include <memory>
27#include <mutex>
28#include <optional>
29#include <string>
30#include <thread>
31#include <vector>
32
33#include <wx/string.h>
34
36#include "db_worker_thread.h"
37
38
40inline std::string utf8( const wxString& aText )
41{
42 return std::string( aText.ToUTF8() );
43}
44
45
60
61
63DB_WORKER_FAILURE DescribeWorkerOutcome( DB_WORKER_THREAD::OUTCOME aOutcome, const std::string& aPath );
64
65
73{
74public:
75 DB_READ_DELIVERY( std::vector<std::string>& aLabels, const DB_ROW_SINK& aSink );
76
79
81 const std::shared_ptr<std::vector<std::string>>& Labels() const { return m_jobLabels; }
82
84 const DB_ROW_SINK* Sink() const { return &m_deliver; }
85
87 void Finish();
88
90 bool SinkThrew() const { return m_sinkThrew; }
91
93 static std::string SinkFailureMessage();
94
95private:
96 std::vector<std::string>& m_labels;
98 std::shared_ptr<std::vector<std::string>> m_jobLabels;
100 bool m_labelsCopied = false;
101 bool m_sinkThrew = false;
102};
103
104
114std::string ScrubSecret( std::string aText, const std::string& aSecret );
115
116
118std::string RedactDetail( const std::string& aDetail, const std::string& aSecret );
119
120
127template <typename T>
129{
130public:
131 explicit DB_PROBE_LATCH( std::function<T()> aProbe ) :
132 m_probe( std::move( aProbe ) )
133 {
134 }
135
137 std::optional<T> Get( std::chrono::milliseconds aWait )
138 {
139 std::call_once( m_started,
140 [this]()
141 {
142 auto promise = std::make_shared<std::promise<T>>();
143
144 m_answer = promise->get_future().share();
145
146 std::thread(
147 [promise, probe = m_probe]()
148 {
149 try
150 {
151 promise->set_value( probe() );
152 }
153 catch( ... )
154 {
155 promise->set_value( T() );
156 }
157 } )
158 .detach();
159 } );
160
161 const std::shared_future<T> answer = m_answer;
162
163 if( answer.wait_for( aWait ) != std::future_status::ready )
164 return std::nullopt;
165
166 return answer.get();
167 }
168
169private:
170 std::function<T()> m_probe;
171 std::once_flag m_started;
172 std::shared_future<T> m_answer;
173};
174
175#endif
std::optional< T > Get(std::chrono::milliseconds aWait)
The probe's answer, or nothing if it has not finished within aWait. A probe that throws answers T().
std::shared_future< T > m_answer
DB_PROBE_LATCH(std::function< T()> aProbe)
std::function< T()> m_probe
std::once_flag m_started
const DB_ROW_SINK & m_sink
DB_READ_DELIVERY & operator=(const DB_READ_DELIVERY &)=delete
bool SinkThrew() const
True if the caller's sink threw.
DB_READ_DELIVERY(const DB_READ_DELIVERY &)=delete
DB_READ_DELIVERY(std::vector< std::string > &aLabels, const DB_ROW_SINK &aSink)
std::shared_ptr< std::vector< std::string > > m_jobLabels
const std::shared_ptr< std::vector< std::string > > & Labels() const
The labels the job fills in.
std::vector< std::string > & m_labels
void Finish()
Copies the labels out if no row did, after the call returned a result.
const DB_ROW_SINK * Sink() const
The sink to pass to the worker call.
static std::string SinkFailureMessage()
The message for a read the caller's sink gave up on.
OUTCOME
Why the last Run or RunCleanup returned without a result.
std::function< void(std::vector< DB_VALUE > &&)> DB_ROW_SINK
Receives one row at a time, in the order of the labels the read produced.
DB_FAILURE
Why a connection attempt failed, as far as the backend's report tells.
DB_WORKER_FAILURE DescribeWorkerOutcome(DB_WORKER_THREAD::OUTCOME aOutcome, const std::string &aPath)
Maps the outcome of a call that returned no result to a failure and a connection decision.
std::string ScrubSecret(std::string aText, const std::string &aSecret)
Replaces a secret in a message, as ***.
std::string utf8(const wxString &aText)
std::string RedactDetail(const std::string &aDetail, const std::string &aSecret)
The provider text to show for a call made with aSecret, which is nothing at all when the secret is sh...
STL namespace.
What a backend reports, and what it does with its connection, when a worker call did not complete.
@ KEEP
Nothing ran, so the connection is intact.
@ DROP
The connection is closed through the worker.
@ FORGET
The stuck job releases the connection itself when its blocked call returns.