Browse Source

Updated for compatibility with GNU++11 and 32bit mingw

wx
wombat 6 years ago
parent
commit
bec780b987
4 changed files with 116 additions and 112 deletions
  1. 63
    62
      networking.cpp
  2. 1
    0
      onetimepad.cpp
  3. 48
    47
      threading.hpp
  4. 4
    3
      timing.cpp

+ 63
- 62
networking.cpp View File

//// Platform Specific Stuff /////////////////////////////////////////////////// //// Platform Specific Stuff ///////////////////////////////////////////////////


#if defined(WIN32) || defined(WIN64) #if defined(WIN32) || defined(WIN64)
#include "winerror.h"


//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
//// Being Windows specific code //// Being Windows specific code
return NULL; // non blocking mode so we return return NULL; // non blocking mode so we return
} // NULL when we see them. } // NULL when we see them.
} }
// Set SO_NOSIGPIPE if needed
// Set SO_NOSIGPIPE if needed if( // On some systems we may have to
0 != SO_NOSIGPIPE && // use SO_NOSIPIPE but if they offer
if( // On some systems we may have to 0 == MSG_NOSIGNAL // MSG_NOSIGNAL we prefer that instead.
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.
int TurnedOn = 1; // Prepare to turn this option on. setsockopt(
int result = // Set SO_NOSIGPIPE. NewHandle,
setsockopt( SOL_SOCKET,
NewHandle, SO_NOSIGPIPE,
SOL_SOCKET, (char*) &TurnedOn,
SO_NOSIGPIPE, sizeof(TurnedOn));
(char*) &TurnedOn, if(0 > result) { // If there was an error then
sizeof(TurnedOn)); LastError = Network.getLastError(); // Capture the error information
Network.closeSocket(NewHandle); // close the handle (avoid leaks)
if(0 > result) { // If there was an error then throw Networking::SocketSetSockOptError( // and throw a descriptive exception.
LastError = Network.getLastError(); // Capture the error information Network.DescriptiveError(
Network.closeSocket(NewHandle); // close the handle (avoid leaks) "TCPListener::acceptClient().setsockopt(SO_NOSIGPIPE)", LastError));
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. // If things have gone well we can do what we came for.


if(0 > size) // Watch out for bad sizes. if(0 > size) // Watch out for bad sizes.
throw Networking::SocketWriteError("TCPClient::transmit() 0 > size!"); throw Networking::SocketWriteError("TCPClient::transmit() 0 > size!");


LastError = 0; // No errors yet. LastError = 0; // No errors yet.
int ByteCount = 0; // No bytes sent yet this pass. int ByteCount = 0; // No bytes sent yet this pass.
ByteCount = send(Handle, bfr, size, MSG_NOSIGNAL); // Try to send and capture the count. ByteCount = send(Handle, bfr, size, MSG_NOSIGNAL); // Try to send and capture the count.
LastError = Network.getLastError(); // Grab any error code. LastError = Network.getLastError(); // Grab any error code.
bool AnErrorOccurred = (0 > ByteCount); // How to know if an error occurred.
bool AnErrorOccurred = (0 > ByteCount); // How to know if an error occurred. const int NoBytesSent = 0; // This is our "Would Block" result.
const int NoBytesSent = 0; // This is our "Would Block" result.
if(AnErrorOccurred) { // If there was an error check it out. if(AnErrorOccurred) { // If there was an error check it out.
if(Network.WouldBlock(LastError)) { // If the error was "Would Block" then if(Network.WouldBlock(LastError)) { // If the error was "Would Block" then
return NoBytesSent; // return no bytes sent (try again). return NoBytesSent; // return no bytes sent (try again).
"TCPClient::transmit().send()", LastError)); "TCPClient::transmit().send()", LastError));
} }
} }
return ByteCount; // Usually: return the sent byte count. return ByteCount; // Usually: return the sent byte count.
} }


