@@ -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. |