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