示例#1
0
    void threadFunction() {
        while (true) {
            Task* task = getNextTask();
            ProblemSpace::iterator problem;

            if (!task) {
                return;
            }

            while (!task->cancelled()) {
                std::unique_lock<std::mutex> problemLock(m_problemMutex);

                if (m_currentProblem == task->problemSpace().end()) {
                    break;
                }

                problem = m_currentProblem++;
                problemLock.unlock();

                //Execute task on a single problem from the problem space
                (*task)(problem);
                task->notifyProblem(problem);
            }

            retireTask(task);
        }
    }
示例#2
0
int ThreadPool::threadRun(){
	LOG_INFO("ThreadPool " << name() << " workThread start");
	
	while (_started) {
		TaskPtr t = getNextTask();
		int ret = t->execute();
		if (ret < 0) {
			LOG_ERROR("ThreadPool " << name() << "task execution error");
		}
	}

	LOG_INFO("ThreadPool stoped");
	return 0;
}
示例#3
0
    void Thread::thread_loop() {
        Task *task;

        threadStarted();

        while(_run) {
            try {
                while ((task = getNextTask())) {
                    task->run();
                    task->acquired_thread = 0;
                    if (task->task_finished)
                        delete task;
                }
                
                while ((task = dynamic_cast<Task*>(Task::getNextTask()))) {
                    task->run();
                    task->acquired_thread = 0;
                    if (task->task_finished)
                        delete task;
                }
                
                if (task_queue.length())
                    continue;
                
            } catch (...) {
                LOG(Log::LOGLEVEL_ERROR, "Invalid Task in queue");
            }
            
            if (!pool || threads->length() > max_threads)
                break;
            
            wait();
        }

        threadFinished();
    }
示例#4
0
void *
ComThread::Entry(void)
{
	struct pollfd	 fds[2];
	ComTask		*current = NULL;
	Notification	*notify;
	ConnectResult	 connectResult;

	connectResult = connect();

	switch (connectResult) {
	case Success:
		break;
	case Failure:
		sendComEvent(JobCtrl::ERR_CONNECT);
		return (0);
	case VersionMismatch:
		sendComEvent(JobCtrl::ERR_VERSION_PROT);
		return (0);
	case AuthNoKey:
		sendComEvent(JobCtrl::ERR_NO_KEY);
		return (0);
	case AuthWrongKeyId:
		sendComEvent(JobCtrl::ERR_KEYID);
		return (0);
	case AuthInvalidKey:
		sendComEvent(JobCtrl::ERR_INV_KEY);
		return (0);
	case AuthInvalidCert:
		sendComEvent(JobCtrl::ERR_INV_CERT);
		return (0);
	case AuthSysFail:
		sendComEvent(JobCtrl::ERR_AUTH_SYS_FAIL);
		return(0);
	}

	fds[0].fd = comPipe_[0];
	fds[0].events = POLLIN;
	fds[1].fd = channel_->fd;
	fds[1].events = POLLIN;

	while (1) {
		/*
		 * Step 1: Clear the notification pipe. We do this first
		 *         to ensure that other events that come in along
		 *         the way will cause the poll below to return
		 *         immediately.
		 */
		while(1) {
			int ret;
			char buf[100];

			ret = read(comPipe_[0], buf, sizeof(buf));
			if (ret <= 0)
				break;
		}
		/* Step 2: Send any pending escalation answers. */
		while((notify = answerQueue_->pop()) != 0) {
			anoubis_token_t		 token;
			bool			 allowed;
			EscalationNotify	*escalation;

			escalation = dynamic_cast<EscalationNotify *>(notify);
			if (escalation) {
				allowed = escalation->getAnswer()->wasAllowed();
				token = escalation->getToken();
				anoubis_client_notifyreply(client_, token,
				    allowed ? 0 : EPERM, 0);
			}
			if (notify->needFree())
				delete notify;
		}
		/* Step 3: If no task is running, try to start a new one. */
		if (current == NULL) {
			Task	*task = getNextTask(Task::TYPE_COM);

			current = dynamic_cast<ComTask *>(task);
			if (current && !current->shallAbort()) {
				current->setClient(client_);
				current->exec();
			}
		}
		/*
		 * Step 4: If the current task is done, handle this.
		 *         This also handles errors in current->exec()
		 *         and performs the next stpes of the task if the
		 *         task is not yet done.
		 */
		if (current && (current->shallAbort() || current->done())) {
			TaskEvent	event(current, wxID_ANY);

			/* Task is no longer a COM task. Reschedule. */
			if (current->getType() != Task::TYPE_COM) {
				JobCtrl::instance()->addTask(current);
				current = NULL;
				continue;
			}
			if (current->shallAbort())
				current->setTaskResultAbort();
			sendEvent(event);
			/* Restart in case there are more tasks on the list. */
			current = NULL;
			continue;
		}
		/*
		 * Step 5: At this point we have an active task that is
		 *         waiting for data from the network and all
		 *         pending answer requests have been handled.
		 *         We poll until either new Jobs or answers
		 *         become ready or a message from the daemon arrives.
		 */
		if (!isConnected() || exitThread())
			break;
		fds[0].revents = 0;
		fds[1].revents = 0;
		if (poll(fds, 2, 60000) <= 0) {
			continue;
		}
		/*
		 * Step 6: Process a message from the Daemon if there is
		 *         one. Then start over.
		 */
		if (fds[1].revents) {
			if (!readMessage())
				break;
		}
	}

	/* Thread is short before exit, disconnect again */
	disconnect();

	return (0);
}