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 );
252 , source( other.source )
253 , callback( std::move( other.callback ) )
255 other.source =
nullptr;
261 g_source_destroy(
source );
269 source = other.source;
270 callback = std::move( other.callback );
271 other.source =
nullptr;
283 g_main_context_ref (
_ctx );
285 _ctx = g_main_context_new();
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;
553 data.callback = std::move(callback);
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 d_func()->_ctx;
591 return g_main_context_iteration( d_func()->
_ctx,
false );
597 d->_idleFuncs.push( std::move(callback) );
598 d->enableIdleSource();
604 userData->
_callback = std::move(callback);
606 GSource *source = g_timeout_source_new ( timeout );
608 g_source_attach (source, d_func()->
_ctx );
609 g_source_unref (source);
615 d->_unrefLater.push_back( std::move(ptr) );
616 d->enableIdleSource();
621 d_func()->_unrefLater.clear();
626 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.
GMainContext * glibContext()
std::function< bool()> IdleFunction
static UnixSignalSourceRef create()
static void destruct(GAbstractEventSource *src)
virtual void onFdReady(int fd, int events)=0
static void timeoutDestroyCallback(gpointer user_data)
static void setThreadDispatcher(const std::shared_ptr< EventDispatcher > &disp)
~EventDispatcher() override
static gboolean check(GSource *source)
std::function< bool()> TimeoutFunction
std::shared_ptr< EventDispatcher > dispatcher()
GlibWaitPIDData(GPid pid)
static GLibTimerSource * create()
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)
std::string strerror(int errno_r)
Return string describing the error_r code.
static void destruct(GLibTimerSource *src)
EventDispatcherPrivate(GMainContext *ctx, EventDispatcher &p)
static bool timeoutCallback(gpointer user_data)
void unrefLaterImpl(std::shared_ptr< void > &&ptr)
repo::DownloadContextRef _ctx
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
std::function< bool()> _callback
EventDispatcherPrivate * _ev
static void waitPidCallback(GPid pid, gint status, gpointer user_data)
virtual void registerTimer(Timer &timer)
static gboolean prepare(GSource *, gint *timeout)
static ZYPP_API ThreadData & current()
std::vector< GUnixPollFD > pollfds
virtual void removeEventSource(AbstractEventSource ¬ifier, int fd=-1)
Base class for Exception.
std::queue< EventDispatcher::IdleFunction > _idleFuncs
auto eintrSafeCall(Fun &&function, Args &&... args)
static int evModeToMask(int mode)
void * data(uint32_t quark)
void invokeAfterImpl(TimeoutFunction &&callback, uint32_t timeout)
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 std::shared_ptr< EventDispatcher > create(GMainContext *ctx=0)
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
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
struct _GMainContext GMainContext
static gboolean check(GSource *source)
std::thread::id _myThreadId
std::unordered_map< int, GlibWaitPIDData > _waitPIDs