PDA

View Full Version : Not getting proper response in slot connected with QNetworkAccessManager second time



BB_Shi
5th August 2015, 13:34
Hi All,

I am working on BB10 native extension which is written in QT. I have started a thread to execute my network request.


void* SignalThread(void* parent) {
TemplateJS *pParent = static_cast<TemplateJS *>(parent);

int argc = 0;
char **argv = NULL;
QCoreApplication QCoreApplication(argc, argv);
webworks::TemplateNDK *m_signalHandler = new webworks::TemplateNDK(pParent);
m_signalHandler->doNetworkRequest(); //sending network request

QCoreApplication::exec();

delete m_signalHandler;
return NULL;
}


bool TemplateJS::StartThread(){

pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);

pthread_t m_thread;
pthread_create(&m_thread, &thread_attr, SignalThread, static_cast<void *>(this));
pthread_attr_destroy(&thread_attr);
if (!m_thread) {
return true;
} else {
return false;
}
}

Here is my simple code to start request.


void TemplateNDK::doNetworkRequest()
{
_networkAccessManager = new QNetworkAccessManager();

QObject::connect(_networkAccessManager, SIGNAL(finished(QNetworkReply*)), this,
SLOT(onRequestFinished(QNetworkReply*)));

QNetworkRequest request = QNetworkRequest();
QString inputUrl = QString::fromUtf8(url.c_str());
request.setUrl(QUrl(inputUrl));
QNetworkReply* response = _networkAccessManager->get(request);
}

When i call startThread() function first time slot returns proper response. But when I call same startThread() function second time it stuck and does not execute slot. QObject::connect is returning true both times.

If using QTimer to abort request after interval then second time onRequestFinished slot is getting executed and returns value of reply->error() as 5 that is "operation canceled".

Am i doing something wrong with QCoreApplication::exec().
Please help.

Thanks.

anda_skoa
5th August 2015, 14:42
Never seen exec() being called without object, you better call exec() on the QCoreApplication object that you created.

The code should be somewhat like this



QCoreApplication app(....);

// setup stuff

app.exec();


I wonder what you are doing here though.
This is obviously intended to be used by a non-Qt application. BB10's app framework "Cascades" is Qt4 based. Kind of a strange conflict.

Cheers,
_

BB_Shi
6th August 2015, 11:45
This code is being used for BB10 native extension which is not fully cascades app. Referring below URL for implementation:

https://github.com/haahmad/SignalSlotExample/blob/master/SignalSlot/src/SignalSlotJS.cpp

Tried what you suggested to call exec() function using object. But it seems to be not working. In this case, got response successfully for the first time but app stuck somewhere and does not return even after time out.

Also tried to connect signal slot with QNetworkReply object instead of QNetworkAccessManager object as suggested in some posts. But this is also not working even for the first time.

Thanks.

anda_skoa
6th August 2015, 13:23
Tried what you suggested to call exec() function using object. But it seems to be not working. In this case, got response successfully for the first time but app stuck somewhere and does not return even after time out.

Did you connect anything to the application's quit() slot or call it after you are done with the request?

Alternatively keep the thread running and send new request into it instead of creating and destroying it every time and having to make sure that only one such thread ever exists at the same time?

Cheers,
_

BB_Shi
6th August 2015, 14:06
I tried to call QCoreApplication::quit() and application terminated at that point.

I will try alternative method also.

Thanks.

d_stranz
6th August 2015, 20:30
QCoreApplication QCoreApplication(argc, argv);

I hope this is just a bad cut and paste job, because I have no idea what you intend this line of code to do.

BB_Shi
7th August 2015, 13:06
I am not finding any way to create thread only once and send request in already running thread because the function which is calling pthread_create needs to be called by below function. Calling of this function can't be handled. This function is called every time whenever a button is clicked from javascript application.


string TemplateJS::InvokeMethod(const string& command) {
// command appears with parameters following after a space
int index = command.find_first_of(" ");
std::string strCommand = command.substr(0, index);
std::string arg = command.substr(index + 1, command.length());
params = arg;
if (strCommand == "request") {
StartThread();

strCommand.append(";");
strCommand.append(command);
return strCommand;
}

return "Unknown C++ method";
}


if I call m_signalHandler->doNetworkRequest(); two times in SignalThread then it's working fine and returns good response. But if I call StartThread() two times in above function, app exits.

Added after 10 minutes:


I hope this is just a bad cut and paste job, because I have no idea what you intend this line of code to do.

I have changed it to
QCoreApplication app(argc, argv);

Also according to document since exec() is static function of QCoreApplication so it can be called like: QCoreApplication::exec();

Please correct me if something is wrong. As I am new to this.

anda_skoa
7th August 2015, 14:04
I am not finding any way to create thread only once and send request in already running thread because the function which is calling pthread_create needs to be called by below function.

You would of course only call the setup function once.

Once the thread and its event loop are running, you have a couple of options to send the requests:
- QCoreApplication::postEvent and a custom event sent to your worker object.
- Or letting the worker object block on a semaphore or wait condition and doing traditional cross-thread data handover.
- Might even work to do QMetaObject::invokeMethod on the worker object (using a Qt::QueuedConnection type)

Cheers,
_

BB_Shi
10th August 2015, 06:58
I am new to this. Can you please provide any sample code that can help.

Added after 1 38 minutes:

Is there any way to find out number of threads running in an application?

anda_skoa
10th August 2015, 15:54
I am new to this. Can you please provide any sample code that can help.

For the first option create a subclass of QEvent.
For the second option have a look at QWaitCondition or QSemphore.
For the third option have a look at QMetaObject::invokeMethod()



Is there any way to find out number of threads running in an application?
There might be operating system specific API for this.

Cheers,
_