9#include <zypp-core/ng/base/UnixSignalSource>
14 return ( G_IO_IN | G_IO_HUP );
41 if ( ( rEvents & requestedEvs ) != 0 ) {
48 if ( ( rEvents & G_IO_ERR) && ( requestedEvs & G_IO_ERR ) )
66 (void)
new (&src->
pollfds) std::vector<GUnixPollFD>();
77 g_source_remove_unix_fd( &src->
source, fd.
tag );
81 src->
pollfds.std::vector< GUnixPollFD >::~vector();
82 g_source_destroy( &src->
source );
83 g_source_unref( &src->
source );
101 bool hasPending =
false;
103 for (
auto fdIt = src->
pollfds.begin(); fdIt != src->
pollfds.end(); ) {
104 if ( fdIt->tag ==
nullptr ) {
108 fdIt = src->
pollfds.erase( fdIt );
110 GIOCondition pendEvents = g_source_query_unix_fd(
source, fdIt->tag );
111 if ( pendEvents & G_IO_NVAL ){
113 fdIt = src->
pollfds.erase( fdIt );
115 hasPending = hasPending || ( pendEvents & fdIt->reqEvents );
122 return hasPending || src->
pollfds.empty();
131 return G_SOURCE_REMOVE;
141 return G_SOURCE_REMOVE;
147 if ( pollfd.
tag !=
nullptr ) {
148 GIOCondition pendEvents = g_source_query_unix_fd(
source, pollfd.
tag );
150 if ( (pendEvents & pollfd.
reqEvents ) != 0 ) {
160 return G_SOURCE_CONTINUE;
182 uint64_t nextTimeout =
source->_t->remaining();
185 if ( nextTimeout > G_MAXINT )
188 *timeout =
static_cast<gint
>( nextTimeout );
190 return ( nextTimeout == 0 );
206 if (
source->_t ==
nullptr )
224 g_source_destroy( &src->
source );
225 g_source_unref( &src->
source );
235 if( dPtr->runIdleTasks() ) {
236 return G_SOURCE_CONTINUE;
239 g_source_unref ( dPtr->_idleSource );
240 dPtr->_idleSource =
nullptr;
242 return G_SOURCE_REMOVE;
247 source = g_child_watch_source_new( pid );
253 ,
callback( std::move( other.callback ) )
255 other.source =
nullptr;
261 g_source_destroy(
source );
270 callback = std::move( other.callback );
271 other.source =
nullptr;
283 g_main_context_ref (
_ctx );
285 _ctx = g_main_context_new();
294 GLibTimerSource::destruct( src );
297 GAbstractEventSource::destruct( src );
308 g_main_context_unref(
_ctx );
318 while ( runQueue.size() ) {
351 auto data = std::move( that->
_waitPIDs.at(pid) );
355 data.callback( pid, status );
357 g_spawn_close_pid( pid );
361 }
catch (
const std::out_of_range &e ) {
404 auto &evSrcList = d->_eventSources;
405 auto itToEvSrc = std::find_if( evSrcList.begin(), evSrcList.end(), [ notifyPtr ](
const auto elem ){ return elem->eventSource == notifyPtr; } );
406 if ( itToEvSrc == evSrcList.end() ) {
410 evSrcList.push_back( evSrc );
412 g_source_attach( &evSrc->
source, d->_ctx );
415 evSrc = (*itToEvSrc);
418 auto it = std::find_if( evSrc->
pollfds.begin(), evSrc->
pollfds.end(), [fd](
const auto &currPollFd ) {
419 return currPollFd.pollfd == fd;
422 if ( it != evSrc->
pollfds.end() ) {
424 it->reqEvents =
static_cast<GIOCondition
>( cond );
425 g_source_modify_unix_fd( &evSrc->
source, it->tag,
static_cast<GIOCondition
>(cond) );
429 static_cast<GIOCondition
>(cond),
431 g_source_add_unix_fd( &evSrc->
source, fd,
static_cast<GIOCondition
>(cond) )
446 auto &evList = d->_eventSources;
447 auto it = std::find_if( evList.begin(), evList.end(), [ ptr ](
const auto elem ){ return elem->eventSource == ptr; } );
449 if ( it == evList.end() )
452 auto &fdList = (*it)->pollfds;
458 for (
auto &pFD : fdList ) {
460 g_source_remove_unix_fd( &(*it)->source, pFD.tag );
465 auto fdIt = std::find_if( fdList.begin(), fdList.end(), [ fd ](
const auto &pFd ){ return pFd.pollfd == fd; } );
466 if ( fdIt != fdList.end() ) {
468 g_source_remove_unix_fd( &(*it)->source, (*fdIt).tag );
481 if ( t->
_t == &timer )
487 d->_runningTimers.push_back( newSrc );
489 g_source_attach( &newSrc->
source, d->_ctx );
495 auto it = std::find_if( d->_runningTimers.begin(), d->_runningTimers.end(), [ &timer ](
const GLibTimerSource *src ){
496 return src->_t == &timer;
499 if ( it != d->_runningTimers.end() ) {
501 d->_runningTimers.erase( it );
508 return d_func()->_ctx;
517 bool eventTriggered =
false;
519 while ( !eventTriggered ) {
520 g_timer_start( *timer );
521 const int res =
eintrSafeCall( g_poll, &pollFd, 1, timeout );
531 timeout -= g_timer_elapsed( *timer,
nullptr );
532 if ( timeout < 0 ) timeout = 0;
536 ERR <<
"g_poll error: " <<
strerror(errno) << std::endl;
540 eventTriggered =
true;
556 data.
tag = g_source_attach ( data.
source, d->_ctx );
557 d->_waitPIDs.insert( std::make_pair( pid, std::move(data) ) );
564 d->_waitPIDs.erase( pid );
565 }
catch (
const std::out_of_range &e ) {
575 UnixSignalSourceRef r;
576 if ( d->_signalSource.expired ()) {
579 r = d->_signalSource.lock ();
586 return g_main_context_iteration( d_func()->_ctx,
false );
592 d->_idleFuncs.push( std::move(
callback) );
593 d->enableIdleSource();
601 GSource *source = g_timeout_source_new ( timeout );
603 g_source_attach (source, d_func()->_ctx );
604 g_source_unref (source);
610 d->_unrefLater.push_back( std::move(ptr) );
611 d->enableIdleSource();
616 d_func()->_unrefLater.clear();
621 return d_func()->_runningTimers.size();
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Base class for Exception.
std::weak_ptr< EventDispatcher > eventDispatcher() const
virtual void onFdReady(int fd, int events)=0
std::shared_ptr< T > shared_this() const
std::unique_ptr< BasePrivate > d_ptr
~EventDispatcherPrivate() override
std::queue< EventDispatcher::IdleFunction > _idleFuncs
std::vector< std::shared_ptr< void > > _unrefLater
static bool timeoutCallback(gpointer user_data)
static void waitPidCallback(GPid pid, gint status, gpointer user_data)
std::thread::id _myThreadId
std::unordered_map< int, GlibWaitPIDData > _waitPIDs
std::vector< GAbstractEventSource * > _eventSources
std::vector< GLibTimerSource * > _runningTimers
static void timeoutDestroyCallback(gpointer user_data)
EventDispatcherPrivate(GMainContext *ctx, EventDispatcher &p)
static std::shared_ptr< EventDispatcher > create()
~EventDispatcher() override
friend class AbstractEventSource
UnixSignalSourceRef unixSignalSource()
virtual void registerTimer(Timer &timer)
void clearUnrefLaterList()
ulong runningTimers() const
void unrefLaterImpl(std::shared_ptr< void > &&ptr)
std::function< bool()> TimeoutFunction
void * nativeDispatcherHandle() const
Returns the native dispatcher handle if the used implementation supports it.
std::function< bool()> IdleFunction
EventDispatcher(void *ctx=nullptr)
static bool waitForFdEvent(const int fd, int events, int &revents, int &timeout)
virtual void removeTimer(Timer &timer)
void trackChildProcess(int pid, std::function< void(int, int)> callback)
bool untrackChildProcess(int pid)
virtual void updateEventSource(AbstractEventSource ¬ifier, int fd, int mode)
virtual void removeEventSource(AbstractEventSource ¬ifier, int fd=-1)
static void setThreadDispatcher(const std::shared_ptr< EventDispatcher > &disp)
static std::shared_ptr< EventDispatcher > instance()
void invokeOnIdleImpl(IdleFunction &&callback)
void invokeAfterImpl(TimeoutFunction &&callback, uint32_t timeout)
The Timer class provides repetitive and single-shot timers.
static UnixSignalSourceRef create()
static gboolean eventLoopIdleFunc(gpointer user_data)
Called when the event loop is idle, here we run cleanup tasks and call later() callbacks of the user.
static GSourceFuncs glibTimerSourceFuncs
static int gioConditionToEventTypes(const GIOCondition rEvents, const int requestedEvs)
std::string strerror(int errno_r) ZYPP_API
Return string describing the error_r code.
auto eintrSafeCall(Fun &&function, Args &&... args)
static int evModeToMask(int mode)
static GSourceFuncs abstractEventSourceFuncs
static gboolean check(GSource *source)
std::vector< GUnixPollFD > pollfds
AbstractEventSource * eventSource
static gboolean dispatch(GSource *source, GSourceFunc, gpointer)
static GAbstractEventSource * create(EventDispatcherPrivate *ev)
static void destruct(GAbstractEventSource *src)
static gboolean prepare(GSource *, gint *timeout)
EventDispatcherPrivate * _ev
static void destruct(GLibTimerSource *src)
static gboolean prepare(GSource *src, gint *timeout)
static gboolean check(GSource *source)
static GLibTimerSource * create()
static gboolean dispatch(GSource *source, GSourceFunc, gpointer)
std::function< bool()> _callback
GlibWaitPIDData & operator=(GlibWaitPIDData &&other) noexcept
EventDispatcher::WaitPidCallback callback
GlibWaitPIDData(GPid pid)
std::shared_ptr< EventDispatcher > dispatcher()
static ZYPP_API ThreadData & current()
void setDispatcher(const std::shared_ptr< EventDispatcher > &disp)
#define ZYPP_IMPL_PRIVATE(Class)