LastError = 0; // Clear our LastError value. LastError = 0; // Clear our LastError value.
bool SuccessFlag = true; // Begin optimistically. bool SuccessFlag = true; // Begin optimistically.


// Set Socket Options // Set Socket Options
if(!OpenStage1Complete) { // If we haven't done this yet: 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 ReuseAddress_Flag = (ReuseAddress? 1:0); // Setup an appropriate integer flag.
int result = // Set SO_REUSEADDR before bind(). int result = // Set SO_REUSEADDR before bind().
setsockopt( setsockopt(
Network.DescriptiveError( Network.DescriptiveError(
"TCPHost::open().setsockopt(SO_REUSEADDR)", LastError)); "TCPHost::open().setsockopt(SO_REUSEADDR)", LastError));
} }
// Set SO_NOSIGPIPE if needed
// Set SO_NOSIGPIPE if needed if( // On some systems we may have to
0 != SO_NOSIGPIPE && // use SO_NOSIPIPE but if they offer
if( // On some systems we may have to 0 == MSG_NOSIGNAL // MSG_NOSIGNAL we prefer that instead.
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.
int TurnedOn = 1; // Prepare to turn this option on. setsockopt(
int result = // Set SO_NOSIGPIPE. Handle,
setsockopt( SOL_SOCKET,
Handle, SO_NOSIGPIPE,
SOL_SOCKET, (char*) &TurnedOn,
SO_NOSIGPIPE, sizeof(TurnedOn));
(char*) &TurnedOn, if(0 > result) { // If there was an error then
sizeof(TurnedOn)); SuccessFlag = false; // we did not succeed.
LastError = Network.getLastError(); // Capture the error information and
if(0 > result) { // If there was an error then throw Networking::SocketSetSockOptError( // throw.
SuccessFlag = false; // we did not succeed. Network.DescriptiveError(
LastError = Network.getLastError(); // Capture the error information and "TCPHost::open().setsockopt(SO_NOSIGPIPE)", LastError));
throw Networking::SocketSetSockOptError( // throw. }
Network.DescriptiveError( }
"TCPHost::open().setsockopt(SO_NOSIGPIPE)", LastError));
}
}
OpenStage1Complete = true; // Skip this section from now on. OpenStage1Complete = true; // Skip this section from now on.
} // Done with stage 1. } // Done with stage 1.



+ 1
- 0
onetimepad.cpp View File



//// WIN32 Strong Entropy Source == CryptGenRandom() /////////////////////////// //// WIN32 Strong Entropy Source == CryptGenRandom() ///////////////////////////


#include <winsock2.h>
#include <windows.h> #include <windows.h>
#include <wincrypt.h> #include <wincrypt.h>



+ 48
- 47
threading.hpp View File

#include <set> #include <set>
#include <vector> #include <vector>
#include <string> #include <string>
#include <queue> #include <queue>
#include "faults.hpp" #include "faults.hpp"


using namespace std; using namespace std;


Pointer(P), Pointer(P),
Type(&T), Type(&T),
State(&S), State(&S),
Name(N), Name(N),
isRunning(R), isRunning(R),
isBad(B), isBad(B),
Fault(F) Fault(F)
isRunning = Right.isRunning; isRunning = Right.isRunning;
isBad = Right.isBad; isBad = Right.isBad;
Fault = Right.Fault; Fault = Right.Fault;
Name = Right.Name; Name = Right.Name;
return *this; return *this;
} }


// When in WIN32 land... // When in WIN32 land...
// Remember to compile (on GNU anyway) with -mthreads // Remember to compile (on GNU anyway) with -mthreads


#include <winsock2.h>
#include <windows.h> #include <windows.h>
#include <process.h> #include <process.h>




