@@ -27,7 +27,7 @@ const pw_core_events PwCore::EVENTS = {
2727 .info = nullptr ,
2828 .done = &PwCore::onSync,
2929 .ping = nullptr ,
30- .error = nullptr ,
30+ .error = &PwCore::onError ,
3131 .remove_id = nullptr ,
3232 .bound_id = nullptr ,
3333 .add_mem = nullptr ,
@@ -36,26 +36,46 @@ const pw_core_events PwCore::EVENTS = {
3636};
3737
3838PwCore::PwCore (QObject* parent): QObject(parent), notifier(QSocketNotifier::Read) {
39- qCInfo (logLoop) << " Creating pipewire event loop." ;
4039 pw_init (nullptr , nullptr );
40+ }
41+
42+ bool PwCore::start (bool retry) {
43+ if (this ->core != nullptr ) return true ;
44+
45+ qCInfo (logLoop) << " Creating pipewire event loop." ;
4146
4247 this ->loop = pw_loop_new (nullptr );
4348 if (this ->loop == nullptr ) {
44- qCCritical (logLoop) << " Failed to create pipewire event loop." ;
45- return ;
49+ if (retry) {
50+ qCInfo (logLoop) << " Failed to create pipewire event loop." ;
51+ } else {
52+ qCCritical (logLoop) << " Failed to create pipewire event loop." ;
53+ }
54+ this ->shutdown ();
55+ return false ;
4656 }
4757
4858 this ->context = pw_context_new (this ->loop , nullptr , 0 );
4959 if (this ->context == nullptr ) {
50- qCCritical (logLoop) << " Failed to create pipewire context." ;
51- return ;
60+ if (retry) {
61+ qCInfo (logLoop) << " Failed to create pipewire context." ;
62+ } else {
63+ qCCritical (logLoop) << " Failed to create pipewire context." ;
64+ }
65+ this ->shutdown ();
66+ return false ;
5267 }
5368
5469 qCInfo (logLoop) << " Connecting to pipewire server." ;
5570 this ->core = pw_context_connect (this ->context , nullptr , 0 );
5671 if (this ->core == nullptr ) {
57- qCCritical (logLoop) << " Failed to connect pipewire context. Errno:" << errno;
58- return ;
72+ if (retry) {
73+ qCInfo (logLoop) << " Failed to connect pipewire context. Errno:" << errno;
74+ } else {
75+ qCCritical (logLoop) << " Failed to connect pipewire context. Errno:" << errno;
76+ }
77+ this ->shutdown ();
78+ return false ;
5979 }
6080
6181 pw_core_add_listener (this ->core , &this ->listener .hook , &PwCore::EVENTS, this );
@@ -66,22 +86,34 @@ PwCore::PwCore(QObject* parent): QObject(parent), notifier(QSocketNotifier::Read
6686 this ->notifier .setSocket (fd);
6787 QObject::connect (&this ->notifier , &QSocketNotifier::activated, this , &PwCore::poll);
6888 this ->notifier .setEnabled (true );
69- }
7089
71- PwCore::~PwCore () {
72- qCInfo (logLoop) << " Destroying PwCore. " ;
90+ return true ;
91+ }
7392
74- if (this ->loop != nullptr ) {
75- if (this ->context != nullptr ) {
76- if (this ->core != nullptr ) {
77- pw_core_disconnect (this ->core );
78- }
93+ void PwCore::shutdown () {
94+ if (this ->core != nullptr ) {
95+ this ->listener .remove ();
96+ pw_core_disconnect (this ->core );
97+ this ->core = nullptr ;
98+ }
7999
80- pw_context_destroy (this ->context );
81- }
100+ if (this ->context != nullptr ) {
101+ pw_context_destroy (this ->context );
102+ this ->context = nullptr ;
103+ }
82104
105+ if (this ->loop != nullptr ) {
83106 pw_loop_destroy (this ->loop );
107+ this ->loop = nullptr ;
84108 }
109+
110+ this ->notifier .setEnabled (false );
111+ QObject::disconnect (&this ->notifier , nullptr , this , nullptr );
112+ }
113+
114+ PwCore::~PwCore () {
115+ qCInfo (logLoop) << " Destroying PwCore." ;
116+ this ->shutdown ();
85117}
86118
87119bool PwCore::isValid () const {
@@ -90,6 +122,7 @@ bool PwCore::isValid() const {
90122}
91123
92124void PwCore::poll () {
125+ if (this ->loop == nullptr ) return ;
93126 qCDebug (logLoop) << " Pipewire event loop received new events, iterating." ;
94127 // Spin pw event loop.
95128 pw_loop_iterate (this ->loop , 0 );
@@ -107,6 +140,18 @@ void PwCore::onSync(void* data, quint32 id, qint32 seq) {
107140 emit self->synced (id, seq);
108141}
109142
143+ void PwCore::onError (void * data, quint32 id, qint32 /* seq*/ , qint32 res, const char * message) {
144+ auto * self = static_cast <PwCore*>(data);
145+
146+ if (message != nullptr ) {
147+ qCWarning (logLoop) << " Fatal pipewire error on object" << id << " with code" << res << message;
148+ } else {
149+ qCWarning (logLoop) << " Fatal pipewire error on object" << id << " with code" << res;
150+ }
151+
152+ emit self->fatalError ();
153+ }
154+
110155SpaHook::SpaHook () { // NOLINT
111156 spa_zero (this ->hook );
112157}
0 commit comments