Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, June 2007
QCoreApplication::exit(returnCode) does not terminate the application


Message 1 in thread

Hi,
  I don't know what I'm doing wrong, but when I call  
QCoreApplication::exit(some returnCode) in void Server::closeServer(int  
returnCode) the application stays runnig.

main.cpp:
#include <QCoreApplication>
#include <QtCore>

#include "server.h"

int main(int argc, char *argv[])
{
	QCoreApplication app(argc, argv);

	Server server;	

	return app.exec();
}


server.h:
#ifndef SERVER_H
#define SERVER_H

#include <QObject>
#include <QTcpSocket>
#include <QFile>
#include <QStringList>

class QTcpServer;

struct server_dir {
	QString path;
	QStringList exclude_dirs;
	QStringList exclude_files;
	QString log_file;
};	

class Server : public QObject
{
     Q_OBJECT

public:
     Server();

private slots:
	void sendFile();
	void displayError(QAbstractSocket::SocketError socketError);		

private:
	QTcpServer *tcpServer;
	QTcpSocket *clientConnection;

	quint16 port;
	QFile log_file;

	QList<server_dir> dirs;

	void readSettings();
	void writeSettings();

	void closeServer(int returnCode = 0);

	QByteArray quint32_to_QByteArray(quint32 & value);
};
#endif


server.cpp:
#include <QtNetwork>

#include <iostream>

#include "server.h"

