-
-
Notifications
You must be signed in to change notification settings - Fork 511
Description
Apologies for the bad formatting but it just wouldn't accept it as it should.
I have a linux application and the last class I've added uses CrowCpp to serve a website that'll become the gui in the end.
When I interrupt the program by pressing CTRL-C the main program loop just keeps on running. I do not have that issue with instances of other classes.
Everything shuts down cleanly but if I dare run the website it no longer works.
I have eventhandlers in place for amongst others SIGHUP and SIGINT. SIGINT is the equivalent of pressing CTRL-C in a terminal.
Both can be sent as kill -SIGHUP pid and kill -SIGINT pid. The latter is thus the equivalent op pressing CTRL-C.
I made a POC that only installs 2 signal handlers that exhibits the same problem. It could be a bit shorter but I kept the main program loop the same as in the real code.
`#include
#include
#include
#include
#include
#include <crow.h>
class MyCrowApp {
public:
MyCrowApp(unsigned int port) : port(port) {
std::cout << "Constructing MyCrowApp instance." << std::endl;
processingThread = std::thread(&MyCrowApp::runWebserver, this); // Start webserver in a separate thread.
}
~MyCrowApp() {
app.stop();
if (processingThread.joinable()) {
processingThread.join();
}
std::cout << "Destructed MyCrowApp instance." << std::endl;
}
void runWebserver() {
std::cout << "Webserver starting ..." << std::endl;
// Define the endpoint at the root directory
CROW_ROUTE(app, "/")([](){
return "Hello world";
});
// Set the port, configure to run on multiple threads, and run the app
app.port(port).multithreaded().run(); // This is a blocking call
std::cout << "Webserver stopped ..." << std::endl;
}
private:
unsigned int port;
crow::SimpleApp app;
std::thread processingThread;
};
void signalHandler( int signum ) {
std::cout << "Received signal " << signum << " -> Exiting gracefully." << std::endl;
exit(signum);
}
int main() {
std::cout << "PID " << getpid() << std::endl;
signal(SIGHUP, signalHandler);
signal(SIGINT, signalHandler);
std::atomic_bool keepOnRunning = true;
MyCrowApp myApp(10088);
std::condition_variable cv;
std::mutex cv_m;
std::thread t([&] {
while (keepOnRunning) {
std::this_thread::sleep_for(std::chrono::seconds(1));
cv.notify_one();
}
});
std::unique_lock<std::mutex> lk(cv_m);
while (keepOnRunning) {
cv.wait(lk);
std::cout << "Sign of life ..." << std::endl;
}
t.join();
exit(EXIT_SUCCESS);
}`
The output when sending SIGINT:
./sandbox4
PID 12069
Constructing MyCrowApp instance.
Webserver starting ...
(2024-06-15 16:59:35) [INFO ] Crow/master server is running at http://0.0.0.0:10088 using 8 threads
(2024-06-15 16:59:35) [INFO ] Call app.loglevel(crow::LogLevel::Warning) to hide Info level logs.
Sign of life ...
Sign of life ...
-> Command executed -> kill -SIGINT 12069 ( It wouldn't make a difference if I do CTRL-C )
(2024-06-15 16:59:50) [INFO ] Closing IO service 0x73e4f4001fc0
(2024-06-15 16:59:50) [INFO ] Closing IO service 0x73e4f4001fc8
(2024-06-15 16:59:50) [INFO ] Closing IO service 0x73e4f4001fd0
(2024-06-15 16:59:50) [INFO ] Closing IO service 0x73e4f4001fd8
(2024-06-15 16:59:50) [INFO ] Closing IO service 0x73e4f4001fe0
(2024-06-15 16:59:50) [INFO ] Closing IO service 0x73e4f4001fe8
(2024-06-15 16:59:50) [INFO ] Closing IO service 0x73e4f4001ff0
(2024-06-15 16:59:50) [INFO ] Closing main IO service (0x73e4f4001078)
(2024-06-15 16:59:50) [INFO ] Exiting.
Webserver stopped ...
-> The main program loop just continues ...
Sign of life ...
Sign of life ...
-> Command executed -> kill -9 12069
Killed
The ouput when sending SIGHUP:
./sandbox4
PID 12094
Constructing MyCrowApp instance.
Webserver starting ...
(2024-06-15 17:04:18) [INFO ] Crow/master server is running at http://0.0.0.0:10088 using 8 threads
(2024-06-15 17:04:18) [INFO ] Call `app.loglevel(crow::LogLevel::Warning)` to hide Info level logs.
Sign of life ...
Sign of life ...
Sign of life ...
-> Command executed -> kill -SIGHUP 12094
Received signal 1 -> Exiting gracefully.
Notice there is no output from Crow nor log messages from myApp's destructor.
I experimented with Crow's run_async() method and tried several approaches but nothing works.
It is as if Crow does something to the signals that interferes with the other code.
I've got 15 classes in it with x instances and everything destructs neatly but not so the Crow class.
I don't have a clue anymore.
If somebody has an idea do elaborate please.