diff --git a/examples/eventloop.cpp b/examples/eventloop.cpp index bb57c944..e5783425 100644 --- a/examples/eventloop.cpp +++ b/examples/eventloop.cpp @@ -29,15 +29,21 @@ #include -finalcut::EventLoop Loop{}; -struct termios OriginalTermIoSettings{}; +struct Global +{ + static struct termios original_term_io_settings; // global termios object +}; + +// static class attribute +struct termios Global::original_term_io_settings{}; + //---------------------------------------------------------------------- void onExit() { // Restore terminal control - tcsetattr (STDIN_FILENO, TCSAFLUSH, &OriginalTermIoSettings); + tcsetattr (STDIN_FILENO, TCSAFLUSH, &Global::original_term_io_settings); std::cout << "Bye!" << std::endl; } @@ -48,17 +54,18 @@ void onExit() auto main() -> int { - finalcut::TimerMonitor timer1{&Loop}; - finalcut::TimerMonitor timer2{&Loop}; - finalcut::SignalMonitor sig_int_monitor{&Loop}; - finalcut::SignalMonitor sig_abrt_monitor{&Loop}; - finalcut::IoMonitor stdin_monitor{&Loop}; + finalcut::EventLoop loop{}; + finalcut::TimerMonitor timer1{&loop}; + finalcut::TimerMonitor timer2{&loop}; + finalcut::SignalMonitor sig_int_monitor{&loop}; + finalcut::SignalMonitor sig_abrt_monitor{&loop}; + finalcut::IoMonitor stdin_monitor{&loop}; // Save terminal setting and set terminal to raw mode // (no echo, no line buffering). - tcgetattr (STDIN_FILENO, &OriginalTermIoSettings); + tcgetattr (STDIN_FILENO, &Global::original_term_io_settings); atexit (onExit); - struct termios new_term_io_settings{OriginalTermIoSettings}; + struct termios new_term_io_settings{Global::original_term_io_settings}; new_term_io_settings.c_lflag &= ~(ECHO | ICANON); tcsetattr (STDIN_FILENO, TCSAFLUSH, &new_term_io_settings); @@ -86,20 +93,20 @@ auto main() -> int , std::chrono::nanoseconds{ 1'000'000'000 } ); sig_int_monitor.init ( SIGINT - , [] (const finalcut::Monitor*, short) + , [&loop] (const finalcut::Monitor*, short) { std::cout << "Signal SIGINT received." << std::endl; - Loop.leave(); + loop.leave(); } , nullptr ); sig_abrt_monitor.init ( SIGABRT - , [] (const finalcut::Monitor*, short) + , [&loop] (const finalcut::Monitor*, short) { std::cout << "Signal SIGABRT received." << std::endl; - Loop.leave(); + loop.leave(); } , nullptr ); @@ -124,5 +131,5 @@ auto main() -> int stdin_monitor.resume(); // Monitoring - return Loop.run(); + return loop.run(); } diff --git a/final/eventloop/kqueue_timer.cpp b/final/eventloop/kqueue_timer.cpp index 1fd77af8..7592b6d1 100644 --- a/final/eventloop/kqueue_timer.cpp +++ b/final/eventloop/kqueue_timer.cpp @@ -89,7 +89,6 @@ struct TimerNode static std::vector timer_nodes{}; static std::vector time_events{}; -static std::mutex timer_nodes_mutex{}; //---------------------------------------------------------------------- @@ -99,7 +98,8 @@ static std::mutex timer_nodes_mutex{}; class KqueueHandler { public: - void operator () (Monitor* monitor, short revents) const + // Overloaded operator + void operator () (Monitor* monitor, short revents) { std::lock_guard lock_guard(timer_nodes_mutex); @@ -149,6 +149,10 @@ class KqueueHandler kqueue_timer_ptr->timer_handler(monitor, revents); } } + + private: + // Data members + std::mutex timer_nodes_mutex{}; }; diff --git a/final/eventloop/monitor.cpp b/final/eventloop/monitor.cpp index 2bd1bf62..8280a05f 100644 --- a/final/eventloop/monitor.cpp +++ b/final/eventloop/monitor.cpp @@ -30,8 +30,7 @@ namespace finalcut // class monitor_error //---------------------------------------------------------------------- -monitor_error::~monitor_error() -{ } +monitor_error::~monitor_error() = default; //---------------------------------------------------------------------- diff --git a/final/eventloop/posix_timer.cpp b/final/eventloop/posix_timer.cpp index c5229279..3cdeaa8b 100644 --- a/final/eventloop/posix_timer.cpp +++ b/final/eventloop/posix_timer.cpp @@ -69,7 +69,6 @@ struct TimerNode }; static std::list timer_nodes{}; -static std::mutex timer_nodes_mutex{}; //---------------------------------------------------------------------- @@ -86,32 +85,60 @@ static std::mutex timer_nodes_mutex{}; , static_cast(duration.count()) }; } + +//---------------------------------------------------------------------- +// class SigAlrmHandler //---------------------------------------------------------------------- -static void onSigAlrm (int, siginfo_t* signal_info, void*) -{ - const auto& timer_id = *static_cast(signal_info->si_value.sival_ptr); - std::lock_guard lock_guard(timer_nodes_mutex); - for (const auto& timer_node : timer_nodes) - { - if ( timer_id != timer_node.timer_id ) - continue; +class SigAlrmHandler +{ + public: + // Using-declaration + using HandlerReturnType = void (*)(int, siginfo_t*, void*); - if ( timer_node.timer_monitor->isActive() ) + // Overloaded operators + void operator () (int, siginfo_t* signal_info, void*) { - // The event loop is notified by write access to the pipe - uint64_t buffer{1U}; - auto successful = ::write (timer_node.fd, &buffer, sizeof(buffer)) > 0; + const auto& timer_id = *static_cast(signal_info->si_value.sival_ptr); + std::lock_guard lock_guard(timer_nodes_mutex); - if ( ! successful ) + for (const auto& timer_node : timer_nodes) { - // Possible error handling + if ( timer_id != timer_node.timer_id ) + continue; + + if ( timer_node.timer_monitor->isActive() ) + { + // The event loop is notified by write access to the pipe + uint64_t buffer{1U}; + auto successful = ::write (timer_node.fd, &buffer, sizeof(buffer)) > 0; + + if ( ! successful ) + { + // Possible error handling + } + } + + break; } } - break; - } -} + operator HandlerReturnType () const noexcept + { + // Converts a member function pointer to a function pointer + return invoke; + }; + + private: + // Method + static void invoke (int, siginfo_t* signal_info, void*) + { + return SigAlrmHandler{}.operator()(0, signal_info, nullptr); + } + + // Data members + std::mutex timer_nodes_mutex{}; +}; //---------------------------------------------------------------------- @@ -240,7 +267,7 @@ class SigAlrmHandlerInstaller { struct sigaction signal_handle{}; sigemptyset(&signal_handle.sa_mask); - signal_handle.sa_sigaction = onSigAlrm; + signal_handle.sa_sigaction = SigAlrmHandler(); signal_handle.sa_flags = SA_SIGINFO; if ( sigaction(SIGALRM, &signal_handle, &original_signal_handle) != -1 ) diff --git a/final/eventloop/timer_monitor.h b/final/eventloop/timer_monitor.h index eedd6f3b..fac8ab6a 100644 --- a/final/eventloop/timer_monitor.h +++ b/final/eventloop/timer_monitor.h @@ -74,6 +74,9 @@ namespace finalcut class TimerMonitorImpl : public Monitor { public: + // Using-declaration + using Monitor::Monitor; + // Constructor explicit TimerMonitorImpl (EventLoop* eloop) : Monitor(eloop) @@ -108,8 +111,8 @@ class PosixTimer : public TimerMonitorImpl , std::chrono::nanoseconds ) override; void trigger(short) override; - private: #if defined(USE_POSIX_TIMER) + private: // Data members timer_t timer_id{}; std::array alarm_pipe_fd{NO_FILE_DESCRIPTOR, NO_FILE_DESCRIPTOR}; @@ -136,18 +139,18 @@ class KqueueTimer : public TimerMonitorImpl , std::chrono::nanoseconds ) override; void trigger(short) override; - private: #if defined(USE_KQUEUE_TIMER) - // Constants - static constexpr int NO_TIMER_ID{-1}; - - // Data members + private: struct TimerSpec { int period_ms{}; int first_ms{}; }; + // Constants + static constexpr int NO_TIMER_ID{-1}; + + // Data members int timer_id{NO_TIMER_ID}; bool first_interval{true}; TimerSpec timer_spec{}; @@ -182,6 +185,10 @@ struct TimerClass class TimerMonitor final : public TimerClass::type { public: + // Using-declarations + using base_class = TimerClass::type; + using base_class::base_class; + TimerMonitor() = delete; // Disable copy constructor diff --git a/final/input/fmouse.h b/final/input/fmouse.h index fd823dc8..dfd2fd78 100644 --- a/final/input/fmouse.h +++ b/final/input/fmouse.h @@ -297,7 +297,7 @@ class FMouseGPM final : public FMouse }; // Method - auto gpmEvent (bool = true) const -> gpmEventType; + auto gpmEvent (bool = true) const -> gpmEventType; // Data member Gpm_Event gpm_ev{};