From c016e4809df23ff5a7c9e8aee4826b1e3ecd5b20 Mon Sep 17 00:00:00 2001 From: Michele Calgaro Date: Wed, 22 Jul 2015 13:17:28 +0900 Subject: Fixed thread handling in KDict. This resolsed bug 1748. (cherry picked from commit 8942bd95385f6019a7ebfbeef7e1840412606be6) Signed-off-by: Michele Calgaro --- kdict/dict.cpp | 75 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 37 deletions(-) (limited to 'kdict/dict.cpp') diff --git a/kdict/dict.cpp b/kdict/dict.cpp index 8094758d..6864cfe8 100644 --- a/kdict/dict.cpp +++ b/kdict/dict.cpp @@ -38,6 +38,7 @@ #include #include + //********* 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 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; } -- cgit v1.2.1