void SocketConnector::run (void) { started(); while (!terminationRequested()) { TCPSocket * const pSocket = dynamic_cast<TCPSocket * const> (_pServerSocket->accept()); if (!pSocket) { if (!terminationRequested()) { checkAndLogMsg ("SocketConnector::run", Logger::L_MildError, "accept() on ServerSocket failed with error %d\n", _pServerSocket->error()); setTerminatingResultCode (-1); } break; } pSocket->bufferingMode (0); ConnectorAdapter * const pConnectorAdapter = ConnectorAdapter::ConnectorAdapterFactory (pSocket); Connection * const pConnection = new Connection (pConnectorAdapter, this); _mConnectionsTable.lock(); pConnection->lock(); Connection * const pOldConnection = _connectionsTable.put (generateUInt64Key (InetAddr (pSocket->getRemoteHostAddr(), pSocket->getRemotePort())), pConnection); _mConnectionsTable.unlock(); if (pOldConnection) { // There was already a connection from this node to the remote node - close that one checkAndLogMsg ("SocketConnector::run", Logger::L_Info, "replaced an old SocketConnection to <%s:%hu> in status %hu with a new one\n", pConnection->getRemoteProxyInetAddr()->getIPAsString(), pConnection->getRemoteProxyInetAddr()->getPort(), pOldConnection->getStatus()); delete pOldConnection; } else { checkAndLogMsg ("SocketConnector::run", Logger::L_Info, "accepted a new SocketConnection from <%s:%hu>\n", pConnection->getRemoteProxyInetAddr()->getIPAsString(), pConnection->getRemoteProxyInetAddr()->getPort()); } pConnection->startMessageHandler(); pConnection->unlock(); } checkAndLogMsg ("SocketConnector::run", Logger::L_Info, "SocketConnector terminated; termination code is %d\n", getTerminatingResultCode()); Connector::_pConnectionManager->deregisterConnector (_connectorType); terminating(); delete this; }
DatabaseThread::~DatabaseThread() { // The DatabaseThread will only be destructed when both its owner // DatabaseContext has deref'ed it, and the databaseThread() thread function // has deref'ed the DatabaseThread object. The DatabaseContext destructor // will take care of ensuring that a termination request has been issued. // The termination request will trigger an orderly shutdown of the thread // function databaseThread(). In shutdown, databaseThread() will deref the // DatabaseThread before returning. ASSERT(terminationRequested()); }
virtual void run() { static const QChar tilde = '~'; struct passwd *pw; while((pw = ::getpwent()) && !terminationRequested()) addMatch(tilde + QString::fromLocal8Bit(pw->pw_name)); ::endpwent(); addMatch(tilde); done(); }
DatabaseThread::~DatabaseThread() { // FIXME: Any cleanup required here? Since the thread deletes itself after running its detached course, I don't think so. Lets be sure. ASSERT(terminationRequested()); }
void DirectoryListThread::run() { // Thread safety notes: // // There very possibly may be thread safety issues here, but I've done a check // of all of the things that would seem to be problematic. Here are a few // things that I have checked to be safe here (some used indirectly): // // QDir::currentDirPath(), QDir::setCurrent(), QFile::decodeName(), QFile::encodeName() // QString::fromLocal8Bit(), QString::local8Bit(), QTextCodec::codecForLocale() // // Also see (for POSIX functions): // http://www.opengroup.org/onlinepubs/009695399/functions/xsh_chap02_09.html DIR *dir = 0; for(QStringList::ConstIterator it = m_dirList.begin(); it != m_dirList.end() && !terminationRequested(); ++it) { // Open the next directory if(!dir) { dir = ::opendir(QFile::encodeName(*it)); if(!dir) { kdDebug() << "Failed to open dir: " << *it << endl; done(); return; } } // A trick from KIO that helps performance by a little bit: // chdir to the directroy so we won't have to deal with full paths // with stat() QString path = QDir::currentDirPath(); QDir::setCurrent(*it); // Loop through all directory entries // Solaris and IRIX dirent structures do not allocate space for d_name. On // systems that do (HP-UX, Linux, Tru64 UNIX), we overallocate space but // that's ok. #ifndef HAVE_READDIR_R struct dirent *dirEntry = 0; while(!terminationRequested() && (dirEntry = ::readdir(dir))) #else struct dirent *dirPosition = (struct dirent *)malloc(sizeof(struct dirent) + MAXPATHLEN + 1); struct dirent *dirEntry = 0; while(!terminationRequested() && ::readdir_r(dir, dirPosition, &dirEntry) == 0 && dirEntry) #endif { // Skip hidden files if m_noHidden is true if(dirEntry->d_name[0] == '.' && m_noHidden) continue; // Skip "." if(dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '\0') continue; // Skip ".." if(dirEntry->d_name[0] == '.' && dirEntry->d_name[1] == '.' && dirEntry->d_name[2] == '\0') continue; QString file = QFile::decodeName(dirEntry->d_name); if(m_filter.isEmpty() || file.startsWith(m_filter)) { if(m_onlyExe || m_onlyDir || m_appendSlashToDir) { KDE_struct_stat sbuff; if(KDE_stat(dirEntry->d_name, &sbuff) == 0) { // Verify executable if(m_onlyExe && (sbuff.st_mode & MODE_EXE) == 0) continue; // Verify directory if(m_onlyDir && !S_ISDIR(sbuff.st_mode)) continue; // Add '/' to directories if(m_appendSlashToDir && S_ISDIR(sbuff.st_mode)) file.append('/'); } else { kdDebug() << "Could not stat file " << file << endl; continue; } } addMatch(file); } } // chdir to the original directory QDir::setCurrent(path); ::closedir(dir); dir = 0; #ifdef HAVE_READDIR_R free(dirPosition); #endif } done(); }