libzypp: zypp-core/ng/base/eventdispatcher_glib.cc Source File

libzypp 17.38.9

eventdispatcher_glib.cc
Go to the documentation of this file.
1#include "timer.h"
2#include "private/eventdispatcher_glib_p.h"
3#include "private/threaddata_p.h"
4#include <zypp-core/ng/base/private/linuxhelpers_p.h>
5
6#include <zypp-core/base/Exception.h>
7#include <zypp-core/base/Logger.h>
8#include <zypp-core/AutoDispose.h>
9#include <zypp-core/ng/base/UnixSignalSource>
10
11namespace zyppng {
12
13 static int inline readMask () {
14 return ( G_IO_IN | G_IO_HUP );
15}
16
17 static int inline writeMask () {
18 return ( G_IO_OUT );
19}
20
21 static int inline excpMask () {
22 return ( G_IO_PRI );
23}
24
25 static int inline evModeToMask ( int mode ) {
26 int cond = 0;
27 if ( mode & AbstractEventSource::Read ) {
28 cond = readMask() | G_IO_ERR;
29 }
30 if ( mode & AbstractEventSource::Write ) {
31 cond = cond | writeMask() | G_IO_ERR;
32 }
33 if ( mode & AbstractEventSource::Exception ) {
34 cond = cond | excpMask() | G_IO_ERR;
35 }
36 return cond;
37}
38
39 static int inline gioConditionToEventTypes ( const GIOCondition rEvents, const int requestedEvs ) {
40 int ev = 0;
41 if ( ( rEvents & requestedEvs ) != 0 ) {
42 if ( ( rEvents & readMask() ) && ( requestedEvs & readMask() ) )
43 ev = AbstractEventSource::Read;
44 if ( ( rEvents & writeMask() ) && ( requestedEvs & writeMask() ) )
45 ev = ev | AbstractEventSource::Write;
46 if ( ( rEvents & excpMask()) && ( requestedEvs & excpMask() ) )
47 ev = ev | AbstractEventSource::Exception;
48 if ( ( rEvents & G_IO_ERR) && ( requestedEvs & G_IO_ERR ) )
49 ev = ev | AbstractEventSource::Error;
50 }
51 return ev;
52}
53
54 static GSourceFuncs abstractEventSourceFuncs = {
55 GAbstractEventSource::prepare,
56 GAbstractEventSource::check,
57 GAbstractEventSource::dispatch,
58 nullptr,
59 nullptr,
60 nullptr
61};
62
63 GAbstractEventSource *GAbstractEventSource::create(EventDispatcherPrivate *ev ) {
64 GAbstractEventSource *src = nullptr;
65 src = reinterpret_cast<GAbstractEventSource *>(g_source_new(&abstractEventSourceFuncs, sizeof(GAbstractEventSource)));
66 (void) new (&src->pollfds) std::vector<GUnixPollFD>();
67
68 src->eventSource = nullptr;
69 src->_ev = ev;
70 return src;
71}
72
73 void GAbstractEventSource::destruct(GAbstractEventSource *src)
74{
75 for ( GUnixPollFD &fd : src->pollfds ) {
76 if ( fd.tag )
77 g_source_remove_unix_fd( &src->source, fd.tag );
78 }
79
80 src->pollfds.clear();
81 src->pollfds.std::vector< GUnixPollFD >::~vector();
82 g_source_destroy( &src->source );
83 g_source_unref( &src->source );
84}
85
86gboolean GAbstractEventSource::prepare(GSource *, gint *timeout)
87{
88 //we can not yet determine if the GSource is ready, polling FDs also have no
89 //timeout, so lets continue
90 if ( timeout )
91 *timeout = -1;
92 return false;
93}
94
95//here we need to figure out which FDs are pending
96gboolean GAbstractEventSource::check( GSource *source )
97{
98 GAbstractEventSource *src = reinterpret_cast<GAbstractEventSource*>( source );
99
100 //check for pending and remove orphaned entries
101 bool hasPending = false;
102
103 for ( auto fdIt = src->pollfds.begin(); fdIt != src->pollfds.end(); ) {
104 if ( fdIt->tag == nullptr ) {
105 //this pollfd was removed, clear it from the list
106 //for now keep the object in the sources list if the pollfd list gets empty, if it does not register new events until
107 //next check it is removed for good
108 fdIt = src->pollfds.erase( fdIt );
109 } else {
110 GIOCondition pendEvents = g_source_query_unix_fd( source, fdIt->tag );
111 if ( pendEvents & G_IO_NVAL ){
112 //that poll is broken, do we need to do more????
113 fdIt = src->pollfds.erase( fdIt );
114 } else {
115 hasPending = hasPending || ( pendEvents & fdIt->reqEvents );
116 fdIt++;
117 }
118 }
119 }
120
121 //if the pollfds are empty trigger dispatch so this source can be removed
122 return hasPending || src->pollfds.empty();
123}
124
125//Trigger all event sources that have been activated
126gboolean GAbstractEventSource::dispatch(GSource *source, GSourceFunc, gpointer)
127{
128 GAbstractEventSource *src = reinterpret_cast<GAbstractEventSource*>( source );
129
130 if ( !src )
131 return G_SOURCE_REMOVE;
132
133 //sources are only removed here so we do not accidentially mess with the pollfd iterator in the next loop
134 //were we trigger all ready FDs
135 if ( src->pollfds.empty() ) {
136 auto it = std::find( src->_ev->_eventSources.begin(), src->_ev->_eventSources.end(), src );
137
138 if ( it != src->_ev->_eventSources.end() ) {
139 GAbstractEventSource::destruct( *it );
140 src->_ev->_eventSources.erase( it );
141 return G_SOURCE_REMOVE;
142 }
143 }
144
145 for ( const GUnixPollFD &pollfd : src->pollfds ) {
146 //do not trigger orphaned ones
147 if ( pollfd.tag != nullptr ) {
148 GIOCondition pendEvents = g_source_query_unix_fd( source, pollfd.tag );
149
150 if ( (pendEvents & pollfd.reqEvents ) != 0 ) {
151 int ev = gioConditionToEventTypes( pendEvents, pollfd.reqEvents );
152 // we require all event objects to be used in shared_ptr form, by doing this we make sure that the object is not destroyed
153 // while we still use it. However this WILL throw in case of using the EventSource outside of shared_ptr bounds
154 auto eventSourceLocked = src->eventSource->shared_this<AbstractEventSource>();
155 eventSourceLocked->onFdReady( pollfd.pollfd, ev );
156 }
157 }
158 }
159
160 return G_SOURCE_CONTINUE;
161}
162
163 static GSourceFuncs glibTimerSourceFuncs = {
164 GLibTimerSource::prepare,
165 GLibTimerSource::check,
166 GLibTimerSource::dispatch,
167 nullptr,
168 nullptr,
169 nullptr
170};
171
172//check when this timer expires and set the correct timeout
173gboolean GLibTimerSource::prepare(GSource *src, gint *timeout)
174{
175 GLibTimerSource *source = reinterpret_cast<GLibTimerSource *>( src );
176 if ( !source )
177 return false; //not ready for dispatch
178
179 if ( !source->_t )
180 return false;
181
182 uint64_t nextTimeout = source->_t->remaining();
183 if ( timeout ) {
184 //this would be a really looong timeout, but be safe
185 if ( nextTimeout > G_MAXINT )
186 *timeout = G_MAXINT;
187 else
188 *timeout = static_cast<gint>( nextTimeout );
189 }
190 return ( nextTimeout == 0 );
191}
192
193//this is essentially the same as prepare
194gboolean GLibTimerSource::check(GSource *source)
195{
196 return prepare( source, nullptr );
197}
198
199//emit the expired timers, restart timers that are no single shots
200gboolean GLibTimerSource::dispatch(GSource *src, GSourceFunc, gpointer)
201{
202 GLibTimerSource *source = reinterpret_cast<GLibTimerSource *>( src );
203 if ( !source )
204 return true;
205
206 if ( source->_t == nullptr )
207 return true;
208 //this will emit the expired signal and reset the timer
209 //or stop it in case its a single shot timer
210 source->_t->shared_this<Timer>()->expire();
211 return true;
212}
213
214 GLibTimerSource *GLibTimerSource::create()
215{
216 GLibTimerSource *src = nullptr;
217 src = reinterpret_cast<GLibTimerSource *>(g_source_new(&glibTimerSourceFuncs, sizeof(GLibTimerSource)));
218 src->_t = nullptr;
219 return src;
220}
221
222 void GLibTimerSource::destruct(GLibTimerSource *src)
223{
224 g_source_destroy( &src->source );
225 g_source_unref( &src->source );
226}
227
231 static gboolean eventLoopIdleFunc ( gpointer user_data )
232{
233 auto dPtr = reinterpret_cast<EventDispatcherPrivate *>( user_data );
234 if ( dPtr ) {
235 if( dPtr->runIdleTasks() ) {
236 return G_SOURCE_CONTINUE;
237 }
238
239 g_source_unref ( dPtr->_idleSource );
240 dPtr->_idleSource = nullptr;
241 }
242 return G_SOURCE_REMOVE;
243}
244
245GlibWaitPIDData::GlibWaitPIDData( GPid pid )
246{
247 source = g_child_watch_source_new( pid );
248}
249
250 GlibWaitPIDData::GlibWaitPIDData(GlibWaitPIDData &&other) noexcept
251 : tag( other.tag )
252 , source( other.source )
253 , callback( std::move( other.callback ) )
254{
255 other.source = nullptr;
256}
257
258GlibWaitPIDData::~GlibWaitPIDData()
259{
260 if ( source ) {
261 g_source_destroy( source );
262 g_source_unref( source );
263 }
264}
265
266 GlibWaitPIDData &GlibWaitPIDData::operator=(GlibWaitPIDData &&other) noexcept
267{
268 tag = other.tag;
269 source = other.source;
270 callback = std::move( other.callback );
271 other.source = nullptr;
272 return *this;
273}
274
275EventDispatcherPrivate::EventDispatcherPrivate (GMainContext *ctx , EventDispatcher &p) : BasePrivate(p)
276{
277 _myThreadId = std::this_thread::get_id();
278
279 //if we get a context specified ( usually when created for main thread ) we use it
280 //otherwise we create our own
281 if ( ctx ) {
282 _ctx = ctx;
283 g_main_context_ref ( _ctx );
284 } else {
285 _ctx = g_main_context_new();
286 }
287 // Enable this again once we switch to a full async API that requires a eventloop before calling any zypp functions
288 // g_main_context_push_thread_default( _ctx );
289}
290
291EventDispatcherPrivate::~EventDispatcherPrivate()
292{
293 std::for_each ( _runningTimers.begin(), _runningTimers.end(), []( GLibTimerSource *src ){
294 GLibTimerSource::destruct( src );
295 });
296 std::for_each ( _eventSources.begin(), _eventSources.end(), []( GAbstractEventSource *src ){
297 GAbstractEventSource::destruct( src );
298 });
299 _runningTimers.clear();
300 _eventSources.clear();
301
302 if ( _idleSource ) {
303 g_source_destroy( _idleSource );
304 g_source_unref ( _idleSource );
305 }
306
307 //g_main_context_pop_thread_default( _ctx );
308 g_main_context_unref( _ctx );
309}
310
311 bool EventDispatcherPrivate::runIdleTasks()
312{
313 //run all user defined idle functions
314 //if they return true, they are executed again in the next idle run
315 decltype ( _idleFuncs ) runQueue;
316 runQueue.swap( _idleFuncs );
317
318 while ( runQueue.size() ) {
319 EventDispatcher::IdleFunction fun( std::move( runQueue.front() ) );
320 runQueue.pop();
321 if ( fun() )
322 _idleFuncs.push( std::move(fun) );
323 }
324
325 //keep this as the last thing to call after all user code was executed
326 if ( _unrefLater.size() )
327 _unrefLater.clear();
328
329 return _idleFuncs.size() || _unrefLater.size();
330}
331
332 void EventDispatcherPrivate::enableIdleSource()
333{
334 if ( !_idleSource ) {
335 _idleSource = g_idle_source_new ();
336 g_source_set_callback ( _idleSource, eventLoopIdleFunc, this, nullptr );
337 g_source_attach ( _idleSource, _ctx );
338 }
339}
340
341std::shared_ptr<EventDispatcher> EventDispatcherPrivate::create( GMainContext *ctx )
342{
343 return std::shared_ptr<EventDispatcher>( new EventDispatcher( ctx ) );
344}
345
346 void EventDispatcherPrivate::waitPidCallback( GPid pid, gint status, gpointer user_data )
347{
348 EventDispatcherPrivate *that = reinterpret_cast<EventDispatcherPrivate *>( user_data );
349
350 try {
351 auto data = std::move( that->_waitPIDs.at(pid) );
352 that->_waitPIDs.erase( pid );
353
354 if ( data.callback )
355 data.callback( pid, status );
356
357 g_spawn_close_pid( pid );
358
359 // no need to take care of releasing the GSource, the event loop took care of that
360
361 } catch ( const std::out_of_range &e ) {
362 return;
363 }
364}
365
366 bool EventDispatcherPrivate::timeoutCallback( gpointer user_data )
367{
368 if ( !user_data )
369 return false;
370
371 GlibTimeoutData *data = reinterpret_cast<GlibTimeoutData *>(user_data);
372 return data->_callback();
373}
374
375 void EventDispatcherPrivate::timeoutDestroyCallback(gpointer user_data)
376{
377 if ( !user_data )
378 return;
379
380 GlibTimeoutData *data = reinterpret_cast<GlibTimeoutData *>(user_data);
381 delete data;
382}
383
384 ZYPP_IMPL_PRIVATE(EventDispatcher)
385
386EventDispatcher::EventDispatcher(void *ctx)
387 : Base ( * new EventDispatcherPrivate( reinterpret_cast<GMainContext*>(ctx), *this ) )
388{
389}
390
391EventDispatcher::~EventDispatcher()
392{
393}
394
395 void EventDispatcher::updateEventSource( AbstractEventSource &notifier, int fd, int mode )
396{
397 Z_D();
398 if ( notifier.eventDispatcher().lock().get() != this )
399 ZYPP_THROW( zypp::Exception("Invalid event dispatcher used to update event source") );
400
401 AbstractEventSource *notifyPtr = &notifier;
402
403 GAbstractEventSource *evSrc = nullptr;
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() ) {
407
408 evSrc = GAbstractEventSource::create( d );
409 evSrc->eventSource = notifyPtr;
410 evSrcList.push_back( evSrc );
411
412 g_source_attach( &evSrc->source, d->_ctx );
413
414 } else
415 evSrc = (*itToEvSrc);
416
417 int cond = evModeToMask( mode );
418 auto it = std::find_if( evSrc->pollfds.begin(), evSrc->pollfds.end(), [fd]( const auto &currPollFd ) {
419 return currPollFd.pollfd == fd;
420 });
421
422 if ( it != evSrc->pollfds.end() ) {
423 //found
424 it->reqEvents = static_cast<GIOCondition>( cond );
425 g_source_modify_unix_fd( &evSrc->source, it->tag, static_cast<GIOCondition>(cond) );
426 } else {
427 evSrc->pollfds.push_back(
428 GUnixPollFD {
429 static_cast<GIOCondition>(cond),
430 fd,
431 g_source_add_unix_fd( &evSrc->source, fd, static_cast<GIOCondition>(cond) )
432 }
433 );
434 }
435}
436
437 void EventDispatcher::removeEventSource( zyppng::AbstractEventSource &notifier, int fd )
438{
439 Z_D();
440
441 AbstractEventSource *ptr = &notifier;
442
443 if ( notifier.eventDispatcher().lock().get() != this )
444 ZYPP_THROW( zypp::Exception("Invalid event dispatcher used to remove event source") );
445
446 auto &evList = d->_eventSources;
447 auto it = std::find_if( evList.begin(), evList.end(), [ ptr ]( const auto elem ){ return elem->eventSource == ptr; } );
448
449 if ( it == evList.end() )
450 return;
451
452 auto &fdList = (*it)->pollfds;
453
454 if ( fd == -1 ) {
455 //we clear out all unix_fd watches but do not destroy the source just yet. We currently might
456 //be in the dispatch() function of that AbstractEventSource, make sure not to break the iterator
457 //for the fd's
458 for ( auto &pFD : fdList ) {
459 if ( pFD.tag )
460 g_source_remove_unix_fd( &(*it)->source, pFD.tag );
461 pFD.pollfd = -1;
462 pFD.tag = nullptr; //mark as orphaned, do not delete the element here this might break dipatching
463 }
464 } else {
465 auto fdIt = std::find_if( fdList.begin(), fdList.end(), [ fd ]( const auto &pFd ){ return pFd.pollfd == fd; } );
466 if ( fdIt != fdList.end() ) {
467 if ( fdIt->tag )
468 g_source_remove_unix_fd( &(*it)->source, (*fdIt).tag );
469 //also do not remove here, mark as orphaned only to not break iterating in dispatch()
470 fdIt->tag = nullptr;
471 fdIt->pollfd = -1;
472 }
473 }
474}
475
476 void EventDispatcher::registerTimer( Timer &timer )
477{
478 Z_D();
479 //make sure timer is not double registered
480 for ( const GLibTimerSource *t : d->_runningTimers ) {
481 if ( t->_t == &timer )
482 return;
483 }
484
485 GLibTimerSource *newSrc = GLibTimerSource::create();
486 newSrc->_t = &timer;
487 d->_runningTimers.push_back( newSrc );
488
489 g_source_attach( &newSrc->source, d->_ctx );
490}
491
492 void EventDispatcher::removeTimer( Timer &timer )
493{
494 Z_D();
495 auto it = std::find_if( d->_runningTimers.begin(), d->_runningTimers.end(), [ &timer ]( const GLibTimerSource *src ){
496 return src->_t == &timer;
497 });
498
499 if ( it != d->_runningTimers.end() ) {
500 GLibTimerSource *src = *it;
501 d->_runningTimers.erase( it );
502 GLibTimerSource::destruct( src );
503 }
504}
505
506 void *EventDispatcher::nativeDispatcherHandle() const
507{
508 return d_func()->_ctx;
509}
510
511 bool EventDispatcher::waitForFdEvent( const int fd, int events , int &revents , int &timeout )
512{
513 GPollFD pollFd;
514 pollFd.fd = fd;
515 pollFd.events = evModeToMask(events);
516
517 bool eventTriggered = false;
518 zypp::AutoDispose<GTimer *> timer( g_timer_new(), &g_timer_destroy );
519 while ( !eventTriggered ) {
520 g_timer_start( *timer );
521 const int res = eintrSafeCall( g_poll, &pollFd, 1, timeout );
522 switch ( res ) {
523 case 0: //timeout
524 timeout = 0;
525 return false;
526 case -1: { // interrupt
527 // if timeout is -1 we wait until eternity
528 if ( timeout == -1 )
529 continue;
530
531 timeout -= g_timer_elapsed( *timer, nullptr );
532 if ( timeout < 0 ) timeout = 0;
533 if ( timeout <= 0 )
534 return false;
535
536 ERR << "g_poll error: " << strerror(errno) << std::endl;
537 return false;
538 }
539 case 1:
540 eventTriggered = true;
541 break;
542 }
543 }
544
545 revents = gioConditionToEventTypes( (GIOCondition)pollFd.revents, evModeToMask(events) );
546 return true;
547}
548
549 void EventDispatcher::trackChildProcess( int pid, std::function<void (int, int)> callback )
550{
551 Z_D();
552 GlibWaitPIDData data ( pid );
553 data.callback = std::move(callback);
554
555 g_source_set_callback ( data.source, reinterpret_cast<GSourceFunc>(&EventDispatcherPrivate::waitPidCallback), d_ptr.get(), nullptr );
556 data.tag = g_source_attach ( data.source, d->_ctx );
557 d->_waitPIDs.insert( std::make_pair( pid, std::move(data) ) );
558}
559
560 bool EventDispatcher::untrackChildProcess(int pid)
561{
562 Z_D();
563 try {
564 d->_waitPIDs.erase( pid );
565 } catch ( const std::out_of_range &e ) {
566 return false;
567 }
568 return true;
569}
570
571UnixSignalSourceRef EventDispatcher::unixSignalSource()
572{
573 Z_D();
574 // lazy init
575 UnixSignalSourceRef r;
576 if ( d->_signalSource.expired ()) {
577 d->_signalSource = r = UnixSignalSource::create();
578 } else {
579 r = d->_signalSource.lock ();
580 }
581 return r;
582}
583
584 GMainContext * EventDispatcher::glibContext()
585{
586 return d_func()->_ctx;
587}
588
589 bool EventDispatcher::run_once()
590{
591 return g_main_context_iteration( d_func()->_ctx, false );
592}
593
594 void EventDispatcher::invokeOnIdleImpl(EventDispatcher::IdleFunction &&callback)
595{
596 auto d = instance()->d_func();
597 d->_idleFuncs.push( std::move(callback) );
598 d->enableIdleSource();
599}
600
601 void EventDispatcher::invokeAfterImpl( TimeoutFunction &&callback, uint32_t timeout )
602{
603 GlibTimeoutData *userData = new GlibTimeoutData();
604 userData->_callback = std::move(callback);
605
606 GSource *source = g_timeout_source_new ( timeout );
607 g_source_set_callback (source, G_SOURCE_FUNC(&EventDispatcherPrivate::timeoutCallback), userData, &EventDispatcherPrivate::timeoutDestroyCallback );
608 g_source_attach (source, d_func()->_ctx );
609 g_source_unref (source);
610}
611
612 void EventDispatcher::unrefLaterImpl( std::shared_ptr<void> &&ptr )
613{
614 Z_D();
615 d->_unrefLater.push_back( std::move(ptr) );
616 d->enableIdleSource();
617}
618
619 void EventDispatcher::clearUnrefLaterList ()
620{
621 d_func()->_unrefLater.clear();
622}
623
624ulong EventDispatcher::runningTimers() const
625{
626 return d_func()->_runningTimers.size();
627}
628
629std::shared_ptr<EventDispatcher> EventDispatcher::instance()
630{
631 return ThreadData::current().dispatcher();
632}
633
634 void EventDispatcher::setThreadDispatcher(const std::shared_ptr<EventDispatcher> &disp)
635{
636 ThreadData::current().setDispatcher( disp );
637}
638
639}
AutoDispose.h
Exception.h
ZYPP_THROW
#define ZYPP_THROW(EXCPT)
Drops a logline and throws the Exception.
Definition Exception.h:459
Logger.h
ERR
#define ERR
Definition Logger.h:105
GPollFD
struct _GPollFD GPollFD
Definition ZYppImpl.h:26
zypp::AutoDispose
Reference counted access to a Tp object calling a custom Dispose function when the last AutoDispose h...
Definition AutoDispose.h:95
zypp::Exception
Base class for Exception.
Definition Exception.h:153
zyppng::AbstractEventSource
Definition abstracteventsource.h:38
zyppng::AbstractEventSource::Error
@ Error
Definition abstracteventsource.h:50
zyppng::AbstractEventSource::Read
@ Read
Definition abstracteventsource.h:47
zyppng::AbstractEventSource::Exception
@ Exception
Definition abstracteventsource.h:49
zyppng::AbstractEventSource::Write
@ Write
Definition abstracteventsource.h:48
zyppng::AbstractEventSource::eventDispatcher
std::weak_ptr< EventDispatcher > eventDispatcher() const
Definition abstracteventsource.cc:37
zyppng::AbstractEventSource::onFdReady
virtual void onFdReady(int fd, int events)=0
zyppng::BasePrivate::BasePrivate
BasePrivate(Base &b)
Definition base_p.h:17
zyppng::Base::shared_this
std::shared_ptr< T > shared_this() const
Definition base.h:114
zyppng::Base::data
void * data(uint32_t quark)
Definition base.cc:82
zyppng::Base::Base
Base()
Definition base.cc:20
zyppng::Base::d_ptr
std::unique_ptr< BasePrivate > d_ptr
Definition base.h:182
zyppng::EventDispatcherPrivate
Definition eventdispatcher_glib_p.h:80
zyppng::EventDispatcherPrivate::~EventDispatcherPrivate
~EventDispatcherPrivate() override
Definition eventdispatcher_glib.cc:291
zyppng::EventDispatcherPrivate::_idleFuncs
std::queue< EventDispatcher::IdleFunction > _idleFuncs
Definition eventdispatcher_glib_p.h:103
zyppng::EventDispatcherPrivate::_unrefLater
std::vector< std::shared_ptr< void > > _unrefLater
Definition eventdispatcher_glib_p.h:102
zyppng::EventDispatcherPrivate::timeoutCallback
static bool timeoutCallback(gpointer user_data)
Definition eventdispatcher_glib.cc:366
zyppng::EventDispatcherPrivate::waitPidCallback
static void waitPidCallback(GPid pid, gint status, gpointer user_data)
Definition eventdispatcher_glib.cc:346
zyppng::EventDispatcherPrivate::_myThreadId
std::thread::id _myThreadId
Definition eventdispatcher_glib_p.h:95
zyppng::EventDispatcherPrivate::_ctx
GMainContext * _ctx
Definition eventdispatcher_glib_p.h:96
zyppng::EventDispatcherPrivate::_waitPIDs
std::unordered_map< int, GlibWaitPIDData > _waitPIDs
Definition eventdispatcher_glib_p.h:104
zyppng::EventDispatcherPrivate::runIdleTasks
bool runIdleTasks()
Definition eventdispatcher_glib.cc:311
zyppng::EventDispatcherPrivate::_idleSource
GSource * _idleSource
Definition eventdispatcher_glib_p.h:98
zyppng::EventDispatcherPrivate::_eventSources
std::vector< GAbstractEventSource * > _eventSources
Definition eventdispatcher_glib_p.h:101
zyppng::EventDispatcherPrivate::create
static std::shared_ptr< EventDispatcher > create(GMainContext *ctx=0)
Definition eventdispatcher_glib.cc:341
zyppng::EventDispatcherPrivate::_runningTimers
std::vector< GLibTimerSource * > _runningTimers
Definition eventdispatcher_glib_p.h:100
zyppng::EventDispatcherPrivate::timeoutDestroyCallback
static void timeoutDestroyCallback(gpointer user_data)
Definition eventdispatcher_glib.cc:375
zyppng::EventDispatcherPrivate::EventDispatcherPrivate
EventDispatcherPrivate(GMainContext *ctx, EventDispatcher &p)
Definition eventdispatcher_glib.cc:275
zyppng::EventDispatcherPrivate::enableIdleSource
void enableIdleSource()
Definition eventdispatcher_glib.cc:332
zyppng::EventDispatcher
Definition eventdispatcher.h:43
zyppng::EventDispatcher::~EventDispatcher
~EventDispatcher() override
Definition eventdispatcher_glib.cc:391
zyppng::EventDispatcher::AbstractEventSource
friend class AbstractEventSource
Definition eventdispatcher.h:45
zyppng::EventDispatcher::run_once
virtual bool run_once()
Definition eventdispatcher_glib.cc:589
zyppng::EventDispatcher::unixSignalSource
UnixSignalSourceRef unixSignalSource()
Definition eventdispatcher_glib.cc:571
zyppng::EventDispatcher::registerTimer
virtual void registerTimer(Timer &timer)
Definition eventdispatcher_glib.cc:476
zyppng::EventDispatcher::clearUnrefLaterList
void clearUnrefLaterList()
Definition eventdispatcher_glib.cc:619
zyppng::EventDispatcher::runningTimers
ulong runningTimers() const
Definition eventdispatcher_glib.cc:624
zyppng::EventDispatcher::Timer
friend class Timer
Definition eventdispatcher.h:46
zyppng::EventDispatcher::unrefLaterImpl
void unrefLaterImpl(std::shared_ptr< void > &&ptr)
Definition eventdispatcher_glib.cc:612
zyppng::EventDispatcher::TimeoutFunction
std::function< bool()> TimeoutFunction
Definition eventdispatcher.h:53
zyppng::EventDispatcher::nativeDispatcherHandle
void * nativeDispatcherHandle() const
Returns the native dispatcher handle if the used implementation supports it.
Definition eventdispatcher_glib.cc:506
zyppng::EventDispatcher::glibContext
GMainContext * glibContext()
Definition eventdispatcher_glib.cc:584
zyppng::EventDispatcher::IdleFunction
std::function< bool()> IdleFunction
Definition eventdispatcher.h:52
zyppng::EventDispatcher::EventDispatcher
EventDispatcher(void *ctx=nullptr)
Definition eventdispatcher_glib.cc:386
zyppng::EventDispatcher::waitForFdEvent
static bool waitForFdEvent(const int fd, int events, int &revents, int &timeout)
Definition eventdispatcher_glib.cc:511
zyppng::EventDispatcher::removeTimer
virtual void removeTimer(Timer &timer)
Definition eventdispatcher_glib.cc:492
zyppng::EventDispatcher::trackChildProcess
void trackChildProcess(int pid, std::function< void(int, int)> callback)
Definition eventdispatcher_glib.cc:549
zyppng::EventDispatcher::untrackChildProcess
bool untrackChildProcess(int pid)
Definition eventdispatcher_glib.cc:560
zyppng::EventDispatcher::updateEventSource
virtual void updateEventSource(AbstractEventSource &notifier, int fd, int mode)
Definition eventdispatcher_glib.cc:395
zyppng::EventDispatcher::removeEventSource
virtual void removeEventSource(AbstractEventSource &notifier, int fd=-1)
Definition eventdispatcher_glib.cc:437
zyppng::EventDispatcher::setThreadDispatcher
static void setThreadDispatcher(const std::shared_ptr< EventDispatcher > &disp)
Definition eventdispatcher_glib.cc:634
zyppng::EventDispatcher::instance
static std::shared_ptr< EventDispatcher > instance()
Definition eventdispatcher_glib.cc:629
zyppng::EventDispatcher::invokeOnIdleImpl
void invokeOnIdleImpl(IdleFunction &&callback)
Definition eventdispatcher_glib.cc:594
zyppng::EventDispatcher::invokeAfterImpl
void invokeAfterImpl(TimeoutFunction &&callback, uint32_t timeout)
Definition eventdispatcher_glib.cc:601
zyppng::Timer
The Timer class provides repetitive and single-shot timers.
Definition timer.h:45
zyppng::UnixSignalSource::create
static UnixSignalSourceRef create()
Definition unixsignalsource.cpp:41
GMainContext
struct _GMainContext GMainContext
Definition eventdispatcher.h:24
eventdispatcher_glib_p.h
linuxhelpers_p.h
zypp::callback
Callbacks light.
Definition Callback.h:146
zyppng
Definition MediaNetworkRequestExecutor.h:16
zyppng::eventLoopIdleFunc
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.
Definition eventdispatcher_glib.cc:231
zyppng::glibTimerSourceFuncs
static GSourceFuncs glibTimerSourceFuncs
Definition eventdispatcher_glib.cc:163
zyppng::gioConditionToEventTypes
static int gioConditionToEventTypes(const GIOCondition rEvents, const int requestedEvs)
Definition eventdispatcher_glib.cc:39
zyppng::strerror
std::string strerror(int errno_r) ZYPP_API
Return string describing the error_r code.
Definition String.cc:56
zyppng::eintrSafeCall
auto eintrSafeCall(Fun &&function, Args &&... args)
Definition linuxhelpers_p.h:50
zyppng::evModeToMask
static int evModeToMask(int mode)
Definition eventdispatcher_glib.cc:25
zyppng::writeMask
static int writeMask()
Definition eventdispatcher_glib.cc:17
zyppng::abstractEventSourceFuncs
static GSourceFuncs abstractEventSourceFuncs
Definition eventdispatcher_glib.cc:54
zyppng::readMask
static int readMask()
Definition eventdispatcher_glib.cc:13
zyppng::excpMask
static int excpMask()
Definition eventdispatcher_glib.cc:21
zyppng::GAbstractEventSource
Definition eventdispatcher_glib_p.h:29
zyppng::GAbstractEventSource::check
static gboolean check(GSource *source)
Definition eventdispatcher_glib.cc:96
zyppng::GAbstractEventSource::pollfds
std::vector< GUnixPollFD > pollfds
Definition eventdispatcher_glib_p.h:33
zyppng::GAbstractEventSource::source
GSource source
Definition eventdispatcher_glib_p.h:30
zyppng::GAbstractEventSource::eventSource
AbstractEventSource * eventSource
Definition eventdispatcher_glib_p.h:32
zyppng::GAbstractEventSource::dispatch
static gboolean dispatch(GSource *source, GSourceFunc, gpointer)
Definition eventdispatcher_glib.cc:126
zyppng::GAbstractEventSource::create
static GAbstractEventSource * create(EventDispatcherPrivate *ev)
Definition eventdispatcher_glib.cc:63
zyppng::GAbstractEventSource::destruct
static void destruct(GAbstractEventSource *src)
Definition eventdispatcher_glib.cc:73
zyppng::GAbstractEventSource::prepare
static gboolean prepare(GSource *, gint *timeout)
Definition eventdispatcher_glib.cc:86
zyppng::GAbstractEventSource::_ev
EventDispatcherPrivate * _ev
Definition eventdispatcher_glib_p.h:31
zyppng::GLibTimerSource
Definition eventdispatcher_glib_p.h:50
zyppng::GLibTimerSource::destruct
static void destruct(GLibTimerSource *src)
Definition eventdispatcher_glib.cc:222
zyppng::GLibTimerSource::source
GSource source
Definition eventdispatcher_glib_p.h:51
zyppng::GLibTimerSource::prepare
static gboolean prepare(GSource *src, gint *timeout)
Definition eventdispatcher_glib.cc:173
zyppng::GLibTimerSource::check
static gboolean check(GSource *source)
Definition eventdispatcher_glib.cc:194
zyppng::GLibTimerSource::create
static GLibTimerSource * create()
Definition eventdispatcher_glib.cc:214
zyppng::GLibTimerSource::dispatch
static gboolean dispatch(GSource *source, GSourceFunc, gpointer)
Definition eventdispatcher_glib.cc:200
zyppng::GLibTimerSource::_t
Timer * _t
Definition eventdispatcher_glib_p.h:52
zyppng::GUnixPollFD
Definition eventdispatcher_glib_p.h:16
zyppng::GUnixPollFD::pollfd
int pollfd
Definition eventdispatcher_glib_p.h:18
zyppng::GUnixPollFD::tag
gpointer tag
Definition eventdispatcher_glib_p.h:19
zyppng::GUnixPollFD::reqEvents
GIOCondition reqEvents
Definition eventdispatcher_glib_p.h:17
zyppng::GlibTimeoutData
Definition eventdispatcher_glib_p.h:75
zyppng::GlibTimeoutData::_callback
std::function< bool()> _callback
Definition eventdispatcher_glib_p.h:76
zyppng::GlibWaitPIDData
Definition eventdispatcher_glib_p.h:63
zyppng::GlibWaitPIDData::~GlibWaitPIDData
~GlibWaitPIDData()
Definition eventdispatcher_glib.cc:258
zyppng::GlibWaitPIDData::source
GSource * source
Definition eventdispatcher_glib_p.h:71
zyppng::GlibWaitPIDData::operator=
GlibWaitPIDData & operator=(GlibWaitPIDData &&other) noexcept
Definition eventdispatcher_glib.cc:266
zyppng::GlibWaitPIDData::callback
EventDispatcher::WaitPidCallback callback
Definition eventdispatcher_glib_p.h:72
zyppng::GlibWaitPIDData::GlibWaitPIDData
GlibWaitPIDData(GPid pid)
Definition eventdispatcher_glib.cc:245
zyppng::GlibWaitPIDData::tag
guint tag
Definition eventdispatcher_glib_p.h:70
zyppng::ThreadData::dispatcher
std::shared_ptr< EventDispatcher > dispatcher()
Definition threaddata.cc:59
zyppng::ThreadData::current
static ZYPP_API ThreadData & current()
Definition threaddata.cc:16
zyppng::ThreadData::setDispatcher
void setDispatcher(const std::shared_ptr< EventDispatcher > &disp)
Definition threaddata.cc:44
threaddata_p.h
timer.h
ZYPP_IMPL_PRIVATE
#define ZYPP_IMPL_PRIVATE(Class)
Definition zyppglobal.h:85
Z_D
#define Z_D()
Definition zyppglobal.h:98