libzypp: zypp-core/zyppng/async/asyncop.h Source File

libzypp 17.36.6

asyncop.h
Go to the documentation of this file.
1/*---------------------------------------------------------------------\
2| ____ _ __ __ ___ |
3| |__ / \ / / . \ . \ |
4| / / \ V /| _/ _/ |
5| / /__ | | | | | | |
6| /_____||_| |_| |_| |
7| |
8----------------------------------------------------------------------/
9*
10* This file contains private API, this might break at any time between releases.
11* You have been warned!
12*
13*/
14#ifndef ZYPPNG_ASYNC_ASYNCOP_H_INCLUDED
15#define ZYPPNG_ASYNC_ASYNCOP_H_INCLUDED
16
17#include <zypp-core/zyppng/meta/type_traits.h>
18#include <zypp-core/zyppng/base/Base>
19#include <zypp-core/base/Exception.h>
20#include <zypp-core/zyppng/base/Signals>
21#include <optional>
22#include <memory>
23
24namespace zyppng {
25
26 template <typename Result> struct AsyncOp;
27 ZYPP_FWD_DECL_TYPE_WITH_REFS ( AsyncOpBase );
28
29 namespace detail {
30 template <typename T, typename Enable = std::void_t<> >
31 struct has_value_type : public std::false_type{};
32
33 template <typename T>
34 struct has_value_type<T, std::void_t<typename T::value_type>> : public std::true_type {};
35
36 template <typename T>
37 constexpr bool has_value_type_v = has_value_type<T>::value;
38
39 template <typename T, typename Enable = void >
40 struct is_asyncop_type : public std::false_type{};
41
42 template <typename T>
43 struct is_asyncop_type<T, std::enable_if_t< std::is_convertible_v<T*, AsyncOp<typename T::value_type>*> >> : public std::true_type{};
44
45 template <typename T>
46 constexpr bool is_asyncop_type_v = is_asyncop_type<T>::value;
47
54 template <typename T>
55 using is_async_op = std::conjunction<
56 has_value_type<remove_smart_ptr_t<T>>,
57 is_asyncop_type<remove_smart_ptr_t<T> >
58 >;
59
60 template < typename T>
61 constexpr bool is_async_op_v = is_async_op<T>::value;
62 }
63
68 class AsyncOpNotReadyException : public zypp::Exception
69 {
70 public:
71 AsyncOpNotReadyException()
72 : Exception( "AsyncOp instance not ready" )
73 {}
74 ~AsyncOpNotReadyException() override;
75 };
76 inline AsyncOpNotReadyException::~AsyncOpNotReadyException() { }
77
78 class CancelNotImplementedException : public zypp::Exception
79 {
80 public:
81 CancelNotImplementedException()
82 : Exception ("AsyncOp does not support cancelling the operation")
83 {}
84 ~CancelNotImplementedException() override;
85 };
86 inline CancelNotImplementedException::~CancelNotImplementedException() { }
87
88
89 class AsyncOpBase : public Base {
90
91 public:
92
96 virtual bool canCancel () {
97 return false;
98 }
99
108 virtual void cancel () {
109 throw CancelNotImplementedException();
110 }
111
115 SignalProxy<void()> sigStarted () {
116 return _sigStarted;
117 }
118
123 SignalProxy<void( const std::string & /*text*/, int /*current*/, int /*max*/ )> sigProgress () {
124 return _sigProgress;
125 }
126
131 SignalProxy<void()> sigReady () {
132 return _sigReady;
133 }
134
135 protected:
136 Signal<void()> _sigStarted;
137 Signal<void()> _sigReady;
138 Signal<void( const std::string & /*text*/, int /*current*/, int /*max*/ )> _sigProgress;
139 };
140
160 template <typename Result>
161 struct AsyncOp : public AsyncOpBase {
162
163 static_assert(!detail::is_async_op_v<Result>, "A async op can never have a async result");
164
165 using value_type = Result;
166 using Ptr = std::shared_ptr<AsyncOp<Result>>;
167
168 AsyncOp () = default;
169
170 AsyncOp ( const AsyncOp &other ) = delete;
171 AsyncOp& operator= ( const AsyncOp &other ) = delete;
172
173 AsyncOp& operator= ( AsyncOp &&other ) noexcept = default;
174 AsyncOp ( AsyncOp &&other ) noexcept = default;
175
176 ~AsyncOp() override{}
177
183 void setReady ( value_type && val ) {
184 if ( _readyCb ) {
185 // use a weak reference to know if `this` was deleted by the callback()
186 auto weak = weak_from_this();
187 _readyCb( std::move( val ) );
188 if ( !weak.expired() )
189 _readyCb = {};
190 }
191 else { //we need to cache the value because no callback is available
192 _maybeValue = std::move(val);
193 _sigReady.emit();
194 }
195 }
196
202 bool isReady () const {
203 return _maybeValue.has_value();
204 }
205
217 template< typename Fun >
218 void onReady ( Fun &&cb ) {
219 this->_readyCb = std::forward<Fun>(cb);
220
221 if ( isReady() ) {
222 // use a weak reference to know if `this` was deleted by the callback()
223 auto weak = weak_from_this();
224
225 _readyCb( std::move( _maybeValue.value()) );
226
227 if ( !weak.expired() ) {
228 // value was passed on, reset the optional
229 _maybeValue.reset();
230
231 // reset the callback, it might be a lambda with captured ressources
232 // that need to be released after returning from the func
233 _readyCb = {};
234 }
235 }
236 }
237
242 value_type &get (){
243 if ( !isReady() )
244 ZYPP_THROW(AsyncOpNotReadyException());
245 return _maybeValue.value();
246 }
247
248 private:
249 std::function<void(value_type &&)> _readyCb;
250 std::optional<value_type> _maybeValue;
251 };
252
253
254 template <typename T>
255 using AsyncOpRef = std::shared_ptr<AsyncOp<T>>;
256
257
265 template <typename Base, typename Result = typename Base::value_type>
266 struct NestedAsyncOpMixin
267 {
268 template <typename ...Args>
269 void operator ()( Args &&...args ) {
270 assert(!_nestedPipeline);
271 _nestedPipeline = static_cast<Base *>(this)->makePipeline( std::forward<Args>(args)...);
272 _nestedPipeline->onReady([this]( auto &&val ){
273 static_cast<Base *>(this)->setReady( std::forward<decltype(val)>(val) );
274 });
275 }
276
277 private:
278 AsyncOpRef<Result> _nestedPipeline;
279 };
280
281 namespace detail {
282 //A async result that is ready right away
283 template <typename T>
284 struct ReadyResult : public zyppng::AsyncOp< T >
285 {
286 ReadyResult( T &&val ) {
287 this->setReady( std::move(val) );
288 }
289 };
290 }
291
296 template <typename T, bool isAsync = true>
297 std::conditional_t<isAsync, AsyncOpRef<T>, T> makeReadyResult ( T && result ) {
298 if constexpr ( isAsync ) {
299 return std::make_shared<detail::ReadyResult<T>>( std::forward<T>(result) );
300 } else {
301 return result;
302 }
303 }
304
305}
306
307
308
309#endif
zypp::Exception
Base class for Exception.
Definition Exception.h:147
zypp::Exception::Exception
Exception()
Default ctor.
Definition Exception.cc:81
zyppng::AsyncOpBase
Definition asyncop.h:89
zyppng::AsyncOpBase::cancel
virtual void cancel()
Definition asyncop.h:108
zyppng::AsyncOpBase::sigStarted
SignalProxy< void()> sigStarted()
Definition asyncop.h:115
zyppng::AsyncOpBase::_sigReady
Signal< void()> _sigReady
Definition asyncop.h:137
zyppng::AsyncOpBase::_sigProgress
Signal< void(const std::string &, int, int)> _sigProgress
Definition asyncop.h:138
zyppng::AsyncOpBase::sigProgress
SignalProxy< void(const std::string &, int, int)> sigProgress()
Definition asyncop.h:123
zyppng::AsyncOpBase::sigReady
SignalProxy< void()> sigReady()
Definition asyncop.h:131
zyppng::AsyncOpBase::canCancel
virtual bool canCancel()
Definition asyncop.h:96
zyppng::AsyncOpBase::_sigStarted
Signal< void()> _sigStarted
Definition asyncop.h:136
zyppng::AsyncOpNotReadyException
Definition asyncop.h:69
zyppng::AsyncOpNotReadyException::AsyncOpNotReadyException
AsyncOpNotReadyException()
Definition asyncop.h:71
zyppng::AsyncOpNotReadyException::~AsyncOpNotReadyException
~AsyncOpNotReadyException() override
Definition asyncop.h:76
zyppng::Base
Definition base.h:60
zyppng::Base::Base
Base()
Definition base.cc:20
zyppng::CancelNotImplementedException
Definition asyncop.h:79
zyppng::CancelNotImplementedException::CancelNotImplementedException
CancelNotImplementedException()
Definition asyncop.h:81
zyppng::CancelNotImplementedException::~CancelNotImplementedException
~CancelNotImplementedException() override
Definition asyncop.h:86
zyppng::SignalProxy
Definition signals.h:325
zyppng::Signal
Definition signals.h:151
std
Definition Arch.h:364
std::conditional_t
typename conditional< B, T, F >::type conditional_t
Definition TypeTraits.h:39
zyppng::detail
Definition reporthelper.h:31
zyppng::detail::is_async_op_v
constexpr bool is_async_op_v
Definition asyncop.h:61
zyppng::detail::is_async_op
std::conjunction< has_value_type< remove_smart_ptr_t< T > >, is_asyncop_type< remove_smart_ptr_t< T > > > is_async_op
Definition asyncop.h:55
zyppng::detail::has_value_type_v
constexpr bool has_value_type_v
Definition asyncop.h:37
zyppng::detail::is_asyncop_type_v
constexpr bool is_asyncop_type_v
Definition asyncop.h:46
zyppng
Definition MediaCurl2.h:22
zyppng::makeReadyResult
std::conditional_t< isAsync, AsyncOpRef< T >, T > makeReadyResult(T &&result)
Definition asyncop.h:297
zyppng::AsyncOpRef
std::shared_ptr< AsyncOp< T > > AsyncOpRef
Definition asyncop.h:255
std::conjunction
Definition type_traits.h:90
zyppng::AsyncOp
Definition asyncop.h:161
zyppng::AsyncOp::AsyncOp
AsyncOp(AsyncOp &&other) noexcept=default
zyppng::AsyncOp::isReady
bool isReady() const
Definition asyncop.h:202
zyppng::AsyncOp::_maybeValue
std::optional< value_type > _maybeValue
Definition asyncop.h:250
zyppng::AsyncOp::setReady
void setReady(value_type &&val)
Definition asyncop.h:183
zyppng::AsyncOp::value_type
Result value_type
Definition asyncop.h:165
zyppng::AsyncOp::get
value_type & get()
Definition asyncop.h:242
zyppng::AsyncOp::operator=
AsyncOp & operator=(const AsyncOp &other)=delete
zyppng::AsyncOp::AsyncOp
AsyncOp()=default
zyppng::AsyncOp::_readyCb
std::function< void(value_type &&)> _readyCb
Definition asyncop.h:249
zyppng::AsyncOp::AsyncOp
AsyncOp(const AsyncOp &other)=delete
zyppng::AsyncOp::Ptr
std::shared_ptr< AsyncOp< Result > > Ptr
Definition asyncop.h:166
zyppng::AsyncOp::onReady
void onReady(Fun &&cb)
Definition asyncop.h:218
zyppng::AsyncOp::~AsyncOp
~AsyncOp() override
Definition asyncop.h:176
zyppng::NestedAsyncOpMixin
Definition asyncop.h:267
zyppng::NestedAsyncOpMixin::operator()
void operator()(Args &&...args)
Definition asyncop.h:269
zyppng::NestedAsyncOpMixin::_nestedPipeline
AsyncOpRef< Result > _nestedPipeline
Definition asyncop.h:278
zyppng::detail::ReadyResult::ReadyResult
ReadyResult(T &&val)
Definition asyncop.h:286
zyppng::detail::has_value_type
Definition asyncop.h:31
zyppng::detail::is_asyncop_type
Definition asyncop.h:40
type_traits.h
Exception.h
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:424
ZYPP_FWD_DECL_TYPE_WITH_REFS
#define ZYPP_FWD_DECL_TYPE_WITH_REFS(T)
Definition zyppglobal.h:126