PDA

View Full Version : God! QSocketNotifier emit the activated signal endlessly



wesley
11th March 2009, 15:14
please anyone here help me to solve this problem.

I am working on linux 2.4.19 (arm based) + qt-embedded-free-3.3.8b.
and now I am writing a custom keyboard handler which subclass from QWSKeyBoardHandler.



class MyKbdHandler: public QObject, public QWSKeyBoardHandler {
Q_OBJECT
public:
MyKbdHandler();
~MyKbdHandler();

private slots:
void readKbdData();

private:
QSocketNotifier *m_kbdNotifier;
int m_kbdFd;
}




MyKbdHandler::MyKbdHandler()
: QObject(), QWSKeyBoardHandler()
{
m_kbdNotifier = NULL;
m_kbdFd = ::open("/dev/input", O_RDONLY|O_NONBLOCK);
if (m_kbdFd < 0) {
qDebug("Can not open input device!\n");
return;
}

m_kbdNotifier = new QSocketNotifier(m_kbdFd, QSocketNotifier::Read, this);
connect(m_kbdNotifier, SIGNAL(activated(int)), this, SLOT(readKbdData()));
}

MyKbdHandler::~MyKbdHandler()
{
if (m_kbdFd >= 0) {
::close(m_kbdFd);
m_kbdFd = -1;
}

if (m_kbdNotifier != NULL) {
delete m_kbdNotifier;
m_kbdNotifier = NULL;
}
}

MyKbdHandler::readKbdData()
{

char buf[1024] = { 0 };
int n = ::read(m_kbdFd, buf, sizeof(buf));
qDebug("MyKbdHandler::readKbdData = %d\n", n);

// do key code mapping and call processKeyEvent here ...

}


after reading all of the available data(the read call already return 0), the activated() signal emit over and over again, and readKbdData() also get invoked. the cpu reached to 98%.!

any idea ?

wesley
12th March 2009, 01:17
any idea???

shui
14th April 2010, 19:44
I just had the same problem, when using QSocketNotifier to a Named Pipe / Fifo (Linux).

The activated() signal is not endlessly, but veeeery often until you read all data from the pipe.

Calling connect( .... , Qt::BlockingQueuedConnection ) worked fine for me. There is the code showing the full test case:


class ReceiverThread : public QThread
{
Q_OBJECT

public:
ReceiverThread()//(QObject * parent = 0):QThread(parent)
{
rxNotifier=0;
}
~ReceiverThread() {
close(rxfd);
}

private:
double sampleTime;
int rxfd, k;
QSocketNotifier *rxNotifier;

protected:
virtual void run() {
rxfd = open("/tmp/testfifo", O_RDONLY);
if (rxfd==-1) {qDebug()<<"\nError opening fifo"; }
fcntl(rxfd, F_SETFL, fcntl(rxfd, F_GETFL) | O_NONBLOCK);
startRxNotifier();
exec();
}

void startRxNotifier() {
if(rxfd >= 0) {
if(rxNotifier == 0) {
rxNotifier = new QSocketNotifier(rxfd, QSocketNotifier::Read);//, this);
connect( rxNotifier, SIGNAL(activated(int)), SLOT(rxEvent(int)), Qt::BlockingQueuedConnection );

} else {
// Debug("QSocketNotifier re-enabled!")
rxNotifier->setEnabled(true);
}
}
}

public slots:
void rxEvent(int socket) {
int readret;
int buf[1024];
qDebug()<<"rxEvent()";
readret = read(socket/*rxfd*/, buf, 2*sizeof(double));
qDebug()<<"Received:"<<buf[0]<<", "<<buf[1]<<" read() returns "<<readret;
}
};


Anyway, this behaviour is not described in the current documentation...

Cheers,
Joerg

wysota
14th April 2010, 20:18
I had a similar issue. What I remember working (at least AFAIR) was to disable buffering for the file descriptor on the system level before feeding the descriptor to the socket notifier.

shui
14th April 2010, 23:42
Ok, I learned now, that the problem has to do with the thread usage in my case: I learned, that the SLOT(rxEvent()) is processed in the event loop of the core application whilst the SIGNAL(activated) is emitted in the thread. This is solved by changing the thread affinitiy of the slot by calling moveToThisThread() in the core application.

ReceiverThread *receiverThread = new ReceiverThread();
app.connect(receiverThread, SIGNAL(finished()), &app, SLOT(quit()));
receiverThread->moveToThread(receiverThread);
receiverThread->start();

So using Qt::BlockingQueuedConnection is a bad idea in this case.

The doc of moveToThisThread() provides a god explaination.

Cheers

beemaneni
4th October 2016, 13:30
I tto face same issue where slot is called continuously even when i run in different thread.How do i overcome this ? Can anybody suggest me a proper answer to close this ASAP


Regards
Bala B

wysota
5th October 2016, 09:48
Did you try code from the previous post?

beemaneni
12th October 2016, 08:48
yeah..but still i get the activated signal continuously in that thread as well