Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #pragma once
00023
00024 #include "Locks.h"
00025 #include "Vary.h"
00026 #include "Thread.h"
00027 #include "File.h"
00028 #include <string>
00029 #include <list>
00030 #include "Setup.h"
00031
00032 namespace MPMA
00033 {
00034 namespace MPMAInternal
00035 {
00036 class AutoInitReports;
00037 }
00038
00039
00040
00042 class RouterOutput
00043 {
00044 public:
00045 inline RouterOutput(): bufferedDataProcessing(true) {}
00046 virtual ~RouterOutput();
00047
00049 virtual void Output(const uint8 *data, nuint dataLen);
00050
00052 inline bool IsBufferProcessing() {return bufferedDataProcessing;}
00053
00054
00055
00056 virtual void FlushInputSources();
00057
00058 protected:
00059
00060 bool bufferedDataProcessing;
00061
00062 private:
00063 SpinLock feedLock;
00064 std::list<class RouterInput*> reportFeeds;
00065 void DetachFeed(RouterInput *feed);
00066
00067 friend class RouterInput;
00068
00069
00070 RouterOutput(const RouterOutput&);
00071 const RouterOutput& operator=(const RouterOutput&);
00072 };
00073
00074 #ifdef DEBUGROUTER_ENABLED
00075
00076 class RouterInput: public RouterOutput
00077 {
00078 public:
00079
00080 RouterInput();
00081 ~RouterInput();
00082
00084 inline RouterInput& operator<<(const Vary &v) {const std::string &s=v; Output((const uint8*)&s[0], s.size()); return *this;}
00085 inline friend RouterInput& operator<<(RouterInput &db, RouterInput &db2) {return db;}
00086
00088 void Output(const uint8 *data, nuint dataLen);
00089 inline void Output(const Vary &v) {*this<<v;}
00090
00092 void AddOutputMethod(RouterOutput *outputter);
00093
00095 void RemoveOutputMethod(RouterOutput *outputter, bool flushOutputFirst=true, bool removeChildLink=true);
00096
00097 private:
00098 bool IsBufferProcessing();
00099 void FlushOutput();
00100 virtual void FlushInputSources();
00101
00102 std::list<RouterOutput*> outputs;
00103 MutexLock outputLock;
00104
00105
00106 Thread *dataMover;
00107 static void ThreadProc(Thread &thread, ThreadParam param);
00108 volatile bool endingThreadedMode;
00109 BlockingObject workerWaiter;
00110 BlockingObject routerWaiter;
00111 volatile uint8 *buffer;
00112 volatile nuint bufferLen;
00113 SpinLock dataLock;
00114 MutexLock addDataLock;
00115 SpinLock threadWorkingLock;
00116
00117 nuint numNonbufferedOutputs;
00118 bool alive;
00119
00120 bool isThreadedMode;
00121 void DemoteToUnthreaded();
00122
00123 friend class RouterOutput;
00124 friend class MPMAInternal::AutoInitReports;
00125
00126
00127 RouterInput(const RouterInput&);
00128 const RouterInput& operator=(const RouterInput&);
00129 };
00130 #else //dummy do-nothing implementation - when reporder is disabled
00131 class RouterInput: public RouterOutput
00132 {
00133 public:
00134 inline RouterInput& operator<<(const Vary &v) {return *this;}
00135 inline friend RouterInput& operator<<(RouterInput &db, RouterInput &db2) {return db;}
00136
00137 inline void Output(const uint8 *data, nuint dataLen) {}
00138 inline void Output(const Vary &v) {}
00139 inline void AddOutputMethod(RouterOutput *outputter) {}
00140 inline void RemoveOutputMethod(RouterOutput *outputter, bool flushOutputFirst=true, bool removeChildLink=true) {}
00141
00142 friend class RouterOutput;
00143 };
00144 #endif
00145
00146
00147
00148
00150 class RouterOutputFile: public RouterOutput
00151 {
00152 public:
00154 RouterOutputFile(const Filename &fileName, bool textMode=true);
00155 ~RouterOutputFile();
00156
00157 void Output(const uint8 *data, nuint dataLen);
00158 private:
00159 #ifdef DEBUGROUTER_ENABLED
00160 FILE *f;
00161 MutexLock lock;
00162 #endif
00163
00164
00165 RouterOutputFile(const RouterOutputFile&);
00166 const RouterOutputFile& operator=(const RouterOutputFile&);
00167 };
00168
00170 class RouterOutputStdout: public RouterOutput
00171 {
00172 public:
00173 ~RouterOutputStdout();
00174 void Output(const uint8 *data, nuint dataLen);
00175 };
00176
00177
00178
00179
00180
00182 RouterInput& ErrorReport();
00183
00184
00185 }