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