// End Thread Manager // End Thread Manager
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////// // A ProductionQueue is a templated, thread safe mechanism for implementing
// A ProductionQueue is a templated, thread safe mechanism for implementing // a producer/consumer relationship. The objects in the queue should be simple
// 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
// data so that they can be created, destroyed, and copied without trouble. Put // another way - the objects in the ProductionQueue should be lightweight
// another way - the objects in the ProductionQueue should be lightweight // handles for other things. Those things should be created and destroyed
// handles for other things. Those things should be created and destroyed // elsewhere.
// elsewhere. template<typename T> // Templatized
class ProductionQueue { // Production Queue Class
template<typename T> // Templatized private:
class ProductionQueue { // Production Queue Class Mutex myMutex; // Contains a mutex and
private: volatile unsigned int LatestSize; // a volatile (blinking light) size
Mutex myMutex; // Contains a mutex and ProductionGateway myGateway; // integrated with a production
volatile unsigned int LatestSize; // a volatile (blinking light) size queue<T> myQueue; // gateway and a queue.
ProductionGateway myGateway; // integrated with a production public:
queue<T> myQueue; // gateway and a queue. ProductionQueue() : LatestSize(0) {} // The size always starts at zero.
T take() { // To consume a queued object
public: myGateway.consume(); // we wait on the production gateway
ProductionQueue() : LatestSize(0) {} // The size always starts at zero. ScopeMutex OneAtATimePlease(myMutex); // and when we get through we lock
T O = myQueue.front(); // the mutext, take the object on the
T take() { // To consume a queued object myQueue.pop(); // front of the queue, pop it out,
myGateway.consume(); // we wait on the production gateway LatestSize = myQueue.size(); // and rest our size (blinking light).
ScopeMutex OneAtATimePlease(myMutex); // and when we get through we lock return O; // Then return the object we got.
T O = myQueue.front(); // the mutext, take the object on the }
myQueue.pop(); // front of the queue, pop it out, void give(T O) { // To produce a queued object
LatestSize = myQueue.size(); // and rest our size (blinking light). ScopeMutex OneAtATimePlease(myMutex); // we wait on the mutex. When we
return O; // Then return the object we got. 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.
void give(T O) { // To produce a queued object } // When we're done it can be grabbed.
ScopeMutex OneAtATimePlease(myMutex); // we wait on the mutex. When we unsigned int size() { // To check the size we look at
myQueue.push(O); // get through we push our object return LatestSize; // the blinking light.
LatestSize = myQueue.size(); // into the queue, reset our size }
myGateway.produce(); // indicator and tell the gateway. };
} // When we're done it can be grabbed. // End Production Queue
////////////////////////////////////////////////////////////////////////////////
unsigned int size() { // To check the size we look at
return LatestSize; // the blinking light.
}
};
// End Production Queue
////////////////////////////////////////////////////////////////////////////////


#endif #endif



+ 4
- 3
timing.cpp View File

// Platform Specific Includes ////////////////////////////////////////////////// // Platform Specific Includes //////////////////////////////////////////////////


#if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64) #if defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)
#include <winsock2.h>
#include <windows.h> #include <windows.h>
#endif #endif


if(x < MinimumSleeperTime || if(x < MinimumSleeperTime ||
x > MaximumSleeperTime) // If it's not a good time value x > MaximumSleeperTime) // If it's not a good time value
throw BadSleeperValue(); // then throw the exception. 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. return MillisecondsToSleep; // Return the set value.
} }


// a natural spiral. // a natural spiral.
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////


PollTimer::PollTimer(int Nom, int Max) : PollTimer::PollTimer(int Nom, int Max) :
NominalPollTime(MinimumSleeperTime), NominalPollTime(MinimumSleeperTime),
MaximumPollTime(MinimumSleeperTime) { // Construction requires a MaximumPollTime(MinimumSleeperTime) { // Construction requires a
setNominalPollTime(Nom); // nominal delay to use and setNominalPollTime(Nom); // nominal delay to use and
setMaximumPollTime(Max); // a maximum delay to allow. setMaximumPollTime(Max); // a maximum delay to allow.

Loading…
Cancel
Save