// tcp_watchdog.cpp // Copyright (C) 2006 - 2009 MicroNeil Research Corporation // See tcp_watchdog.hpp for details. #include "tcp_watchdog.hpp" const ThreadType TCPWatchdog::Type("TCPWatchdog"); // Thread type. const ThreadState TCPWatchdog::Watching("Watching"); // State when waiting to fire. const ThreadState TCPWatchdog::KilledSocket("KilledSocket"); // Killed The Socket. const ThreadState TCPWatchdog::LiveAndLetBe("LiveAndLetBe"); // Shutdown without incident. TCPWatchdog::TCPWatchdog(Socket& SocketToWatch, int Milliseconds) : // Construct with MySocket(SocketToWatch), // a socket to watch, MyTimeout(Milliseconds), // a time limit, StillAlive(true) { // and a true alive flag. run(); // Run the thread. } TCPWatchdog::~TCPWatchdog() { // When we go away, we stop(); // need to stop. } void TCPWatchdog::reset() { // We can be reset by MyTimeout.restart(); // restarting the timeout. } void TCPWatchdog::reset(int Milliseconds) { // We can also be reset by MyTimeout.setDuration(Milliseconds); // setting a new timeout and MyTimeout.restart(); // starting fresh. } void TCPWatchdog::stop() { // If we are stopped then MyTimeout.restart(); // we restart the timeout for safety, if(StillAlive) { // IF we're alive when we get here CurrentThreadState(LiveAndLetBe); // we are "calling off the dog". } StillAlive = false; // falsify our alive flag, and join(); // wait for our thread to end. } void TCPWatchdog::myTask() { // This is the job we do. const int OneSecond = 1000; // One second in milliseconds. Sleeper WaitATic(OneSecond); // Set up a one second sleeper. while(StillAlive) { // While we are alive, CurrentThreadState(Watching); // we are watching the clock. WaitATic(); // Every second or so we will if(MyTimeout.isExpired()) { // check to see if we've expired. CurrentThreadState(KilledSocket); // If the clock expires - we kill! StillAlive = false; // To do that, we turn ourselves MySocket.close(); // off and close the socket. } } }