PDA

View Full Version : qRegisterMetaType: getting garbage through signal/slot



zlacelle
10th June 2009, 16:50
I'm using the libipq library to do some packet management on a linux system. When I receive the packet, I successfully use the library to store important information and deconstruct it into its parts. However, now I want to add a separate NetworkStatistics thread, which logs network traffic information. I would like to send pointers to these packets through the signals/slots to the NetworkStatistics thread from my backend thread.

Originally, I was having the trouble "Cannot queue arguments of type const ipq_packet_msg_t&". I solved this problem by calling qRegisterMetaType<ipq_packet_msg_t>;("ipq_packet_msg_t"); right above my QObject::connect() statements. Now, however, when I send this const ipq_packet_msg_t& pointer through the signal/slot, I get garbage out the other side. Where my source address might be 127.0.0.1 inside of my backend thread, that same source address right after the signal call inside of NetworkStatistics will be some other random set of 4 integers.

How can I pass this type through signals/slots?

Some Code:


//REGISTERING WITH QREGISTERMETATYPE:
//Register the ipq_packet_msg_t type with QMetaType, so that
//it can be successfully passed through signals/slots
qRegisterMetaType<ipq_packet_msg_t>("ipq_packet_msg_t");

//Connect to NetworkStat
QObject::connect(back, SIGNAL(update_stats_sig(const ipq_packet_msg_t&)), netStat, SLOT(update_stats_slot(const ipq_packet_msg_t&)));

//CODE INSIDE BACKEND:
ipq_packet_msg_t *m = ipq_get_packet(buf);

emit update_stats_sig(*m);

IPAddress sourceIP = getSourceIP(*m);
QString qstr = toIpString(sourceIP);
std::string str = qstr.toStdString();
cout << "Correct IP: " << str << endl; //GIVES CORRECT IP

//CODE INSIDE NETWORKSTATISTICS:
//The Slot:
void NetworkStat::update_stats_slot(const ipq_packet_msg_t& m)
{
update(m);
}

//The Function:
iphdr* iph = (iphdr*) msg.payload;
unsigned int sourceAddress = ntohl(iph->saddr);

QString qstr = toIpString(sourceAddress);
std::string str = qstr.toStdString();
cout << "Source Address inside NetStat: " << str << endl; //GARBAGE SOURCE IP

wysota
16th June 2009, 10:05
Never emit pointers (or non-const references) across threads, they might become invalid before the receiving thread has a chance to process them. Make a copy and send the copy instead.