| @@ -29,6 +29,7 @@ Networking Network; | |||
| //// Platform Specific Stuff /////////////////////////////////////////////////// | |||
| #if defined(WIN32) || defined(WIN64) | |||
| #include "winerror.h" | |||
| //////////////////////////////////////////////////////////////////////////////// | |||
| //// Being Windows specific code | |||
| @@ -393,30 +394,30 @@ TCPClient* TCPListener::acceptClient() { | |||
| return NULL; // non blocking mode so we return | |||
| } // NULL when we see them. | |||
| } | |||
| // Set SO_NOSIGPIPE if needed | |||
| if( // On some systems we may have to | |||
| 0 != SO_NOSIGPIPE && // use SO_NOSIPIPE but if they offer | |||
| 0 == MSG_NOSIGNAL // MSG_NOSIGNAL we prefer that instead. | |||
| ) { | |||
| int TurnedOn = 1; // Prepare to turn this option on. | |||
| int result = // Set SO_NOSIGPIPE. | |||
| setsockopt( | |||
| NewHandle, | |||
| SOL_SOCKET, | |||
| SO_NOSIGPIPE, | |||
| (char*) &TurnedOn, | |||
| sizeof(TurnedOn)); | |||
| if(0 > result) { // If there was an error then | |||
| LastError = Network.getLastError(); // Capture the error information | |||
| Network.closeSocket(NewHandle); // close the handle (avoid leaks) | |||
| throw Networking::SocketSetSockOptError( // and throw a descriptive exception. | |||
| Network.DescriptiveError( | |||
| "TCPListener::acceptClient().setsockopt(SO_NOSIGPIPE)", LastError)); | |||
| } | |||
| } | |||
| // Set SO_NOSIGPIPE if needed | |||
| if( // On some systems we may have to | |||
| 0 != SO_NOSIGPIPE && // use SO_NOSIPIPE but if they offer | |||
| 0 == MSG_NOSIGNAL // MSG_NOSIGNAL we prefer that instead. | |||
| ) { | |||
| int TurnedOn = 1; // Prepare to turn this option on. | |||
| int result = // Set SO_NOSIGPIPE. | |||
| setsockopt( | |||
| NewHandle, | |||
| SOL_SOCKET, | |||
| SO_NOSIGPIPE, | |||
| (char*) &TurnedOn, | |||
| sizeof(TurnedOn)); | |||
| if(0 > result) { // If there was an error then | |||
| LastError = Network.getLastError(); // Capture the error information | |||
| Network.closeSocket(NewHandle); // close the handle (avoid leaks) | |||
| throw Networking::SocketSetSockOptError( // and throw a descriptive exception. | |||
| Network.DescriptiveError( | |||
| "TCPListener::acceptClient().setsockopt(SO_NOSIGPIPE)", LastError)); | |||
| } | |||
| } | |||
| // If things have gone well we can do what we came for. | |||
| @@ -433,14 +434,14 @@ int TCPClient::transmit(const char* bfr, int size) { | |||
| if(0 > size) // Watch out for bad sizes. | |||
| throw Networking::SocketWriteError("TCPClient::transmit() 0 > size!"); | |||
| LastError = 0; // No errors yet. | |||
| int ByteCount = 0; // No bytes sent yet this pass. | |||
| LastError = 0; // No errors yet. | |||
| int ByteCount = 0; // No bytes sent yet this pass. | |||
| ByteCount = send(Handle, bfr, size, MSG_NOSIGNAL); // Try to send and capture the count. | |||
| LastError = Network.getLastError(); // Grab any error code. | |||
| bool AnErrorOccurred = (0 > ByteCount); // How to know if an error occurred. | |||
| const int NoBytesSent = 0; // This is our "Would Block" result. | |||
| LastError = Network.getLastError(); // Grab any error code. | |||
| bool AnErrorOccurred = (0 > ByteCount); // How to know if an error occurred. | |||
| const int NoBytesSent = 0; // This is our "Would Block" result. | |||
| if(AnErrorOccurred) { // If there was an error check it out. | |||
| if(Network.WouldBlock(LastError)) { // If the error was "Would Block" then | |||
| return NoBytesSent; // return no bytes sent (try again). | |||
| @@ -450,7 +451,7 @@ int TCPClient::transmit(const char* bfr, int size) { | |||
| "TCPClient::transmit().send()", LastError)); | |||
| } | |||
| } | |||
| return ByteCount; // Usually: return the sent byte count. | |||
| } | |||
| @@ -544,12 +545,12 @@ void TCPHost::open() { | |||
| LastError = 0; // Clear our LastError value. | |||
| bool SuccessFlag = true; // Begin optimistically. | |||
| // Set Socket Options | |||
| // Set Socket Options | |||
| if(!OpenStage1Complete) { // If we haven't done this yet: | |||
| // Set SO_REUSEADDR if turned on | |||
| // Set SO_REUSEADDR if turned on | |||
| int ReuseAddress_Flag = (ReuseAddress? 1:0); // Setup an appropriate integer flag. | |||
| int result = // Set SO_REUSEADDR before bind(). | |||
| setsockopt( | |||
| @@ -566,31 +567,31 @@ void TCPHost::open() { | |||
| Network.DescriptiveError( | |||
| "TCPHost::open().setsockopt(SO_REUSEADDR)", LastError)); | |||
| } | |||
| // Set SO_NOSIGPIPE if needed | |||
| if( // On some systems we may have to | |||
| 0 != SO_NOSIGPIPE && // use SO_NOSIPIPE but if they offer | |||
| 0 == MSG_NOSIGNAL // MSG_NOSIGNAL we prefer that instead. | |||
| ) { | |||
| int TurnedOn = 1; // Prepare to turn this option on. | |||
| int result = // Set SO_NOSIGPIPE. | |||
| setsockopt( | |||
| Handle, | |||
| SOL_SOCKET, | |||
| SO_NOSIGPIPE, | |||
| (char*) &TurnedOn, | |||
| sizeof(TurnedOn)); | |||
| if(0 > result) { // If there was an error then | |||
| SuccessFlag = false; // we did not succeed. | |||
| LastError = Network.getLastError(); // Capture the error information and | |||
| throw Networking::SocketSetSockOptError( // throw. | |||
| Network.DescriptiveError( | |||
| "TCPHost::open().setsockopt(SO_NOSIGPIPE)", LastError)); | |||
| } | |||
| } | |||
| // Set SO_NOSIGPIPE if needed | |||
| if( // On some systems we may have to | |||
| 0 != SO_NOSIGPIPE && // use SO_NOSIPIPE but if they offer | |||
| 0 == MSG_NOSIGNAL // MSG_NOSIGNAL we prefer that instead. | |||
| ) { | |||
| int TurnedOn = 1; // Prepare to turn this option on. | |||
| int result = // Set SO_NOSIGPIPE. | |||
| setsockopt( | |||
| Handle, | |||
| SOL_SOCKET, | |||
| SO_NOSIGPIPE, | |||
| (char*) &TurnedOn, | |||
| sizeof(TurnedOn)); | |||
| if(0 > result) { // If there was an error then | |||
| SuccessFlag = false; // we did not succeed. | |||
| LastError = Network.getLastError(); // Capture the error information and | |||
| throw Networking::SocketSetSockOptError( // throw. | |||
| Network.DescriptiveError( | |||
| "TCPHost::open().setsockopt(SO_NOSIGPIPE)", LastError)); | |||
| } | |||
| } | |||
| OpenStage1Complete = true; // Skip this section from now on. | |||
| } // Done with stage 1. | |||
| @@ -26,6 +26,7 @@ class OneTimePad { | |||
| //// WIN32 Strong Entropy Source == CryptGenRandom() /////////////////////////// | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #include <wincrypt.h> | |||
| @@ -64,8 +64,8 @@ | |||
| #include <set> | |||
| #include <vector> | |||
| #include <string> | |||
| #include <queue> | |||
| #include "faults.hpp" | |||
| #include <queue> | |||
| #include "faults.hpp" | |||
| using namespace std; | |||
| @@ -120,7 +120,7 @@ class ThreadStatusRecord { | |||
| Pointer(P), | |||
| Type(&T), | |||
| State(&S), | |||
| Name(N), | |||
| Name(N), | |||
| isRunning(R), | |||
| isBad(B), | |||
| Fault(F) | |||
| @@ -133,7 +133,7 @@ class ThreadStatusRecord { | |||
| isRunning = Right.isRunning; | |||
| isBad = Right.isBad; | |||
| Fault = Right.Fault; | |||
| Name = Right.Name; | |||
| Name = Right.Name; | |||
| return *this; | |||
| } | |||
| @@ -165,6 +165,7 @@ typedef vector<ThreadStatusRecord> ThreadStatusReport; | |||
| // When in WIN32 land... | |||
| // Remember to compile (on GNU anyway) with -mthreads | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #include <process.h> | |||
| @@ -436,49 +437,49 @@ class ScopeThreadLock { | |||
| // End Thread Manager | |||
| //////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////// | |||
| // A ProductionQueue is a templated, thread safe mechanism for implementing | |||
| // a producer/consumer relationship. The objects in the queue should be simple | |||
| // data so that they can be created, destroyed, and copied without trouble. Put | |||
| // another way - the objects in the ProductionQueue should be lightweight | |||
| // handles for other things. Those things should be created and destroyed | |||
| // elsewhere. | |||
| template<typename T> // Templatized | |||
| class ProductionQueue { // Production Queue Class | |||
| private: | |||
| Mutex myMutex; // Contains a mutex and | |||
| volatile unsigned int LatestSize; // a volatile (blinking light) size | |||
| ProductionGateway myGateway; // integrated with a production | |||
| queue<T> myQueue; // gateway and a queue. | |||
| public: | |||
| ProductionQueue() : LatestSize(0) {} // The size always starts at zero. | |||
| T take() { // To consume a queued object | |||
| myGateway.consume(); // we wait on the production gateway | |||
| ScopeMutex OneAtATimePlease(myMutex); // and when we get through we lock | |||
| T O = myQueue.front(); // the mutext, take the object on the | |||
| myQueue.pop(); // front of the queue, pop it out, | |||
| LatestSize = myQueue.size(); // and rest our size (blinking light). | |||
| return O; // Then return the object we got. | |||
| } | |||
| void give(T O) { // To produce a queued object | |||
| ScopeMutex OneAtATimePlease(myMutex); // we wait on the mutex. When we | |||
| myQueue.push(O); // get through we push our object | |||
| LatestSize = myQueue.size(); // into the queue, reset our size | |||
| myGateway.produce(); // indicator and tell the gateway. | |||
| } // When we're done it can be grabbed. | |||
| unsigned int size() { // To check the size we look at | |||
| return LatestSize; // the blinking light. | |||
| } | |||
| }; | |||
| // End Production Queue | |||
| //////////////////////////////////////////////////////////////////////////////// | |||
| //////////////////////////////////////////////////////////////////////////////// | |||
| // A ProductionQueue is a templated, thread safe mechanism for implementing | |||
| // a producer/consumer relationship. The objects in the queue should be simple | |||
| // data so that they can be created, destroyed, and copied without trouble. Put | |||
| // another way - the objects in the ProductionQueue should be lightweight | |||
| // handles for other things. Those things should be created and destroyed | |||
| // elsewhere. | |||
| template<typename T> // Templatized | |||
| class ProductionQueue { // Production Queue Class | |||
| private: | |||
| Mutex myMutex; // Contains a mutex and | |||
| volatile unsigned int LatestSize; // a volatile (blinking light) size | |||
| ProductionGateway myGateway; // integrated with a production | |||
| queue<T> myQueue; // gateway and a queue. | |||
| public: | |||
| ProductionQueue() : LatestSize(0) {} // The size always starts at zero. | |||
| T take() { // To consume a queued object | |||
| myGateway.consume(); // we wait on the production gateway | |||
| ScopeMutex OneAtATimePlease(myMutex); // and when we get through we lock | |||
| T O = myQueue.front(); // the mutext, take the object on the | |||
| myQueue.pop(); // front of the queue, pop it out, | |||
| LatestSize = myQueue.size(); // and rest our size (blinking light). | |||
| return O; // Then return the object we got. | |||
| } | |||
| void give(T O) { // To produce a queued object | |||
| ScopeMutex OneAtATimePlease(myMutex); // we wait on the mutex. When we | |||
| myQueue.push(O); // get through we push our object | |||
| LatestSize = myQueue.size(); // into the queue, reset our size | |||
| myGateway.produce(); // indicator and tell the gateway. | |||
| } // When we're done it can be grabbed. | |||
| unsigned int size() { // To check the size we look at | |||
| return LatestSize; // the blinking light. | |||
| } | |||
| }; | |||
| // End Production Queue | |||
| //////////////////////////////////////////////////////////////////////////////// | |||
| #endif | |||
| @@ -28,6 +28,7 @@ | |||
| // Platform Specific Includes ////////////////////////////////////////////////// | |||
| #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) | |||
| #include <winsock2.h> | |||
| #include <windows.h> | |||
| #endif | |||
| @@ -92,7 +93,7 @@ int Sleeper::setMillisecondsToSleep(int x) { | |||
| if(x < MinimumSleeperTime || | |||
| x > MaximumSleeperTime) // If it's not a good time value | |||
| throw BadSleeperValue(); // then throw the exception. | |||
| MillisecondsToSleep = x; // If it is good - set it. | |||
| MillisecondsToSleep = x; // If it is good - set it. | |||
| return MillisecondsToSleep; // Return the set value. | |||
| } | |||
| @@ -129,8 +130,8 @@ void Sleeper::operator()() { | |||
| // a natural spiral. | |||
| /////////////////////////////////////////////////////////////////////////////// | |||
| PollTimer::PollTimer(int Nom, int Max) : | |||
| NominalPollTime(MinimumSleeperTime), | |||
| PollTimer::PollTimer(int Nom, int Max) : | |||
| NominalPollTime(MinimumSleeperTime), | |||
| MaximumPollTime(MinimumSleeperTime) { // Construction requires a | |||
| setNominalPollTime(Nom); // nominal delay to use and | |||
| setMaximumPollTime(Max); // a maximum delay to allow. | |||