bbk/src/framework/task.cpp
2025-10-13 10:38:50 +02:00

146 lines
3.7 KiB
C++

// Copyright (c) 2019 The Swedish Internet Foundation
// Written by Göran Andersson <initgoran@gmail.com>
#include "task.h"
#include "socketconnection.h"
#include "serversocket.h"
#ifdef USE_THREADS
thread_local
#endif
EventLoop *Task::supervisor = nullptr;
Task::Task(const std::string &task_name) :
Logger(task_name) {
log() << "Task " << task_name << " created";
}
void Task::setResult(const std::string &res) {
if (is_finished) {
dbg_log() << "result already set, ignoring " << res;
} else {
dbg_log() << "setResult " << res;
is_finished = true;
the_result = res;
if (has_started)
supervisor->notifyTaskFinished(this);
}
}
void Task::setMessage(const std::string &msg) {
the_message = msg;
supervisor->notifyTaskMessage(this);
}
PollState Task::connectionReady(SocketConnection * /* conn */) {
log() << "connectionReady not implemented";
return PollState::CLOSE;
}
PollState Task::msgFromConnection(SocketConnection * /* conn */,
const std::string & /* msg */) {
log() << "msgFromConnection not implemented";
return PollState::CLOSE;
}
bool Task::addConnection(SocketConnection *conn) {
if (terminated()) {
if (conn)
delete conn;
return false;
}
return supervisor->addConnection(conn);
}
bool Task::addConnected(SocketConnection *conn) {
if (terminated()) {
if (conn)
delete conn;
return false;
}
return supervisor->addConnected(conn);
}
bool Task::adoptConnection(Socket *conn) {
conn->setOwner(this);
return true;
}
std::set<Socket *> Task::getMyConnections() const {
return supervisor->findConnByTask(this);
}
void Task::wakeUp() {
supervisor->wakeUpTask(this);
}
Task::~Task() {
supervisor->taskDeleted(this);
}
bool Task::addServer(ServerSocket *conn) {
if (terminated()) {
if (conn)
delete conn;
return false;
}
return supervisor->addServer(conn);
}
int Task::runProcess(const char *const argv[]) {
return supervisor->externalCommand(this, argv);
}
void Task::processFinished(int pid, int wstatus) {
log() << "Process " << pid << " finished, status " << wstatus;
}
bool Task::parseListen(const TaskConfig &tc, const std::string &log_label) {
auto to = tc.cfg().upper_bound("listen");
for (auto p=tc.cfg().lower_bound("listen"); p!=to; ++p) {
std::istringstream s(p->second);
uint16_t port;
std::string ip;
s >> port;
if (!s) {
err_log() << "Bad configuration directive: listen " << p->second;
setError("bad configuration directive");
return false;
}
s >> ip;
bool tls;
if (ip.empty()) {
tls = false;
} else if (ip == "tls") {
ip.clear();
tls = true;
} else {
std::string tmp;
s >> tmp;
tls = (tmp == "tls");
}
auto sock = new ServerSocket(log_label, this, port, ip);
#ifdef USE_GNUTLS
if (tls) {
std::string cert, key, password;
s >> cert >> key >> password;
if (key.empty() || !tlsSetKey(sock, cert, key, password)) {
err_log() << "Bad configuration: " << p->second;
setError("cannot use TLS certificate");
return false;
}
log() << "Port " << port << " enable TLS";
}
#else
if (tls) {
err_log() << "cannot enable TLS, will not listen on port " << port;
return false;
}
#endif
if (!addServer(sock)) {
setError("cannot listen");
return false;
}
}
return true;
}