Fixed thread handling in KDict. This resolsed bug 1748.

(cherry picked from commit 8942bd9538)
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/38/head
Michele Calgaro 9 years ago
parent 1da54d8c25
commit c016e4809d

@ -38,6 +38,7 @@
#include <signal.h>
#include <stdlib.h>
//********* JobData ******************************************
@ -53,8 +54,8 @@ JobData::JobData(QueryType Ntype,bool NnewServer,TQString const& Nserver,int Npo
//********* DictAsyncClient *************************************
DictAsyncClient::DictAsyncClient(int NfdPipeIn, int NfdPipeOut)
: job(0L), inputSize(10000), fdPipeIn(NfdPipeIn),
fdPipeOut(NfdPipeOut), tcpSocket(-1), idleHold(0)
: TQThread(), job(0L), inputSize(10000), fdPipeIn(NfdPipeIn),
fdPipeOut(NfdPipeOut), tcpSocket(-1), idleHold(0), m_request_termination(false)
{
input = new char[inputSize];
}
@ -68,22 +69,6 @@ DictAsyncClient::~DictAsyncClient()
}
void* DictAsyncClient::startThread(void* pseudoThis)
{
DictAsyncClient* newthis = (DictAsyncClient*) (pseudoThis);
if (0!=pthread_setcanceltype(PTHREAD_CANCEL_ENABLE,NULL))
tqWarning("pthread_setcanceltype failed!");
if (0!= pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL))
tqWarning("pthread_setcanceltype failed!");
signal(SIGPIPE,SIG_IGN); // ignore sigpipe
newthis->waitForWork();
return NULL;
}
void DictAsyncClient::insertJob(JobData *newJob)
{
if (!job) // don't overwrite existing job pointer
@ -97,27 +82,33 @@ void DictAsyncClient::removeJob()
}
void DictAsyncClient::waitForWork()
void DictAsyncClient::run()
{
fd_set fdsR,fdsE;
timeval tv;
int selectRet;
char buf;
timeval timeout_interval;
while (true) {
while (!m_request_termination) {
if (tcpSocket != -1) { // we are connected, hold the connection for xx secs
FD_ZERO(&fdsR);
FD_SET(fdPipeIn, &fdsR);
FD_SET(tcpSocket, &fdsR);
FD_ZERO(&fdsE);
FD_SET(tcpSocket, &fdsE);
tv.tv_sec = idleHold;
tv.tv_usec = 0;
selectRet = KSocks::self()->select(FD_SETSIZE, &fdsR, NULL, &fdsE, &tv);
int cnt = 0;
do {
FD_ZERO(&fdsR);
FD_SET(fdPipeIn, &fdsR);
++cnt;
timeout_interval.tv_sec=1;
timeout_interval.tv_usec=0;
selectRet=KSocks::self()->select(FD_SETSIZE, &fdsR, NULL, &fdsE, &timeout_interval);
} while (!m_request_termination && cnt<idleHold && selectRet==0);
if (selectRet == 0) {
doQuit(); // nothing happend...
} else {
if (((selectRet > 0)&&(!FD_ISSET(fdPipeIn,&fdsR)))||(selectRet == -1))
if ((selectRet>0 && !FD_ISSET(fdPipeIn,&fdsR)) || selectRet==-1)
closeSocket();
}
}
@ -125,8 +116,13 @@ void DictAsyncClient::waitForWork()
do {
FD_ZERO(&fdsR);
FD_SET(fdPipeIn, &fdsR);
} while (select(FD_SETSIZE, &fdsR, NULL, NULL, NULL)<0); // don't get tricked by signals
timeout_interval.tv_sec=1;
timeout_interval.tv_usec=0;
} while (!m_request_termination && select(FD_SETSIZE, &fdsR, NULL, NULL, &timeout_interval)<=0);
if (m_request_termination)
return;
clearPipe();
if (job) {
@ -785,7 +781,6 @@ void DictAsyncClient::openConnection()
}
KExtendedSocket ks;
ks.setAddress(job->server, job->port);
ks.setTimeout(job->timeout);
if (ks.connect() < 0) {
@ -1211,11 +1206,12 @@ DictInterface::DictInterface()
(void) KSocks::self();
client = new DictAsyncClient(fdPipeOut[0],fdPipeIn[1]);
if (0!=pthread_create(&threadID,0,&(client->startThread),client)) {
if (!client) {
KMessageBox::error(global->topLevel, i18n("Internal error:\nUnable to create thread."));
kapp->exit(1);
}
client->start();
jobList.setAutoDelete(true);
}
@ -1223,13 +1219,16 @@ DictInterface::DictInterface()
DictInterface::~DictInterface()
{
disconnect(notifier,TQT_SIGNAL(activated(int)),this,TQT_SLOT(clientDone()));
if (0!=pthread_cancel(threadID))
kdWarning() << "pthread_cancel failed!" << endl;
if (0!=pthread_join(threadID,NULL))
kdWarning() << "pthread_join failed!" << endl;
delete client;
if (client)
{
client->request_termination();
if (!client->wait(3000))
{
client->terminate();
client->wait(3000);
}
}
if ( ::close( fdPipeIn[0] ) == -1 ) {
perror( "Closing fdPipeIn[0]" );
}
@ -1242,6 +1241,8 @@ DictInterface::~DictInterface()
if ( ::close( fdPipeOut[1] ) == -1 ) {
perror( "Closing fdPipeOut[1]" );
}
delete client;
}

@ -1,9 +1,9 @@
/* -------------------------------------------------------------
dict.h (part of The KDE Dictionary Client)
dict.h (part of The TDE Dictionary Client)
Copyright (C) 2000-2001 Christian Gebauer <gebauer@kde.org>
(C) by Matthias Hölzer 1998
(C) by Matthias Hölzer 1998
This file is distributed under the Artistic License.
See LICENSE for details.
@ -19,7 +19,7 @@
#ifndef _DICT_H_
#define _DICT_H_
#include <pthread.h>
#include <ntqthread.h>
#include <tqptrlist.h>
#include <tqsocketnotifier.h>
@ -95,22 +95,21 @@ public:
//********* DictAsyncClient ******************************************
class DictAsyncClient
class DictAsyncClient : public TQThread
{
public:
DictAsyncClient(int NfdPipeIn, int NfdPipeOut);
~DictAsyncClient();
static void* startThread(void* pseudoThis);
void run(); // main loop
void request_termination() { m_request_termination = true; }
void insertJob(JobData *newJob);
void removeJob();
private:
void waitForWork(); // main loop
void define();
bool getDefinitions();
bool match();
@ -144,6 +143,7 @@ private:
int fdPipeIn,fdPipeOut; //IPC-Pipes to/from async thread
int tcpSocket,timeout,idleHold;
TQTextCodec *codec;
bool m_request_termination;
};
@ -194,7 +194,6 @@ private:
TQSocketNotifier *notifier;
int fdPipeIn[2],fdPipeOut[2]; //IPC-Pipes to/from async thread
pthread_t threadID;
DictAsyncClient *client;
TQPtrList<JobData> jobList;
bool newServer,clientDoneInProgress;

@ -114,6 +114,12 @@ TopLevel::TopLevel(TQWidget* parent, const char* name)
TopLevel::~TopLevel()
{
if (splitter)
delete splitter;
if (interface)
delete interface;
if (global)
delete global;
}
@ -636,6 +642,7 @@ void TopLevel::toggleMatchListShow()
matchView->reparent(this,0,matchView->pos(),true);
matchView->hide();
delete splitter;
splitter=NULL;
setCentralWidget(queryView);
}
else // list is not visible -> show it

Loading…
Cancel
Save