idle_detect  0.8.3.0
Provides overall idle detection for a linux computer
event_detect.h
1 /*
2  * Copyright (C) 2025 James C. Owens
3  *
4  * This code is licensed under the MIT license. See LICENSE.md in the repository.
5  */
6 
7 #ifndef EVENT_DETECT_H
8 #define EVENT_DETECT_H
9 
10 #include <atomic>
11 #include <condition_variable>
12 #include <mutex>
13 #include <thread>
14 #include <filesystem>
15 
16 #include <util.h>
17 
18 namespace EventDetect {
19 
27 class Monitor
28 {
29 public:
33  std::thread m_monitor_thread;
34 
38  std::condition_variable cv_monitor_thread;
39 
43  std::atomic<bool> m_interrupt_monitor;
44 
48  Monitor();
49 
55  std::vector<fs::path> GetEventDevices() const;
56 
60  void UpdateEventDevices();
61 
66 
72  bool IsInitialized() const;
73 
78  int64_t GetLastActiveTime() const;
79 
80 private:
86  static std::vector<fs::path> EnumerateEventDevices();
87 
92  void WriteLastActiveTimeToFile(const fs::path& filepath);
93 
98  mutable std::mutex mtx_event_monitor;
99 
103  mutable std::mutex mtx_event_monitor_thread;
104 
108  std::vector<fs::path> m_event_device_paths;
109 
114  std::atomic<int64_t> m_last_active_time;
115 
120  std::atomic<bool> m_initialized;
121 };
122 
129 {
130 public:
134  std::condition_variable cv_recorder_threads;
135 
139  std::atomic<bool> m_interrupt_recorders;
140 
145 
152  {
153  public:
158 
163  explicit EventRecorder(fs::path event_device_path);
164 
170  fs::path GetEventDevicePath() const;
171 
176  int64_t GetEventCount() const;
177 
182 
183  private:
187  mutable std::mutex mtx_event_recorder;
188 
193 
197  std::atomic<int64_t> m_event_count;
198  };
199 
204  int64_t GetTotalEventCount() const;
205 
210  std::vector<std::shared_ptr<EventRecorder>>& GetEventRecorders();
211 
212  void ResetEventRecorders();
213 
214 private:
220  mutable std::mutex mtx_event_recorders;
221 
225  mutable std::mutex mtx_event_recorder_threads;
226 
230  std::vector<std::shared_ptr<EventRecorder>> m_event_recorder_ptrs;
231 };
232 
234 {
235 public:
239  std::thread m_tty_monitor_thread;
240 
244  std::condition_variable cv_tty_monitor_thread;
245 
249  std::atomic<bool> m_interrupt_tty_monitor;
250 
252  TtyMonitor();
253 
259  std::vector<fs::path> GetTtyDevices() const;
260 
264  void UpdateTtyDevices();
265 
269  void TtyMonitorThread();
270 
276  bool IsInitialized() const;
277 
282  int64_t GetLastTtyActiveTime() const;
283 
288  class Tty
289  {
290  public:
295  explicit Tty(const fs::path& tty_device_path);
296 
301 
306  };
307 
308 private:
313  static std::vector<fs::path> EnumerateTtyDevices();
314 
319  mutable std::mutex mtx_tty_monitor;
320 
324  mutable std::mutex mtx_tty_monitor_thread;
325 
330  std::vector<fs::path> m_tty_device_paths;
331 
335  std::vector<Tty> m_ttys;
336 
340  std::atomic<int64_t> m_last_ttys_active_time;
341 
346  std::atomic<bool> m_initialized;
347 };
348 
350 {
351 public:
352  enum State {
353  UNKNOWN,
354  NORMAL,
355  FORCED_ACTIVE,
356  FORCED_IDLE
357  };
358 
363 
367  std::condition_variable cv_idle_detect_monitor_thread;
368 
373 
376 
381 
387  bool IsInitialized() const;
388 
393  int64_t GetLastIdleDetectActiveTime() const;
394 
399  State GetState() const;
400 
406  static std::string StateToString(const State& state);
407 
412  std::string StateToString() const;
413 
414 private:
419  mutable std::mutex mtx_idle_detect_monitor;
420 
424  mutable std::mutex mtx_idle_detect_monitor_thread;
425 
429  std::atomic<int64_t> m_last_idle_detect_active_time;
430 
437  std::atomic<State> m_state;
438 
443  std::atomic<bool> m_initialized;
444 };
445 
452 public:
457  explicit SharedMemoryTimestampExporter(const std::string& name);
458 
463 
464  // Prevent copying/moving
469 
477  bool CreateOrOpen(mode_t mode = 0666);
478 
485  // *** SIGNATURE CHANGED ***
486  bool UpdateTimestamps(int64_t update_time, int64_t last_active_time);
487 
492  bool IsInitialized() const;
493 
499  bool UnlinkSegment();
500 
501 private:
505  void Cleanup();
506 
514  std::mutex mtx_shmem;
515 
516  std::string m_shm_name;
517  int m_shm_fd;
518  int64_t* m_mapped_ptr; // Pointer to the start of the int64_t[2] array
519  const size_t m_size; // Size of the int64_t[2] array
520  bool m_is_creator; // Did this instance create/resize the segment?
521  std::atomic<bool> m_is_initialized;
522 };
523 
528 void Shutdown(const int &exit_code = 0);
529 
530 } // namespace event_detect
531 
536 class EventDetectConfig : public Config
537 {
538  void ProcessArgs() override;
539 };
540 
541 #endif // EVENT_DETECT_H
bool IsInitialized() const
Provides a flag to indicate whether the monitor has been initialized. This is used in main in the app...
Definition: event_detect.cpp:828
std::condition_variable cv_tty_monitor_thread
Condition variable for control/synchronization of the tty monitor threads.
Definition: event_detect.h:244
std::atomic< int64_t > m_last_active_time
holds the last active time determined by the monitor. This is an atomic, which means it can be writte...
Definition: event_detect.h:114
static std::vector< fs::path > EnumerateTtyDevices()
Provides the enumerated pts/tty devices.
Definition: event_detect.cpp:523
int64_t GetLastTtyActiveTime() const
Returns the overall last active time of all of the monitored pts/ttys.
Definition: event_detect.cpp:517
fs::path GetEventDevicePath() const
Gets the event device path.
Definition: event_detect.cpp:359
int64_t GetLastActiveTime() const
Provides the last active time on this machine globally based on the activated monitors/recorders.
Definition: event_detect.cpp:215
void EventActivityMonitorThread()
This is the function that is the entry point for the event activity monitor worker thread...
Definition: event_detect.cpp:92
EventRecorder(fs::path event_device_path)
Parameterized constructor.
Definition: event_detect.cpp:348
std::mutex mtx_event_monitor_thread
This provides lock control for the monitor worker thread itself.
Definition: event_detect.h:103
bool IsInitialized() const
Provides a flag to indicate whether the monitor has been initialized. This is used in main in the app...
Definition: event_detect.cpp:512
std::condition_variable cv_monitor_thread
Condition variable for control/synchronization of the monitor thread.
Definition: event_detect.h:38
std::atomic< int64_t > m_event_count
Atomic that holds the current event tally for the monitored device.
Definition: event_detect.h:197
std::mutex mtx_event_monitor
This is the mutex member that provides lock control for the event monitor object. This is used to ens...
Definition: event_detect.h:98
std::mutex mtx_event_recorders
This is the mutex member that provides lock control for the input event recorders object...
Definition: event_detect.h:220
bool UpdateTimestamps(int64_t update_time, int64_t last_active_time)
Updates both timestamps in the mapped shared memory.
Definition: event_detect.cpp:1069
int64_t m_tty_last_active_time
Holds the last active time of the pts/tty.
Definition: event_detect.h:305
The Tty class is a small class to hold pts/tty information. It is essentially a struct with a paramet...
Definition: event_detect.h:288
Manages a POSIX shared memory segment for exporting timestamps. Stores an array of two int64_t: {upda...
Definition: event_detect.h:451
std::string StateToString() const
Returns the string representation of the idle monitor object state.
Definition: event_detect.cpp:865
std::atomic< int64_t > m_last_ttys_active_time
Atomic that holds the overall last active time across all of the monitored pts/ttys.
Definition: event_detect.h:340
fs::path m_tty_device_path
Holds the pts/tty device path.
Definition: event_detect.h:300
void TtyMonitorThread()
Method to instantiate the tty monitor thread.
Definition: event_detect.cpp:554
bool UnlinkSegment()
Explicitly unlinks the shared memory segment. Call during clean shutdown if desired. Idempotent.
Definition: event_detect.cpp:1108
std::condition_variable cv_idle_detect_monitor_thread
Condition variable for control/synchronization of the idle_detect monitor threads.
Definition: event_detect.h:367
Definition: event_detect.h:233
std::thread m_event_recorder_thread
Holds the actual event recorder thread.
Definition: event_detect.h:157
TtyMonitor()
Constructor.
Definition: event_detect.cpp:481
void EventActivityRecorderThread()
Method to run in the instantiated recorder thread.
Definition: event_detect.cpp:371
The Config class is a singleton that stores program config read from the config file, with applied defaults if the config file cannot be read, or a config parameter is not in the config file.
Definition: util.h:233
std::atomic< bool > m_initialized
This holds the flag as to whether the monitor has been initialized and is provided by the IsInitializ...
Definition: event_detect.h:120
int64_t GetTotalEventCount() const
Provides the total count (tally) of events across all monitored devices.
Definition: event_detect.cpp:334
std::vector< fs::path > GetEventDevices() const
Provides a copy of the m_event_device_paths private member. The copy is provided instead of a referen...
Definition: event_detect.cpp:287
int64_t GetLastIdleDetectActiveTime() const
Returns the overall last active time of all of the message receipts from idle_detect instances...
Definition: event_detect.cpp:833
bool IsInitialized() const
Checks if the shared memory was successfully initialized (opened and mapped).
Definition: event_detect.cpp:1083
The InputEventRecorders class provides the framework for recording event activity from each of the in...
Definition: event_detect.h:128
std::atomic< bool > m_interrupt_monitor
Atomic boolean that interrupts the monitor thread.
Definition: event_detect.h:43
InputEventRecorders()
Constructor.
Definition: event_detect.cpp:307
std::thread m_tty_monitor_thread
Holds the actual tty monitor thread.
Definition: event_detect.h:239
void WriteLastActiveTimeToFile(const fs::path &filepath)
This is the whole point of the application. This writes out the last active time determined by the mo...
Definition: event_detect.cpp:260
std::condition_variable cv_recorder_threads
Condition variable for control/synchronization of the recorder threads.
Definition: event_detect.h:134
std::atomic< bool > m_interrupt_tty_monitor
Atomic boolean that interrupts the tty monitor thread.
Definition: event_detect.h:249
The EventDetectConfig class. This specializes the Config class and implements the virtual method Proc...
Definition: event_detect.h:536
std::vector< Tty > m_ttys
std::vector holding the tty objects.
Definition: event_detect.h:335
std::vector< std::shared_ptr< EventRecorder > > m_event_recorder_ptrs
Holds smart shared pointers to the event recorder threads. This is a specialized thread pool with ass...
Definition: event_detect.h:230
Definition: event_detect.h:18
std::mutex mtx_tty_monitor
This is the mutex member that provides lock control for the tty monitor object. This is used to ensur...
Definition: event_detect.h:319
std::atomic< State > m_state
Holds the current state of the idle monitor. NORMAL means idle detect follows the normal threshold (t...
Definition: event_detect.h:437
fs::path m_event_device_path
Holds the event device path of the monitored device.
Definition: event_detect.h:192
The EventRecorder class formalizes the event recorder instance and is instantiated for each event rec...
Definition: event_detect.h:151
void Cleanup()
Performs resource cleanup (munmap). Called by destructor.
Definition: event_detect.cpp:1087
int64_t GetEventCount() const
Returns the current event count tallied by the recorder.
Definition: event_detect.cpp:364
std::mutex mtx_idle_detect_monitor_thread
This provides lock control for the tty monitor worker thread itself.
Definition: event_detect.h:424
void IdleDetectMonitorThread()
Method to instantiate the tty monitor thread.
Definition: event_detect.cpp:629
Monitor()
Constructor.
Definition: event_detect.cpp:85
bool IsInitialized() const
Provides a flag to indicate whether the monitor has been initialized. This is used in main in the app...
Definition: event_detect.cpp:210
void ProcessArgs() override
Private helper method used by ReadAndUpdateConfig. Note this is pure virtual. It must be implemented ...
Definition: event_detect.cpp:872
SharedMemoryTimestampExporter(const std::string &name)
Construct with the desired shared memory name.
Definition: event_detect.cpp:973
std::vector< fs::path > GetTtyDevices() const
Returns a copy of the vector of pts/tty paths. A copy is returned to avoid holding the lock on mtx_tt...
Definition: event_detect.cpp:489
~SharedMemoryTimestampExporter()
Destructor handles unmapping and potentially unlinking the shared memory.
Definition: event_detect.cpp:986
std::atomic< bool > m_initialized
This holds the flag as to whether the tty monitor has been initialized and is provided by the IsIniti...
Definition: event_detect.h:346
std::atomic< bool > m_interrupt_recorders
Atomic boolean that interrupts the recorder threads.
Definition: event_detect.h:139
bool CreateOrOpen(mode_t mode=0666)
Creates (if necessary) and opens the shared memory segment, sets its size (to sizeof(int64_t[2])), and maps it for writing. Must be called before UpdateTimestamps or IsInitialized.
Definition: event_detect.cpp:991
std::atomic< int64_t > m_last_idle_detect_active_time
Atomic that holds the overall last active time across all of the monitored pts/ttys.
Definition: event_detect.h:429
std::mutex mtx_event_recorder_threads
This provides lock control for the recorder worker threads themselves.
Definition: event_detect.h:225
std::vector< fs::path > m_event_device_paths
Holds the paths of the input event devices to monitor.
Definition: event_detect.h:108
std::vector< fs::path > m_tty_device_paths
Holds the device paths of the monitored pts/ttys. Note that this is duplicative of information in the...
Definition: event_detect.h:330
The Monitor class provides the framework for monitoring event activity recorded by the EventRecorders...
Definition: event_detect.h:27
std::thread m_idle_detect_monitor_thread
Holds the actual idle_detect monitor thread.
Definition: event_detect.h:362
Tty(const fs::path &tty_device_path)
Parameterized constructor.
Definition: event_detect.cpp:615
std::mutex mtx_shmem
This protects against multiple threads in the event_detect process from simultaneously accessing and ...
Definition: event_detect.h:514
std::atomic< bool > m_interrupt_idle_detect_monitor
Atomic boolean that interrupts the idle_detect monitor thread.
Definition: event_detect.h:372
std::mutex mtx_event_recorder
This is the mutex member that provides lock control for the individual event recorder.
Definition: event_detect.h:187
std::thread m_monitor_thread
Holds the actual monitor thread.
Definition: event_detect.h:33
void UpdateTtyDevices()
Initializes/Updates the pts/tty device paths to monitor.
Definition: event_detect.cpp:496
std::mutex mtx_tty_monitor_thread
This provides lock control for the tty monitor worker thread itself.
Definition: event_detect.h:324
Definition: event_detect.h:349
IdleDetectMonitor()
Constructor.
Definition: event_detect.cpp:623
State GetState() const
Returns the state of the idle monitor. This is NORMAL, FORCED_ACTIVE or FORCED_IDLE.
Definition: event_detect.cpp:838
std::mutex mtx_idle_detect_monitor
This is the mutex member that provides lock control for the tty monitor object. This is used to ensur...
Definition: event_detect.h:419
std::vector< std::shared_ptr< EventRecorder > > & GetEventRecorders()
Returns a reference to the event recorder objects thread pool.
Definition: event_detect.cpp:312
std::atomic< bool > m_initialized
This holds the flag as to whether the tty monitor has been initialized and is provided by the IsIniti...
Definition: event_detect.h:443
void UpdateEventDevices()
This calls the private method EnumerateEventDevices() and updates the m_event_device_paths private me...
Definition: event_detect.cpp:294
static std::vector< fs::path > EnumerateEventDevices()
This is a private method to determine the input event devices to monitor. In particular we only want ...
Definition: event_detect.cpp:220