Server::Server() : QObject()
{
	readSettings();

	tcpServer = new QTcpServer(this);

	if (!tcpServer->listen(QHostAddress::Any, port)) {
		std::cerr << qPrintable(tr("Unable to start the server:  
%1.\n").arg(tcpServer->errorString())) << std::endl;

		closeServer(2);
		return;
	}

	log_file.write(tr("The server is running on port  
%1.\n").arg(tcpServer->serverPort()).toAscii());

	connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFile()));
}

void Server::sendFile()
{
	//QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
	clientConnection = tcpServer->nextPendingConnection();

	connect(clientConnection, SIGNAL(disconnected()),
					clientConnection, SLOT(deleteLater()));
	connect(clientConnection, SIGNAL(error(QAbstractSocket::SocketError)),
             this, SLOT(displayError(QAbstractSocket::SocketError)));

	log_file.write(tr("The client has connected from IP  
%1.\n").arg(clientConnection->localAddress().toString()).toAscii());


	//QFile file("C:\\Downloads\\test.txt");
	QFile file("C:\\Downloads\\Hiren's.BootCD.9.0.iso");	

	if (!file.open(QIODevice::ReadOnly)) {
		std::cerr << qPrintable(tr("Cannot open file for reading:  
%1").arg(file.errorString())) << std::endl;
		return;
	}

	QByteArray block, size;
	quint32 data_size;

	do {
		// read max 10MiB from file
		block = file.read(10485760);

		// prepend size of read data
		data_size = block.isEmpty()?0xFFFFFFFF:block.size();
		size      = quint32_to_QByteArray(data_size);
		block.prepend(size);

		clientConnection->write(block);

	} while ((block.size() - sizeof(quint32)) != 0);

	clientConnection->disconnectFromHost();

	file.close();
}

void Server::displayError(QAbstractSocket::SocketError socketError)
{
     switch (socketError) {
     case QAbstractSocket::RemoteHostClosedError:
				exit(0);
         break;
     case QAbstractSocket::HostNotFoundError:
         std::cerr << qPrintable(tr("The host was not found. Please check  
the host name and port settings.")) << std::endl;
         break;
     case QAbstractSocket::ConnectionRefusedError:
         std::cerr << qPrintable(tr("The connection was refused by the  
peer. "
                                     "Make sure the fortune server is  
running, "
                                     "and check that the host name and port  
"
                                     "settings are correct.")) << std::endl;
         break;
     default:
         std::cerr << qPrintable(tr("The following error occurred: %1.")
                                  .arg(clientConnection->error())) <<  
std::endl;
     }
}

void Server::readSettings()
{
	QSettings settings(QSettings::IniFormat, QSettings::SystemScope,  
"ziginet", "znsyn_server");

	port = settings.value("port", 9083).toInt();

	#ifdef Q_OS_WIN32
	QString log_path = settings.value("log",  
QCoreApplication::applicationDirPath().append("/znsyn_server.log")).toString();
	#endif

	#ifdef Q_OS_UNIX
	QString log_path = settings.value("log",  
"/var/log/znsyn_server.log").toString();
	#endif

	log_file.setFileName(log_path);

	if (!log_file.open(QIODevice::WriteOnly | QIODevice::Append |  
QIODevice::Text | QIODevice::Unbuffered)) {
		std::cerr << qPrintable(tr("Cannot open log file \"%1\":  
%2").arg(log_path, log_file.errorString())) << std::endl;

		//QTimer::singleShot(0, QCoreApplication::instance(), SLOT(quit()));
		closeServer(1);

		return;
	}
}

void Server::closeServer(int returnCode)
{
	std::cout << "rc " << returnCode << std::endl;
	log_file.close();

	//QCoreApplication::instance()->exit(returnCode);
	QCoreApplication::exit(returnCode);

	//QTimer::singleShot(0, QCoreApplication::instance(), SLOT(quit()));
}

QByteArray Server::quint32_to_QByteArray(quint32 & value)
{
	int size = sizeof(quint32);
	QByteArray ba(size, 0);
	uchar *p = (uchar *)(&value);

	if (QSysInfo::ByteOrder == QSysInfo::BigEndian) {
		for (int i = 0; i < size; i++) ba[i] = *p++;
	}
	else { // swap bytes
		for (int i = size - 1; i >= 0; i--) ba[i] = *p++;
	}

	return ba;
}

Thaks
-- 
 [ signature omitted ] 

Message 2 in thread

From the docs:
"Note that unlike the C library function of the same name, this function
does return to the caller -- it is event processing that stops."

Cheers,
Peter

-----Original Message-----
From: kAja Ziegler [mailto:ziegleka@xxxxxxxxx] 
Sent: Wednesday, June 13, 2007 3:03 PM
To: qt-interest@xxxxxxxxxxxxx
Subject: QCoreApplication::exit(returnCode) does not terminate the
application

Hi,
  I don't know what I'm doing wrong, but when I call  
QCoreApplication::exit(some returnCode) in void Server::closeServer(int

returnCode) the application stays runnig.


--
 [ signature omitted ] 

Message 3 in thread

How can I do it in the right way?

  Terminate console application with the exit error code.

On Wed, 13 Jun 2007 15:25:33 +0200, Peter Prade <prade@xxxxxxxxxxx> wrote:

> From the docs:
> "Note that unlike the C library function of the same name, this function
> does return to the caller -- it is event processing that stops."
>
> Cheers,
> Peter
>
> -----Original Message-----
> From: kAja Ziegler [mailto:ziegleka@xxxxxxxxx]
> Sent: Wednesday, June 13, 2007 3:03 PM
> To: qt-interest@xxxxxxxxxxxxx
> Subject: QCoreApplication::exit(returnCode) does not terminate the
> application
>
> Hi,
>   I don't know what I'm doing wrong, but when I call
> QCoreApplication::exit(some returnCode) in void Server::closeServer(int
>
> returnCode) the application stays runnig.
>
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with  
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/



-- 
 [ signature omitted ] 

Message 4 in thread

unless you need some cleanup code to be called, you can just use the C
exit() function.

Cheers,
Peter

> How can I do it in the right way?
> 
>   Terminate console application with the exit error code.
> 
> On Wed, 13 Jun 2007 15:25:33 +0200, Peter Prade <prade@xxxxxxxxxxx>
wrote:
> 
> > From the docs:
> > "Note that unlike the C library function of the same name, this
function
> > does return to the caller -- it is event processing that stops."

--
 [ signature omitted ] 

Message 5 in thread

I know this possibility, but I'm interested how it could be made in the  
right Qt way.

Thank you for your fast replie.

On Wed, 13 Jun 2007 16:04:02 +0200, Peter Prade <prade@xxxxxxxxxxx> wrote:

> unless you need some cleanup code to be called, you can just use the C
> exit() function.
>
> Cheers,
> Peter
>
>> How can I do it in the right way?
>>
>>   Terminate console application with the exit error code.
>>
>> On Wed, 13 Jun 2007 15:25:33 +0200, Peter Prade <prade@xxxxxxxxxxx>
> wrote:
>>
>> > From the docs:
>> > "Note that unlike the C library function of the same name, this
> function
>> > does return to the caller -- it is event processing that stops."
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with  
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/



-- 
 [ signature omitted ] 

Message 6 in thread

> I know this possibility, but I'm interested how it could be made in the
> right Qt way.
>

The advice given below is only partially correct.

It is true that QCoreApplication::exit(int) will return the the caller.

However it also will cause the event loop to collapse once control gets
passed back to the event loop. When the eventloop is done control will
return to the caller of exec().

You are also correct in thinking that QCoreApplication::exit(int) is the
correct "Qt Way" to return an error code.

Please see the attached example application.  There is an error in your
code where either the eventloop is not being processed or the code that
you think calls exit() never actually gets run.

--Justin


>
> On Wed, 13 Jun 2007 16:04:02 +0200, Peter Prade <prade@xxxxxxxxxxx> wrote:
>
>> unless you need some cleanup code to be called, you can just use the C
>> exit() function.
>>
>> Cheers,
>> Peter
>>
>>> How can I do it in the right way?
>>>
>>>   Terminate console application with the exit error code.
>>>
>>> On Wed, 13 Jun 2007 15:25:33 +0200, Peter Prade <prade@xxxxxxxxxxx>
>> wrote:
>>>
>>> > From the docs:
>>> > "Note that unlike the C library function of the same name, this
>> function
>>> > does return to the caller -- it is event processing that stops."
>>
>> --
>> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
>> "unsubscribe" in the subject or the body.
>> List archive and information: http://lists.trolltech.com/qt-interest/
>
>
>
> --
> Using Opera's revolutionary e-mail client: http://www.opera.com/mail/
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body.
> List archive and information: http://lists.trolltech.com/qt-interest/
>

Attachment:

Attachment: testExit.zip
Description: Zip compressed data


Message 7 in thread

Thank you a lot for your example. I separate it into one method, one slot  
and one variable:

// slot
void Server::exitServer()
{
	QCoreApplication::instance()->exit(returnCode);
}

// method
void Server::closeServer(int rCode)
{
	returnCode = rCode; // variable
	QTimer::singleShot(0, this, SLOT(exitServer()));
}


On Wed, 13 Jun 2007 17:34:46 +0200, <justin@xxxxxxx> wrote:

>> I know this possibility, but I'm interested how it could be made in the
>> right Qt way.
>>
>
> The advice given below is only partially correct.
>
> It is true that QCoreApplication::exit(int) will return the the caller.
>
> However it also will cause the event loop to collapse once control gets
> passed back to the event loop. When the eventloop is done control will
> return to the caller of exec().
>
> You are also correct in thinking that QCoreApplication::exit(int) is the
> correct "Qt Way" to return an error code.
>
> Please see the attached example application.  There is an error in your
> code where either the eventloop is not being processed or the code that
> you think calls exit() never actually gets run.
>
> --Justin

-- 
 [ signature omitted ] 

Message 8 in thread

kAja Ziegler schrieb:
> I know this possibility, but I'm interested how it could be made in the 
> right Qt way.

Calling the C library function exit() /is/ the right way(tm) - even with 
Qt (that is, if you really intend to exit your application from this 
given point in your code, returning an error code).

;)

Cheers, Oliver

--
 [ signature omitted ] 

Message 9 in thread

kAja Ziegler schrieb:
> How can I do it in the right way?
> 
>  Terminate console application with the exit error code.

Why not using the good old exit() function?

Martin

-- 
 [ signature omitted ]