8#include <zypp-core/zyppng/base/UnixSignalSource>
13 return ( G_IO_IN | G_IO_HUP );
40 if ( ( rEvents & requestedEvs ) != 0 ) {
47 if ( ( rEvents & G_IO_ERR) && ( requestedEvs & G_IO_ERR ) )
65 (void)
new (&src->
pollfds) std::vector<GUnixPollFD>();
76 g_source_remove_unix_fd( &src->
source, fd.tag );
80 src->
pollfds.std::vector< GUnixPollFD >::~vector();
81 g_source_destroy( &src->
source );
82 g_source_unref( &src->
source );
100 bool hasPending =
false;
102 for (
auto fdIt = src->
pollfds.begin(); fdIt != src->
pollfds.end(); ) {
103 if ( fdIt->tag ==
nullptr ) {
107 fdIt = src->
pollfds.erase( fdIt );
109 GIOCondition pendEvents = g_source_query_unix_fd(
source, fdIt->tag );
110 if ( pendEvents & G_IO_NVAL ){
112 fdIt = src->
pollfds.erase( fdIt );
114 hasPending = hasPending || ( pendEvents & fdIt->reqEvents );
121 return hasPending || src->
pollfds.empty();
130 return G_SOURCE_REMOVE;
140 return G_SOURCE_REMOVE;
146 if ( pollfd.tag !=
nullptr ) {
147 GIOCondition pendEvents = g_source_query_unix_fd(
source, pollfd.tag );
149 if ( (pendEvents & pollfd.reqEvents ) != 0 ) {
154 eventSourceLocked->
onFdReady( pollfd.pollfd, ev );
159 return G_SOURCE_CONTINUE;
184 if ( nextTimeout > G_MAXINT )
187 *timeout =
static_cast<gint
>( nextTimeout );
189 return ( nextTimeout == 0 );
205 if (
source->_t ==
nullptr )
223 g_source_destroy( &src->
source );
224 g_source_unref( &src->
source );
234 if( dPtr->runIdleTasks() ) {
235 return G_SOURCE_CONTINUE;
238 g_source_unref ( dPtr->_idleSource );
239 dPtr->_idleSource =
nullptr;
241 return G_SOURCE_REMOVE;
246 source = g_child_watch_source_new( pid );
251 , source( other.source )
252 , callback( std::move( other.callback ) )
254 other.source =
nullptr;
260 g_source_destroy(
source );
268 source = other.source;
269 callback = std::move( other.callback );
270 other.source =
nullptr;
282 g_main_context_ref (
_ctx );
284 _ctx = g_main_context_new();
293 GLibTimerSource::destruct( src );
296 GAbstractEventSource::destruct( src );
307 g_main_context_unref(
_ctx );
317 while ( runQueue.size() ) {
350 auto data = std::move( that->
_waitPIDs.at(pid) );
354 data.callback( pid, status );
356 g_spawn_close_pid( pid );
360 }
catch (
const std::out_of_range &e ) {
385 auto &evSrcList = d->_eventSources;
386 auto itToEvSrc = std::find_if( evSrcList.begin(), evSrcList.end(), [ notifyPtr ](
const auto elem ){ return elem->eventSource == notifyPtr; } );
387 if ( itToEvSrc == evSrcList.end() ) {
391 evSrcList.push_back( evSrc );
393 g_source_attach( &evSrc->
source, d->_ctx );
396 evSrc = (*itToEvSrc);
399 auto it = std::find_if( evSrc->
pollfds.begin(), evSrc->
pollfds.end(), [fd](
const auto &currPollFd ) {
400 return currPollFd.pollfd == fd;
403 if ( it != evSrc->
pollfds.end() ) {
405 it->reqEvents =
static_cast<GIOCondition
>( cond );
406 g_source_modify_unix_fd( &evSrc->
source, it->tag,
static_cast<GIOCondition
>(cond) );
410 static_cast<GIOCondition
>(cond),
412 g_source_add_unix_fd( &evSrc->
source, fd,
static_cast<GIOCondition
>(cond) )
427 auto &evList = d->_eventSources;
428 auto it = std::find_if( evList.begin(), evList.end(), [ ptr ](
const auto elem ){ return elem->eventSource == ptr; } );
430 if ( it == evList.end() )
433 auto &fdList = (*it)->pollfds;
439 for (
auto &pFD : fdList ) {
441 g_source_remove_unix_fd( &(*it)->source, pFD.tag );
446 auto fdIt = std::find_if( fdList.begin(), fdList.end(), [ fd ](
const auto &pFd ){ return pFd.pollfd == fd; } );
447 if ( fdIt != fdList.end() ) {
449 g_source_remove_unix_fd( &(*it)->source, (*fdIt).tag );
462 if ( t->_t == &timer )
468 d->_runningTimers.push_back( newSrc );
470 g_source_attach( &newSrc->
source, d->_ctx );
476 auto it = std::find_if( d->_runningTimers.begin(), d->_runningTimers.end(), [ &timer ](
const GLibTimerSource *src ){
477 return src->_t == &timer;
480 if ( it != d->_runningTimers.end() ) {
482 d->_runningTimers.erase( it );
489 return d_func()->_ctx;
498 bool eventTriggered =
false;
500 while ( !eventTriggered ) {
501 g_timer_start( *timer );
502 const int res = g_poll( &pollFd, 1, timeout );
512 timeout -= g_timer_elapsed( *timer,
nullptr );
513 if ( timeout < 0 ) timeout = 0;
517 if ( errno == EINTR )
520 ERR <<
"g_poll error: " << strerror(errno) << std::endl;
524 eventTriggered =
true;
537 data.
callback = std::move(callback);
540 data.
tag = g_source_attach ( data.
source, d->_ctx );
541 d->_waitPIDs.insert( std::make_pair( pid, std::move(data) ) );
548 d->_waitPIDs.erase( pid );
549 }
catch (
const std::out_of_range &e ) {
559 UnixSignalSourceRef r;
560 if ( d->_signalSource.expired ()) {
563 r = d->_signalSource.lock ();
570 return g_main_context_iteration( d_func()->
_ctx,
false );
576 d->_idleFuncs.push( std::move(callback) );
577 d->enableIdleSource();
583 d->_unrefLater.push_back( std::move(ptr) );
584 d->enableIdleSource();
589 d_func()->_unrefLater.clear();
594 return d_func()->_runningTimers.size();
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 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
EventDispatcherPrivate(GMainContext *ctx, EventDispatcher &p)
static std::shared_ptr< EventDispatcher > create()
~EventDispatcher() override
UnixSignalSourceRef unixSignalSource()
virtual void registerTimer(Timer &timer)
void clearUnrefLaterList()
ulong runningTimers() const
void unrefLaterImpl(std::shared_ptr< void > &&ptr)
void * nativeDispatcherHandle() const
Returns the native dispatcher handle if the used implementation supports it.
std::function< bool()> IdleFunction
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)
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)
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)
GlibWaitPIDData & operator=(GlibWaitPIDData &&other) noexcept
EventDispatcher::WaitPidCallback callback
GlibWaitPIDData(GPid pid)
std::shared_ptr< EventDispatcher > dispatcher()
static ThreadData & current()
void setDispatcher(const std::shared_ptr< EventDispatcher > &disp)
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
#define ZYPP_IMPL_PRIVATE(Class)