00001 #ifndef _SCOPED_STACK_EXECUTION_H 00002 #define _SCOPED_STACK_EXECUTION_H 00003 00004 #include "mset.h" 00005 #include "mdeque.h" 00006 #include "Log.h" 00007 #include "LogIdSet.h" 00008 #include "mace.h" 00009 #include "ScopedLogReader.h" 00010 #include "MaceTime.h" 00011 #include "BinaryLogObject.h" 00012 00018 namespace mace { 00019 00021 class SSEReader : public BinaryLogObject, public PrintPrintable { 00022 public: 00023 bool begin; 00024 LogicalClock::lclock_t step; 00025 static const std::string type; 00026 00027 SSEReader() {} 00028 SSEReader(bool b, LogicalClock::lclock_t val) : begin(b), step(val) 00029 { } 00030 00031 public: 00032 void serialize(std::string& __str) const { 00033 __str += begin ? '1' : '0'; 00034 mace::serialize(__str, &step); 00035 } 00036 00037 int deserialize(std::istream& is) throw(mace::SerializationException) { 00038 char c; 00039 00040 c = is.get(); 00041 if (c == '1') { 00042 begin = true; 00043 } 00044 else if (c == '0') { 00045 begin = false; 00046 } 00047 else { 00048 std::cerr << "Invalid ScopedStackExecution token " << (int)c << " found" << std::endl; 00049 throw mace::SerializationException("Invalid ScopedStackExecution token found"); 00050 } 00051 00052 mace::deserialize(is, &step); 00053 00054 return 1+sizeof(step); 00055 } 00056 00057 void print(std::ostream& __out) const { 00058 if (begin) { 00059 __out << "STARTING (Step " << step << ")"; 00060 } 00061 else { 00062 __out << "ENDING (Step " << step << ")"; 00063 } 00064 } 00065 00066 const std::string& getLogType() const { 00067 return type; 00068 } 00069 00070 const std::string& getLogDescription() const { 00071 static const std::string desc = "ScopedStackExecution"; 00072 return desc; 00073 } 00074 00075 LogClass getLogClass() const { 00076 return STRUCTURE; 00077 } 00078 00079 static void init(); 00080 }; 00081 00104 class ScopedStackExecution { 00105 private: 00106 typedef set<BaseMaceService*, SoftState> ServiceList; 00107 00108 static int stack; 00109 static ServiceList needDefer; 00110 static const bool logStart = true; 00111 static const bool logEnd = true; 00112 int here; 00113 public: 00117 ScopedStackExecution() { 00118 const static log_id_t logid = Log::getId("ServiceStack"); 00119 here = stack++; 00120 if (here == 0) { 00121 LogicalClock::instance().tick(); 00122 if (logStart) { 00123 Log::binaryLog(logid, SSEReader(true, LogicalClock::instance().getClock()), 0); 00124 } 00125 } 00126 } 00127 ~ScopedStackExecution() { 00128 const static log_id_t logid = Log::getId("ServiceStack"); 00129 if (here == 0) { 00130 runDefer(); 00131 if (logEnd) { 00132 Log::binaryLog(logid, SSEReader(false, LogicalClock::instance().getClock()), 0); 00133 } 00134 } 00135 stack--; 00136 } 00137 00139 static void addDefer(BaseMaceService* service) { needDefer.insert(service); } 00141 static void runDefer() { 00142 ServiceList sl; 00143 sl.swap(needDefer); 00144 for (ServiceList::iterator i = sl.begin(); i != sl.end(); i++) { 00145 (*i)->processDeferred(); 00146 } 00147 if (!needDefer.empty()) { 00148 runDefer(); 00149 } 00150 } 00151 00153 static int getStackDepth() { 00154 return stack; 00155 } 00156 }; 00157 00162 } 00163 00164 #endif //_SCOPED_STACK_EXECUTION_H