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 ) {
159 return G_SOURCE_CONTINUE;
181 uint64_t nextTimeout =
source->_t->remaining();
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();
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();
~EventDispatcherPrivate() override
virtual void removeTimer(Timer &timer)
std::vector< std::shared_ptr< void > > _unrefLater
std::vector< GAbstractEventSource * > _eventSources
GlibWaitPIDData & operator=(GlibWaitPIDData &&other) noexcept
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
std::function< bool()> IdleFunction
static UnixSignalSourceRef create()
static void destruct(GAbstractEventSource *src)
virtual void onFdReady(int fd, int events)=0
static std::shared_ptr< EventDispatcher > create()
static void setThreadDispatcher(const std::shared_ptr< EventDispatcher > &disp)
~EventDispatcher() override
static gboolean check(GSource *source)
GlibWaitPIDData(GPid pid)
static GLibTimerSource * create()
EventDispatcher::WaitPidCallback callback
static int gioConditionToEventTypes(const GIOCondition rEvents, const int requestedEvs)
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...
void * nativeDispatcherHandle() const
Returns the native dispatcher handle if the used implementation supports it.
static bool waitForFdEvent(const int fd, int events, int &revents, int &timeout)
static void destruct(GLibTimerSource *src)
EventDispatcherPrivate(GMainContext *ctx, EventDispatcher &p)
void unrefLaterImpl(std::shared_ptr< void > &&ptr)
The Timer class provides repetitive and single-shot timers.
static GSourceFuncs glibTimerSourceFuncs
void trackChildProcess(int pid, std::function< void(int, int)> callback)
virtual void updateEventSource(AbstractEventSource ¬ifier, int fd, int mode)
std::vector< GLibTimerSource * > _runningTimers
static std::shared_ptr< EventDispatcher > instance()
void clearUnrefLaterList()
ulong runningTimers() const
static GSourceFuncs abstractEventSourceFuncs
EventDispatcherPrivate * _ev
static void waitPidCallback(GPid pid, gint status, gpointer user_data)
virtual void registerTimer(Timer &timer)
static gboolean prepare(GSource *, gint *timeout)
static ThreadData & current()
std::vector< GUnixPollFD > pollfds
virtual void removeEventSource(AbstractEventSource ¬ifier, int fd=-1)
Base class for Exception.
std::queue< EventDispatcher::IdleFunction > _idleFuncs
static int evModeToMask(int mode)
ZYPP_IMPL_PRIVATE(UnixSignalSource)
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
static gboolean dispatch(GSource *source, GSourceFunc, gpointer)
static gboolean prepare(GSource *src, gint *timeout)
static GAbstractEventSource * create(EventDispatcherPrivate *ev)
std::weak_ptr< EventDispatcher > eventDispatcher() const
AbstractEventSource * eventSource
std::unique_ptr< BasePrivate > d_ptr
std::shared_ptr< EventDispatcher > dispatcher()
std::string strerror(int errno_r)
Return string describing the error_r code.
bool untrackChildProcess(int pid)
void invokeOnIdleImpl(IdleFunction &&callback)
void setDispatcher(const std::shared_ptr< EventDispatcher > &disp)
UnixSignalSourceRef unixSignalSource()
static gboolean dispatch(GSource *source, GSourceFunc, gpointer)
std::shared_ptr< T > shared_this() const
static gboolean check(GSource *source)
std::thread::id _myThreadId
std::unordered_map< int, GlibWaitPIDData > _waitPIDs