選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

JobPool.cpp 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. // SNF4CGP/JobPool.cpp
  2. // Copyright (C) 2009 ARM Research Labs, LLC.
  3. // See www.armresearch.com for more information.
  4. #include "JobPool.hpp"
  5. #include "Command.hpp"
  6. #include "ScannerPool.hpp"
  7. #include "OutputProcessor.hpp"
  8. #include "../SNFMulti/SNFMulti.hpp"
  9. #include "../CodeDweller/threading.hpp"
  10. #include "../CodeDweller/faults.hpp"
  11. #include <iostream>
  12. #include <vector>
  13. using namespace std;
  14. //// Tuning Constants //////////////////////////////////////////////////////////
  15. const int ReadBufferSize = snf_ScanHorizon;
  16. const int StringReserveSize = 2048;
  17. //// Job ///////////////////////////////////////////////////////////////////////
  18. void Job::emitCommentPrefix() {
  19. }
  20. void Job::emitComment(string Comment) {
  21. ostringstream O;
  22. O << "* " << Comment << endl;
  23. OutputBuffer.append(O.str());
  24. }
  25. void Job::emitResponsePrevix() {
  26. }
  27. void Job::emitOK() {
  28. }
  29. void Job::emitINTF() {
  30. }
  31. void Job::emitFAIL() {
  32. }
  33. void Job::emitADDHEADER(string Headers) {
  34. }
  35. void Job::emitERROR() {
  36. }
  37. void Job::emitDISCARD() {
  38. }
  39. void Job::finalize() {
  40. Output.outputJob(*this);
  41. }
  42. void Job::doWakeUp() {
  43. emitComment("SNF4CGP Waking Up");
  44. emitComment(CurrentCommand.Data);
  45. }
  46. void Job::doINTF() {
  47. }
  48. void Job::doFAIL() {
  49. }
  50. void Job::doFILE() {
  51. }
  52. void Job::readTopOfMessage(ifstream& Reader) {
  53. }
  54. void Job::doRead() {
  55. }
  56. void Job::doScan() {
  57. }
  58. void Job::doAction() {
  59. }
  60. void Job::doBypass() {
  61. }
  62. void Job::doAllow() {
  63. }
  64. void Job::doReject() {
  65. }
  66. void Job::doDelete() {
  67. }
  68. void Job::moveMessageToHoldPath(ifstream& Reader) {
  69. }
  70. void Job::doHold() {
  71. }
  72. Job::Job(ScannerPool& S, OutputProcessor& O) : // Construct with important links.
  73. Scanners(S),
  74. Output(O),
  75. ScanResultCode(0),
  76. ReadLength(0) { // Minimize heap thrashing.
  77. OutputBuffer.reserve(StringReserveSize);
  78. HeadersToInject.reserve(StringReserveSize);
  79. ReadBuffer.reserve(ReadBufferSize);
  80. }
  81. Job::~Job() { // Cleanup when destructing.
  82. try { clear(); }
  83. catch(...) {}
  84. }
  85. void Job::clear() { // Cleanup for the next command.
  86. CurrentCommand.clear();
  87. ScanResultCode = 0;
  88. OutputBuffer.clear();
  89. HeadersToInject.clear();
  90. MessageMoveFilePath.clear();
  91. ReadBuffer.clear();
  92. ReadLength = 0;
  93. }
  94. LogicFault FaultIfQuitGetsHere("Job::setCommand() Fault(Command::QUIT == C.Type)");
  95. void Job::setCommand(Command& C) { // Assign a command for this job.
  96. FaultIfQuitGetsHere(Command::QUIT == C.Type);
  97. CurrentCommand = C;
  98. }
  99. void Job::doIt() { // Get the job done.
  100. switch(CurrentCommand.Type) {
  101. case Command::WAKE: { doWakeUp(); break; }
  102. case Command::INTF: { doINTF(); break; }
  103. case Command::FILE: { doFILE(); break; }
  104. default: { doFAIL(); break; }
  105. }
  106. finalize();
  107. }
  108. string& Job::Responses() { // Read the job's report.
  109. return OutputBuffer;
  110. }
  111. //// JobPool ///////////////////////////////////////////////////////////////////
  112. JobPool::JobPool() : // Simple constructor.
  113. Output_(0),
  114. Scanners_(new ScannerPool()),
  115. AllocatedJobs(0),
  116. Started(false) {
  117. }
  118. JobPool::~JobPool() { // Clean up on the way out.
  119. try {
  120. stop();
  121. Output_ = 0;
  122. if(Scanners_) delete Scanners_;
  123. Scanners_ = 0;
  124. }
  125. catch(...) {}
  126. }
  127. RuntimeCheck CheckForValidOutputPool("JobPool::Output() Check(0 != Output_)");
  128. OutputProcessor& JobPool::Output() {
  129. CheckForValidOutputPool(0 != Output_);
  130. return (*Output_);
  131. }
  132. RuntimeCheck CheckForValidScannerPool("JobPool::Scanners() Check(0 != Scanners_)");
  133. ScannerPool& JobPool::Scanners() {
  134. CheckForValidScannerPool(0 != Scanners_);
  135. return (*Scanners_);
  136. }
  137. // Watch out -- Initializing the JobPool also means starting up SNFMulti and
  138. // the ScannerPool.
  139. void JobPool::init(string Configuration, OutputProcessor& O) { // Initialize the JobPool.
  140. Output_ = &O;
  141. Scanners().init(Configuration);
  142. ScopeMutex Busy(AllocationMutex);
  143. Job* FirstJob = makeJob();
  144. Jobs.give(FirstJob);
  145. Started = true;
  146. }
  147. Job* JobPool::makeJob() { // Create and count a Job.
  148. Job* NewJob = new Job(Scanners(), Output());
  149. ++AllocatedJobs;
  150. return NewJob;
  151. }
  152. LogicCheck CheckGrabJobsOnlyWhenStarted("JobPool::grab() Check(Started)");
  153. RuntimeCheck CheckForValidGrabbedJob("JobPool::grab() Check(0 != GrabbedJob)");
  154. Job& JobPool::grab() { // Grab a job (prefer from the pool).
  155. ScopeMutex Busy(AllocationMutex);
  156. CheckGrabJobsOnlyWhenStarted(Started);
  157. Job* GrabbedJob = 0;
  158. if(0 < Jobs.size()) GrabbedJob = Jobs.take(); // Prefer jobs from the pool.
  159. else GrabbedJob = makeJob(); // Make new ones if needed.
  160. CheckForValidGrabbedJob(0 != GrabbedJob);
  161. return (*GrabbedJob);
  162. }
  163. void JobPool::drop(Job& J) { // Drop a job into the pool.
  164. Jobs.give(&J);
  165. }
  166. void JobPool::killJobFromPool() { // Kill and count a Job from the pool.
  167. Job* JobToKill = 0;
  168. JobToKill = Jobs.take();
  169. delete JobToKill;
  170. --AllocatedJobs;
  171. }
  172. // Watch out -- Stopping the JobPool also means shutting down SNFMulti and
  173. // the ScannerPool.
  174. void JobPool::stop() { // Shut down the JobPool.
  175. ScopeMutex Busy(AllocationMutex);
  176. while(0 < AllocatedJobs) killJobFromPool();
  177. Scanners().stop();
  178. Started = false;
  179. }