10 return ( G_IO_IN | G_IO_HUP );
30 return &threadDispatch;
45 (void)
new (&src->
pollfds) std::vector<GUnixPollFD>();
56 g_source_remove_unix_fd( &src->
source, fd.
tag );
60 src->
pollfds.std::vector< GUnixPollFD >::~vector();
61 g_source_destroy( &src->
source );
62 g_source_unref( &src->
source );
80 bool hasPending =
false;
82 for (
auto fdIt = src->
pollfds.begin(); fdIt != src->
pollfds.end(); ) {
83 if ( fdIt->tag ==
nullptr ) {
87 fdIt = src->
pollfds.erase( fdIt );
89 GIOCondition pendEvents = g_source_query_unix_fd(
source, fdIt->tag );
90 if ( pendEvents & G_IO_NVAL ){
92 fdIt = src->
pollfds.erase( fdIt );
94 hasPending = hasPending || ( pendEvents & fdIt->reqEvents );
101 return hasPending || src->
pollfds.empty();
110 return G_SOURCE_REMOVE;
120 return G_SOURCE_REMOVE;
126 if ( pollfd.
tag !=
nullptr ) {
127 GIOCondition pendEvents = g_source_query_unix_fd(
source, pollfd.
tag );
129 if ( (pendEvents & pollfd.
reqEvents ) != 0 ) {
137 if ( (pendEvents & G_IO_ERR) && ( pollfd.
reqEvents & G_IO_ERR ) )
145 return G_SOURCE_CONTINUE;
167 uint64_t nextTimeout =
source->_t->remaining();
170 if ( nextTimeout > G_MAXINT )
173 *
timeout =
static_cast<gint
>( nextTimeout );
175 return ( nextTimeout == 0 );
191 if (
source->_t ==
nullptr )
209 g_source_destroy( &src->
source );
210 g_source_unref( &src->
source );
220 if( dPtr->runIdleTasks() ) {
221 return G_SOURCE_CONTINUE;
224 return G_SOURCE_REMOVE;
236 g_main_context_ref (
_ctx );
238 _ctx = g_main_context_get_thread_default();
240 _ctx = g_main_context_new();
242 g_main_context_ref (
_ctx );
245 g_main_context_push_thread_default(
_ctx );
266 g_main_context_pop_thread_default(
_ctx );
267 g_main_context_unref(
_ctx );
268 g_main_loop_unref(
_loop );
280 rerunQueue.push( std::move(fun) );
282 if ( !rerunQueue.empty() )
308 return std::shared_ptr<EventDispatcher>(
new EventDispatcher(g_main_context_default()) );
328 auto &evSrcList = d->_eventSources;
329 auto itToEvSrc = std::find_if( evSrcList.begin(), evSrcList.end(), [ notifier ](
const auto elem ){
return elem->eventSource == notifier; } );
330 if ( itToEvSrc == evSrcList.end() ) {
334 evSrcList.push_back( evSrc );
336 g_source_attach( &evSrc->
source, d->_ctx );
339 evSrc = (*itToEvSrc);
349 cond = cond |
excpMask() | G_IO_ERR;
352 auto it = std::find_if( evSrc->
pollfds.begin(), evSrc->
pollfds.end(), [fd](
const auto &currPollFd ) {
353 return currPollFd.pollfd == fd;
356 if ( it != evSrc->
pollfds.end() ) {
358 it->reqEvents =
static_cast<GIOCondition
>( cond );
359 g_source_modify_unix_fd( &evSrc->
source, it->tag, static_cast<GIOCondition>(cond) );
363 static_cast<GIOCondition
>(cond),
365 g_source_add_unix_fd( &evSrc->
source, fd, static_cast<GIOCondition>(cond) )
378 auto &evList = d->_eventSources;
379 auto it = std::find_if( evList.begin(), evList.end(), [ notifier ](
const auto elem ){
return elem->eventSource == notifier; } );
381 if ( it == evList.end() )
384 auto &fdList = (*it)->pollfds;
390 for (
auto &pFD : fdList ) {
392 g_source_remove_unix_fd( &(*it)->source, pFD.tag );
397 auto fdIt = std::find_if( fdList.begin(), fdList.end(), [ fd ](
const auto &pFd ){
return pFd.pollfd == fd; } );
398 if ( fdIt != fdList.end() ) {
400 g_source_remove_unix_fd( &(*it)->source, (*fdIt).tag );
413 if ( t->
_t == timer )
419 d->_runningTimers.push_back( newSrc );
421 g_source_attach( &newSrc->
source, d->_ctx );
427 auto it = std::find_if( d->_runningTimers.begin(), d->_runningTimers.end(), [ timer ](
const GLibTimerSource *src ){
428 return src->_t == timer;
431 if ( it != d->_runningTimers.end() ) {
433 d->_runningTimers.erase( it );
440 return g_main_context_iteration( d_func()->_ctx,
false );
445 g_main_loop_run( d_func()->_loop );
450 g_main_loop_quit( d_func()->_loop );
456 d->_idleFuncs.push( std::move(callback) );
457 d->enableIdleSource();
463 d->_unrefLater.push_back( std::forward< std::shared_ptr<void> >(ptr) );
464 d->enableIdleSource();
469 return d_func()->_runningTimers.size();
477 return std::shared_ptr<EventDispatcher>();
std::vector< std::shared_ptr< void > > _unrefLater
std::vector< GAbstractEventSource * > _eventSources
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
std::function< bool()> IdleFunction
static void destruct(GAbstractEventSource *src)
virtual void onFdReady(int fd, int events)=0
virtual ~EventDispatcher()
static std::shared_ptr< EventDispatcher > createForThread()
EventDispatcherPrivate(GMainContext *ctx)
static gboolean check(GSource *source)
static GLibTimerSource * create()
virtual void removeTimer(Timer *timer)
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 void destruct(GLibTimerSource *src)
void unrefLaterImpl(std::shared_ptr< void > &&ptr)
static EventDispatcher ** threadLocalDispatcher(EventDispatcher *set=nullptr)
static std::shared_ptr< EventDispatcher > createMain()
virtual void registerTimer(Timer *timer)
The Timer class provides repetitive and single-shot timers.
static GSourceFuncs glibTimerSourceFuncs
EventDispatcher(void *ctx=nullptr)
std::vector< GLibTimerSource * > _runningTimers
static std::shared_ptr< EventDispatcher > instance()
ulong runningTimers() const
static GSourceFuncs abstractEventSourceFuncs
EventDispatcherPrivate * _ev
static gboolean prepare(GSource *, gint *timeout)
std::vector< GUnixPollFD > pollfds
Base class for Exception.
std::queue< EventDispatcher::IdleFunction > _idleFuncs
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
virtual ~EventDispatcherPrivate()
virtual void updateEventSource(AbstractEventSource *notifier, int fd, int mode)
void invokeOnIdleImpl(IdleFunction &&callback)
static gboolean dispatch(GSource *source, GSourceFunc, gpointer)
virtual void removeEventSource(AbstractEventSource *notifier, int fd=-1)
static gboolean check(GSource *source)
std::thread::id _myThreadId