// tcp_watchdog.hpp
// Copyright (C) 2006 - 2009 MicroNeil Research Corporation
// Watchdog timer for TCP connections.
// Closes the connection if it times out.
// Theoretically, when a socet closes, anything blocked on that socket
// will receive an exception and will deal with that appropriately by
// stopping what it is doing... Can't work on a closed socket ;-)
// This allows blocking sockets to be used safely in that the application
// won't "hang" on a stopped / broken socket.

#ifndef tcp_watchdog_included
#define tcp_watchdog_included

#include "timing.hpp"
#include "threading.hpp"
#include "networking.hpp"

class TCPWatchdog : private Thread {
  private:

    Socket& MySocket;                                                           // Socket to watch.
    Timeout MyTimeout;                                                          // Timeout value.

    void myTask();                                                              // Watchdog task.

    volatile bool StillAlive;                                                   // True if we're watching.

  public:

    TCPWatchdog(Socket& SocketToWatch, int Milliseconds);                       // Create with a socket and a time limit.
    ~TCPWatchdog();                                                             // Destroy by stopping the task.

    void reset();                                                               // Reset the watchdog - everything is ok.
    void reset(int Milliseconds);                                               // Reset the watchdog - use a new time.
    void stop();                                                                // Stop the watchdog - all done here.

    const static ThreadType Type;                                               // The thread's type.

    const static ThreadState Watching;                                          // State when waiting to fire.
    const static ThreadState KilledSocket;                                      // Killed The Socket.
    const static ThreadState LiveAndLetBe;                                      // Shutdown without incident.

};

#endif
