#ifndef APPLICATION_H /*************************************************************************** -*- c++ -*- **/
#define APPLICATION_H

/****************************************************************************************************************/

#include "object.h"
#include <sys/types.h>
#include <signal.h>
#include <time.h>

/****************************************************************************************************************/

class Application : public Object {

public: // Construction
  Application();
  virtual ~Application();

public:
  const struct timeval &checkpoint(void) { return m_checkpoint; }

public:
  bool hasPendingEvents(int timeout);
  void processEvents(void);
  int exec(void);
  void exit(int code);

public: // SIGCHLD handler
  void reapChild(void);
  void mapChildProcess(pid_t pid) { mapChildProcess(0, pid); }
  void mapChildProcess(Object *owner, pid_t pid);
  void unmapChildProcesses(Object *owner);

public:
  void deleteLater(Object *obj);

public:
  static void installDefaultSignalHandler(void);

public:
  static void timeStamp(struct timeval *tv); // Returns a monotonic rising time stamp

private:
  bool tryChildMap(pid_t pid, int status);
  void removeDone(pid_t pid);
  void tryDone(void);
  void doProcessEvents(bool reap_children);

private:
  unsigned long m_exit_requested[2];
  int m_exit_code;
  int m_errcnt; // Number of errors happened in select

  struct {
    pid_t pid;
    Object *owner;
  } m_child_map[64]; // TODO: Could be turned into a hash someday, if it's worth it...

  struct {
    pid_t pid;
    int status;
  } m_childs_done[64]; // Childs that died before the child_map could be initialized

  volatile int m_childs_done_index;

  Object *m_reaper;

  struct timeval m_checkpoint;

  bool m_has_events;

  // Race catcher
  bool m_run_loop;
};

/****************************************************************************************************************/

extern Application *App;

/****************************************************************************************************************/

#endif
