Happens on windows when SetPixelFormat is called...
}
}
-static int reentrancy = 0;
-
static void _Open(const char *szExtension) {
_Close();
if (g_gzFile == NULL)
return;
- if (reentrancy > 1)
- return;
-
gzwrite(g_gzFile, sBuffer, dwBytesToWrite);
}
_Close();
}
-void BeginCall(const char *function) {
+static unsigned call_no = 0;
+
+unsigned BeginEnter(const char *function) {
OS::AcquireMutex();
Open();
- ++reentrancy;
+ WriteByte(Trace::EVENT_ENTER);
WriteName(function);
+ return call_no++;
+}
+
+void EndEnter(void) {
+ WriteByte(Trace::CALL_END);
+ gzflush(g_gzFile, Z_SYNC_FLUSH);
+ OS::ReleaseMutex();
+}
+
+void BeginLeave(unsigned call) {
+ OS::AcquireMutex();
+ WriteByte(Trace::EVENT_LEAVE);
+ WriteUInt(call);
}
-void EndCall(void) {
+void EndLeave(void) {
WriteByte(Trace::CALL_END);
- --reentrancy;
gzflush(g_gzFile, Z_SYNC_FLUSH);
OS::ReleaseMutex();
}
void Open(void);
void Close(void);
- void BeginCall(const char *function);
- void EndCall(void);
+ unsigned BeginEnter(const char *function);
+ void EndEnter(void);
+
+ void BeginLeave(unsigned call);
+ void EndLeave(void);
void BeginArg(unsigned index, const char *name);
inline void EndArg(void) {}
void
AcquireMutex(void)
{
- //EnterCriticalSection(&CriticalSection);
+ EnterCriticalSection(&CriticalSection);
}
void
ReleaseMutex(void)
{
- //LeaveCriticalSection(&CriticalSection);
+ LeaveCriticalSection(&CriticalSection);
}
print ' %s __result;' % function.type
result = '__result = '
self._get_true_pointer(function)
- print ' Log::BeginCall("%s");' % (function.name)
+ print ' unsigned __call = Log::BeginEnter("%s");' % (function.name)
for arg in function.args:
if not arg.output:
self.unwrap_arg(function, arg)
self.dump_arg(function, arg)
+ print ' Log::EndEnter();'
print ' %s%s(%s);' % (result, pvalue, ', '.join([str(arg.name) for arg in function.args]))
+ print ' Log::BeginLeave(__call);'
for arg in function.args:
if arg.output:
self.dump_arg(function, arg)
self.wrap_arg(function, arg)
if function.type is not stdapi.Void:
self.dump_ret(function, "__result")
- print ' Log::EndCall();'
+ print ' Log::EndLeave();'
if function.type is not stdapi.Void:
self.wrap_ret(function, "__result")
print ' return __result;'
#define TRACE_VERSION 0
+enum Event {
+ EVENT_ENTER = 0,
+ EVENT_LEAVE,
+ EVENT_MESSAGE
+};
+
enum CallDetail {
CALL_END = 0,
CALL_ARG,
class Call
{
public:
+ unsigned no;
std::string name;
std::vector<Arg> args;
Value *ret;
typedef std::map<size_t, std::string> namemap;
namemap names;
+ typedef std::map<unsigned, Call *> callmap;
+ callmap calls;
+
+ unsigned next_call_no;
+
public:
Parser() {
file = NULL;
+ next_call_no = 0;
}
~Parser() {
}
Call *parse_call(void) {
+ do {
+ int c = read_byte();
+ switch(c) {
+ case Trace::EVENT_ENTER:
+ parse_enter();
+ break;
+ case Trace::EVENT_LEAVE:
+ return parse_leave();
+ case Trace::EVENT_MESSAGE:
+ std::cerr << "message: " << read_string() << "\n";
+ break;
+ default:
+ std::cerr << "error: unknown call detail " << c << "\n";
+ assert(0);
+ /* fallthrough */
+ case -1:
+ return NULL;
+ }
+ } while(true);
+ }
+
+ void parse_enter(void) {
Call *call = new Call;
+ call->no = next_call_no++;
call->name = read_name();
+ parse_call_details(call);
+ calls[call->no] = call;
+ }
+
+ Call *parse_leave(void) {
+ unsigned call_no = read_uint();
+ Call *call = calls[call_no];
+ assert(call);
+ if (!call) {
+ return NULL;
+ }
+ parse_call_details(call);
+ return call;
+ }
+
+ void parse_call_details(Call *call) {
do {
int c = read_byte();
switch(c) {
case Trace::CALL_END:
- return call;
+ return;
case Trace::CALL_ARG:
parse_arg(call);
break;
assert(0);
/* fallthrough */
case -1:
- delete call;
- return NULL;
+ return;
}
} while(true);
}