Skip to content

Commit

Permalink
TgBot++: Make sighandlers registerable, add sighandler to builder
Browse files Browse the repository at this point in the history
- Add galaxy s4 config
  • Loading branch information
Royna2544 committed Jul 6, 2024
1 parent 02bd6b2 commit ac5bae1
Show file tree
Hide file tree
Showing 17 changed files with 138 additions and 43 deletions.
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,6 @@ set(SRC_LIST
src/command_modules/compiler/Generic.cpp
src/command_modules/compiler/Helper.cpp
src/database/bot/TgBotDatabaseImpl.cpp
src/libos/libsighandler_impl.cpp
src/libos/libsighandler_${TARGET_VARIANT}.cpp
src/popen_wdt/popen_wdt.c
src/popen_wdt/popen_wdt_${TARGET_VARIANT}.c
src/random/RandomNumberGenerator.cpp
Expand Down
2 changes: 2 additions & 0 deletions cmake/tgbotutils.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ add_library_san(
src/ConfigManager.cpp
src/ConfigManager_${TARGET_VARIANT}.cpp
src/GitData.cpp
src/libos/libsighandler_impl.cpp
src/libos/libsighandler_${TARGET_VARIANT}.cpp
src/libos/libfs.cpp
src/libos/libfs_${TARGET_VARIANT}.cpp)

Expand Down
14 changes: 14 additions & 0 deletions src/android_builder/ForkAndRun.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@

#include <csignal>
#include <cstdlib>
#include <libos/OnTerminateRegistrar.hpp>
#include <string>
#include <thread>

#include "random/RandomNumberGenerator.h"

bool ForkAndRun::execute() {
Pipe stdout_pipe{};
Pipe stderr_pipe{};
Expand Down Expand Up @@ -46,13 +49,22 @@ bool ForkAndRun::execute() {
Py_DECREF(os_environ);
Py_DECREF(os);

// Clear handlers
signal(SIGINT, [](int){});
signal(SIGTERM, [](int){});

int ret = runFunction() ? EXIT_SUCCESS : EXIT_FAILURE;
absl::RemoveLogSink(&sink);
_exit(ret);
} else if (pid > 0) {
Pipe program_termination_pipe{};
bool breakIt = false;
int status = 0;
random_return_type token = RandomNumberGenerator::generate(100);
auto tregi = OnTerminateRegistrar::getInstance();

tregi->registerCallback(
[this](int sig) { cancel(); }, token);

childProcessId = pid;
close(stdout_pipe.writeEnd());
Expand Down Expand Up @@ -132,6 +144,8 @@ bool ForkAndRun::execute() {
program_termination_pipe.close();
stderr_pipe.close();
stdout_pipe.close();
python_pipe.close();
tregi->unregisterCallback(token);
} else {
PLOG(ERROR) << "Unable to fork";
}
Expand Down
6 changes: 6 additions & 0 deletions src/android_builder/PythonClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ std::vector<long> convert<std::vector<long>>(PyObject* value) {
} // namespace details

bool PythonClass::addLookupDirectory(const std::filesystem::path& directory) {
GILStateManagement _;

// Get the sys.path list from Python interpreter
PyObject* sysPath = PySys_GetObject("path");

Expand All @@ -87,6 +89,8 @@ bool PythonClass::addLookupDirectory(const std::filesystem::path& directory) {

std::shared_ptr<PythonClass::ModuleHandle> PythonClass::importModule(
const std::string& name) {
GILStateManagement _;

// Import the specified module
PyObject* module = PyImport_ImportModule(name.c_str());

Expand All @@ -102,6 +106,8 @@ std::shared_ptr<PythonClass::ModuleHandle> PythonClass::importModule(

std::shared_ptr<PythonClass::FunctionHandle>
PythonClass::ModuleHandle::lookupFunction(const std::string& name) {
GILStateManagement _;

// Get the specified function from the current module
PyObject* function = PyObject_GetAttrString(module, name.c_str());

Expand Down
7 changes: 7 additions & 0 deletions src/android_builder/PythonClass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ std::vector<int> convert<std::vector<int>>(PyObject* value);

} // namespace details

struct GILStateManagement {
GILStateManagement() : gstate(PyGILState_Ensure()) {}
~GILStateManagement() { PyGILState_Release(gstate); }
PyGILState_STATE gstate;
};

class PythonClass : public std::enable_shared_from_this<PythonClass> {
// Declare a class to hold Py_init functions
struct PyInitHolder {
Expand Down Expand Up @@ -93,6 +99,7 @@ class PythonClass : public std::enable_shared_from_this<PythonClass> {
*/
template <typename T>
bool call(PyObject* args, T* out) {
GILStateManagement _;
LOG(INFO) << "Calling Python function: module "
<< moduleHandle->name << " function: " << name;

Expand Down
3 changes: 2 additions & 1 deletion src/android_builder/configs/build_config.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# Name RomName LocalManifestUrl LocalManifestBranch device variant
EvoxTablet Evox https://github.com/Roynas-Android-Playground/local_manifests/ tb128fu-Evolution-X-udc tb128fu user
EvoxA30 Evox https://github.com/Roynas-Android-Playground/local_manifests/ Exynos7885-fourteen a30 user
EvoxA30 Evox https://github.com/Roynas-Android-Playground/local_manifests/ Exynos7885-fourteen a30 user
crDroidS4 crDroid https://github.com/Roynas-Android-Playground/local_manifests/ ks01lteskt-crDroid-11.0 ks01ltexx user
1 change: 1 addition & 0 deletions src/android_builder/configs/rom_config.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Name RepoUrl RepoBranch TargetName OutZipPrefix
Evox https://github.com/Evolution-XYZ/manifest udc evolution EvolutionX
crDroid https://github.com/crdroidandroid/android/ 11.0 bacon crDroidAndroid
4 changes: 2 additions & 2 deletions src/android_builder/scripts/build_rom_utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import subprocess_utils
import os
import print
import custom_print

print = print.print_fd
print = custom_print.custom_print

def find_vendor_str() -> str:
vendor_path = 'vendor/'
Expand Down
14 changes: 14 additions & 0 deletions src/android_builder/scripts/custom_print.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import os

def custom_print(*args, **kwargs):
logfd = int(os.environ['PYTHON_LOG_FD'])

# Get kwargs or set default values
sep = kwargs.get('sep', ' ')
end = kwargs.get('end', '\n')

# Construct the message
message = sep.join(map(str, args)) + end

# Write the message to the file descriptor
os.write(logfd, message.encode())
23 changes: 0 additions & 23 deletions src/android_builder/scripts/print.py

This file was deleted.

6 changes: 3 additions & 3 deletions src/android_builder/scripts/subprocess_utils.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import subprocess
import sys
import print
import custom_print

testing = False
testing = True
testingRet = True

print = print.print_fd
print = custom_print.custom_print

def run_command(command: str) -> bool:
print("Running command: %s" % command)
Expand Down
2 changes: 0 additions & 2 deletions src/android_builder/tasks/ROMBuildTask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
#include <boost/algorithm/string/trim.hpp>
#include <chrono>
#include <cmath>
#include <iomanip>
#include <memory>
#include <mutex>
#include <ostream>

Expand Down
5 changes: 4 additions & 1 deletion src/database/bot/TgBotDatabaseImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <database/ProtobufDatabase.hpp>
#include <database/SQLiteDatabase.hpp>
#include <libos/OnTerminateRegistrar.hpp>
#include <variant>

#include "InstanceClassBase.hpp"
Expand All @@ -24,7 +25,7 @@ struct TgBotDatabaseImpl : InstanceClassBase<TgBotDatabaseImpl>, InitCall {
[[nodiscard]] std::optional<UserId> getOwnerUserId() const;
[[nodiscard]] std::optional<DatabaseBase::MediaInfo> queryMediaInfo(
std::string str) const;
[[nodiscard]] bool addMediaInfo(const DatabaseBase::MediaInfo& info) const;
[[nodiscard]] bool addMediaInfo(const DatabaseBase::MediaInfo &info) const;
std::ostream &dump(std::ostream &ofs) const;
void setOwnerUserId(UserId userid) const;
[[nodiscard]] bool addChatInfo(const ChatId chatid,
Expand All @@ -37,6 +38,8 @@ struct TgBotDatabaseImpl : InstanceClassBase<TgBotDatabaseImpl>, InitCall {
}
void doInitCall() override {
loadDBFromConfig();
OnTerminateRegistrar::getInstance()->registerCallback(
[this](int) { unloadDatabase(); });
}

private:
Expand Down
65 changes: 65 additions & 0 deletions src/libos/OnTerminateRegistrar.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include <functional>
#include <map>

#include "InstanceClassBase.hpp"

struct OnTerminateRegistrar : InstanceClassBase<OnTerminateRegistrar> {
using callback_type = std::function<void(int sig)>;

/**
* @brief Registers a callback function to be called when the process
* terminates.
*
* @param callback The function to be called when signal is received.
*/
void registerCallback(const callback_type& callback) {
callbacks.emplace_back(callback);
}

/**
* @brief Registers a callback function with a token to be called the
* process terminates.
*
* @param callback The function to be called when signal is received.
* @param token A unique identifier for the callback.
*/
void registerCallback(const callback_type& callback, const size_t token) {
callbacksWithToken[token] = callback;
}

/**
* @brief Unregisters a callback function with a token from the list of
* callbacks to be called when any message is received.
*
* @param token The unique identifier of the callback to be unregistered.
*
* @return True if the callback with the specified token was found and
* successfully unregistered, false otherwise.
*/
bool unregisterCallback(const size_t token) {
auto it = callbacksWithToken.find(token);
if (it == callbacksWithToken.end()) {
return false;
}
callbacksWithToken.erase(it);
return true;
}

/**
* @brief Calls all registered callback functions with the given signal.
*
* @param sig The signal to be sent to all registered callback functions.
*/
void callCallbacks(int sig) {
for (const auto& callback : callbacks) {
callback(sig);
}
for (const auto& pair : callbacksWithToken) {
pair.second(sig);
}
}

private:
std::vector<callback_type> callbacks;
std::map<size_t, callback_type> callbacksWithToken;
};
6 changes: 3 additions & 3 deletions src/libos/libsighandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

using exit_handler_t = void (*)(int);

constexpr int invalidSignal = -1;

/**
* installSignalHandler - install the default signal handler
* Signal handler is the function that is called after signal event
Expand All @@ -17,6 +19,4 @@ void installSignalHandler();
* @param sig signal number
*/
extern void defaultSignalHandler(int sig);
extern void defaultCleanupFunction();

constexpr int invalidSignal = -1;
extern void defaultCleanupFunction(int bySignal = invalidSignal);
16 changes: 10 additions & 6 deletions src/libos/libsighandler_impl.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
#include <absl/log/log.h>

#include <ManagedThreads.hpp>
#include <database/bot/TgBotDatabaseImpl.hpp>
#include <mutex>

#include "InstanceClassBase.hpp"
#include "OnTerminateRegistrar.hpp"
#include "libsighandler.h"

void defaultSignalHandler(int s) {
static std::once_flag once;
std::call_once(once, [s] { defaultCleanupFunction(); });
std::call_once(once, [s] { defaultCleanupFunction(s); });
std::exit(0);
};

void defaultCleanupFunction() {
void defaultCleanupFunction(int bySignal) {
LOG(INFO) << "Exiting";
ThreadManager::getInstance()->destroyManager();
TgBotDatabaseImpl::getInstance()->unloadDatabase();
OnTerminateRegistrar::getInstance()->callCallbacks(bySignal);
LOG(INFO) << "TgBot process exiting, Goodbye!";
}
}

DECLARE_CLASS_INST(OnTerminateRegistrar);
5 changes: 5 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ void initLogging() {

void createAndDoInitCallAll(TgBot::Bot& gBot) {
constexpr int kWebServerListenPort = 8080;

createAndDoInitCall<StringResManager>();
createAndDoInitCall<TgBotWebServer, ThreadManager::Usage::WEBSERVER_THREAD>(
kWebServerListenPort);
Expand All @@ -208,6 +209,10 @@ void createAndDoInitCallAll(TgBot::Bot& gBot) {
createAndDoInitCall<TgBotDatabaseImpl>();
// Must be last
createAndDoInitCall<OnAnyMessageRegisterer>(gBot);
// Must be last
OnTerminateRegistrar::getInstance()->registerCallback([](int sig) {
ThreadManager::getInstance()->destroyManager();
});
}

void onBotInitialized(TgBot::Bot& gBot, DurationPoint& startupDp,
Expand Down

0 comments on commit ac5bae1

Please sign in to comment.