13
0

Test cross thread invalidation-record

This also tests 2 receivers connected to the same signal
This commit is contained in:
Robin Gareus 2021-11-21 04:11:22 +01:00
parent b2f0d31630
commit beddcf1a01
Signed by: rgareus
GPG Key ID: A090BCE02CF57F04

View File

@ -4,60 +4,100 @@
#include "pbd/pbd.h" #include "pbd/pbd.h"
#include "pbd/signals.h" #include "pbd/signals.h"
#include "pbd/event_loop.h"
class Tx { class Tx {
public: public:
PBD::Signal1<void, int> sig1; PBD::Signal1<void, int> sig1;
}; };
class Rx { /* ****************************************************************************/
class Rx1 {
public: public:
Rx (Tx& sender) { Rx1 (Tx& sender) {
sender.sig1.connect_same_thread (_connection, boost::bind (&Rx::cb, this, _1)); sender.sig1.connect_same_thread (_connection, boost::bind (&Rx1::cb, this, _1));
}
private:
void cb (int i) {
printf ("Rx1 %d\n", i);
}
PBD::ScopedConnection _connection;
};
/* ****************************************************************************/
struct MyInvalidationRecord : public PBD::EventLoop::InvalidationRecord
{
~MyInvalidationRecord () {
assert (use_count () == 0);
}
};
MyInvalidationRecord _ir;
class Rx2 : public PBD::ScopedConnectionList {
public:
Rx2 (Tx& sender) {
sender.sig1.connect (*this, &_ir, boost::bind (&Rx2::cb, this, _1), /* PBD::EventLoop */ 0);
} }
private: private:
void cb (int i) { void cb (int i) {
printf ("CB %d\n", i); printf ("CB %d\n", i);
} }
PBD::ScopedConnection _connection;
}; };
/* ****************************************************************************/
pthread_barrier_t barrier; pthread_barrier_t barrier;
static void* delete_t (void* arg) { static void* delete_tx (void* arg) {
Tx* t = static_cast<Tx*> (arg); Tx* tx = static_cast<Tx*> (arg);
pthread_barrier_wait (&barrier); pthread_barrier_wait (&barrier);
delete t; delete tx;
//printf ("Deleted tx\n"); //printf ("Deleted tx\n");
return 0; return 0;
} }
static void* delete_r (void* arg) { static void* delete_rx1 (void* arg) {
Rx* r = static_cast<Rx*> (arg); Rx1* rx1 = static_cast<Rx1*> (arg);
pthread_barrier_wait (&barrier); pthread_barrier_wait (&barrier);
delete r; delete rx1;
//printf ("Deleted rx\n"); //printf ("Deleted rx1\n");
return 0; return 0;
} }
static void* delete_rx2 (void* arg) {
Rx2* rx2 = static_cast<Rx2*> (arg);
pthread_barrier_wait (&barrier);
delete rx2;
//printf ("Deleted rx2\n");
return 0;
}
/* ****************************************************************************/
int int
main (int argc, char** argv) main (int argc, char** argv)
{ {
PBD::init (); PBD::init ();
Tx* t = new Tx (); Tx* tx = new Tx ();
Rx* r = new Rx (*t); Rx1* rx1 = new Rx1 (*tx);
Rx2* rx2 = new Rx2 (*tx);
//t->sig1 (11); /* EMIT SIGNAL */ pthread_barrier_init (&barrier, NULL, 3);
pthread_t t[3];
pthread_barrier_init (&barrier, NULL, 2); pthread_create (&t[0], NULL, delete_tx, (void*)tx);
pthread_t dt, dr; pthread_create (&t[1], NULL, delete_rx1, (void*)rx1);
pthread_create (&dt, NULL, delete_t, (void*)t); pthread_create (&t[2], NULL, delete_rx2, (void*)rx2);
pthread_create (&dr, NULL, delete_r, (void*)r);
pthread_join (dt, NULL); for (int i = 0; i < 3; ++i) {
pthread_join (dr, NULL); pthread_join (t[i], NULL);
}
pthread_barrier_destroy (&barrier); pthread_barrier_destroy (&barrier);
PBD::cleanup (); PBD::cleanup ();