You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.cpp 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // SNFServer/main.cpp
  2. //
  3. // (C) Copyright 2006 - 2009 ARM Research Labs, LLC
  4. // See www.armresearch.com for the copyright terms.
  5. //
  6. #include <sys/types.h>
  7. #include <sys/stat.h>
  8. #include <ctime>
  9. #include <cstring>
  10. #include <iostream>
  11. #include <iomanip>
  12. #include <fstream>
  13. #include <sstream>
  14. #include <string>
  15. #include <queue>
  16. #include <cmath>
  17. #include <exception>
  18. #include <stdexcept>
  19. #include "unistd.h"
  20. #include "../CodeDweller/timing.hpp"
  21. #include "../CodeDweller/threading.hpp"
  22. #include "../CodeDweller/networking.hpp"
  23. #include "../SNFMulti/SNFMulti.hpp"
  24. #include "../SNFMulti/snf_xci.hpp"
  25. #include "../SNFMulti/snf_sync.hpp"
  26. //#include "config.h"
  27. // temporary - proving base64codec
  28. #include "../CodeDweller/base64codec.hpp"
  29. //#include "../nvwa-0.6/nvwa/debug_new.h"
  30. using namespace std; // Introduce standard namespace.
  31. const char* SERVER_VERSION_INFO = "SNF Server Version 3.2.0 Build: " __DATE__ " " __TIME__;
  32. static const string XCIShutdownResponse =
  33. "<snf><xci><server><response message=\'shutdown in progress\' code=\'0\'/></server></xci></snf>\n";
  34. class XCIShutdownWatcher : public snfXCIServerCommandHandler { // Shutdown watcher.
  35. public:
  36. XCIShutdownWatcher():TimeToStop(false){} // Construct with shutdown flag false.
  37. bool TimeToStop; // Here is the flag.
  38. string processXCIRequest(snf_xci& X) { // Here is how we process requests.
  39. if(0 == X.xci_server_command.find("shutdown")) { // If we find shutdown then
  40. TimeToStop = true; // set the shutdown flag
  41. return XCIShutdownResponse; // and let them know we got it.
  42. } // If we get some other request
  43. return XCIErrorResponse; // return the error response.
  44. }
  45. };
  46. // Thread Status Analysis For Debugging.
  47. void ThreadStatusToCout() { // Produce a thread status list.
  48. ThreadStatusReport R = Threads.StatusReport(); // Get a report from Threads.
  49. cout << endl; // Break the line.
  50. for(
  51. ThreadStatusReport::iterator iR = R.begin(); // Loop through the report.
  52. iR != R.end(); iR++
  53. ) {
  54. ThreadStatusRecord& S = (*iR); // Take each status report and
  55. cout // send it to cout on it's own line.
  56. << S.getName() << " (" << S.getPointer() << "), "
  57. << S.getType().Name << ", "
  58. << S.getState().Name << ", "
  59. << ((S.getRunning()) ? "Running, " : "Not Running, ")
  60. << ((S.getBad()) ? "Broken, " : "Ok, ")
  61. << S.getFault()
  62. << endl;
  63. }
  64. cout << endl; // Leave a blank line at the end.
  65. }
  66. // Here in the main thread is where we get executive tasks done.
  67. int go(int argc, char* argv[]) { //// go() stands in for main(). main() catches any unhandled exceptions.
  68. // Check for debug mode.
  69. bool DebugMode = false; // This will be our debug mode.
  70. string argv0(argv[0]); // Capture how we were called.
  71. if(
  72. string::npos != argv0.find("Debug") || // If we find "Debug" or
  73. string::npos != argv0.find("debug") // "debug" in our command path
  74. ) { // then we are in DebugMode.
  75. DebugMode = true; // Set the flag and tell the
  76. cout << "Debug Mode" << endl; // watchers.
  77. }
  78. // DebugMode = true; // Force it when needed.
  79. // Announce Version / Build Info.
  80. cout << SERVER_VERSION_INFO << endl; // Shout out our version.
  81. cout << SNF_ENGINE_VERSION << endl; // Shout out the engine version.
  82. // Sanity checks before we get going.
  83. if(2 != argc) { // Check the command line args.
  84. cout << "Use: SNFServer <path-to-config-file>" << endl; // If wrong, say how we work.
  85. return 0;
  86. }
  87. if(0 != access(argv[1], R_OK)) { // Check the config file path.
  88. cout << "Can't read " << argv[1] << endl; // If it's not accessible, punt.
  89. return 0;
  90. }
  91. cout << "Launching with " << argv[1] << endl; // Tell them we're going.
  92. snf_RulebaseHandler MyRulebase; // Create a rulebase manager.
  93. MyRulebase.PlatformVersion(SERVER_VERSION_INFO); // Set the Platform version string.
  94. XCIShutdownWatcher ShutdownWatcher; // Make a server shutdown processor
  95. MyRulebase.XCIServerCommandHandler(ShutdownWatcher); // and register it with the engine.
  96. MyRulebase.open(argv[1], "", ""); // Open a configured rulebase.
  97. Sleeper WaitATic(1000); // Learn to wait a second.
  98. cout << "Running." << endl << endl; // Tell them we're running.
  99. char Tic = '\\'; // Tic/Toc indicator.
  100. while(false == ShutdownWatcher.TimeToStop) { // While running, update the screen.
  101. WaitATic(); // One second between updates.
  102. // Animate the Tick/Toc Indicator
  103. switch(Tic) {
  104. case '\\': Tic = '|'; break;
  105. case '|': Tic = '/'; break;
  106. case '/': Tic = '-'; break;
  107. default: Tic = '\\'; break;
  108. }
  109. // Format and output the screen update. At the end post a \r so that
  110. // the line appears to update in place.
  111. cout
  112. << "M/min: " << setw(4) << (int) MyRulebase.MyLOGmgr.MessagesPerMinute() << " "
  113. << "SP: " << setw(6) << setprecision(2) << setiosflags(ios::fixed) <<
  114. ((0 < MyRulebase.MyLOGmgr.MessagesPerMinute()) ?
  115. (100 * MyRulebase.MyLOGmgr.SpamPerMinute() / MyRulebase.MyLOGmgr.MessagesPerMinute()) : 0.0) << "% "
  116. << "LR:" << setw(7) << MyRulebase.MyLOGmgr.LatestRuleID()
  117. << " ["
  118. << MyRulebase.MyXCImgr.pollClientCount() << "/"
  119. << MyRulebase.MyXCImgr.pollLoopCount() << " "
  120. << Tic << " " << (int) MyRulebase.MyXCImgr.TotalQueue() << "] "
  121. << "W:" << (int) MyRulebase.MyLOGmgr.WhitePerMinute() << " "
  122. << "C:" << (int) MyRulebase.MyLOGmgr.CautionPerMinute() << " "
  123. << "B:" << (int) MyRulebase.MyLOGmgr.BlackPerMinute() << " "
  124. << "T:" << (int) MyRulebase.MyLOGmgr.TruncatePerMinute() << " "
  125. << "S:" << (int) MyRulebase.MyLOGmgr.SamplePerMinute()
  126. << " \r" << flush;
  127. if(DebugMode) ThreadStatusToCout(); // Debug? Show Thread Status Report.
  128. }
  129. cout << endl << endl << "Shutdown Received." << endl;
  130. // When this loop fails it is time to shut down.
  131. // All the rest happens via XCI now.
  132. cout << "Closing Rulebase Handler..." << endl;
  133. MyRulebase.close();
  134. // All done...
  135. cout << "Bye bye." << endl;
  136. return 0;
  137. }
  138. /*
  139. class DebugExceptionHandler { // Hand wrapper for exception handler.
  140. public:
  141. DebugExceptionHandler() {
  142. LoadLibrary("exchndl.dll");
  143. }
  144. };
  145. static DebugExceptionHandler TheDebugExceptionHandler; // Global exception handler.
  146. */
  147. int main(int argc, char* argv[]) {
  148. try {
  149. go(argc, argv);
  150. }
  151. catch(exception& e) {
  152. cout << "Unhandled Exception: " << e.what() << " Thrown!" << endl;
  153. }
  154. catch(...) {
  155. cout << "Unknown, Unhandled Exception Discovered!" << endl;
  156. }
  157. return 0;
  158. }