///////////////////////////////////////////////////////////////////////////////
// MQ4CPP - Message queuing for C++
// Copyright (C) 2004-2007 Riccardo Pompeo (Italy)
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// For WinDbg users:
// -----------------
// There's a problem with OutputDebugString / TRACE statements running under
// the debugger near synchronization conditions.
// The problem is documented roughly in the article 'PRB: Synchronization
// Failure When Debugging' on MSDN. As I understand it, it's more of a
// limitation of the Win32 debug environment rather than any specific debugger.
// The solution unfortunately is to remove the TRACE / OutputDebugString calls
// from around the code making SetEvent / WaitForSingleObject (or other
// synchronization routines). This problem doesn't occur if you don't use WinDbg
// because TRACE macro switch debug messages to stdout. This work fine on IA32 if you
// redirect output to a file. Redirection doesn't work well on W2003/IA64 because writing
// on a file isn't thread safe. This problem occur expecially with Thread.cpp invoking wait(),
// release() or suspend().
//
#ifndef __TRACE__
#define __TRACE__
#include <iostream>
#include <strstream>
using namespace std;
#ifdef WIN32
#include <windows.h>
#else
#include <pthread.h>
#endif
#define DISPLAY(a) \
cout << __FILE__ << "(" << __LINE__ << ")" << ": " << a << endl;
#define BREAKPOINT \
DebugBreak();
#ifndef SILENT
extern void trace_dump(const char* descr,char* theString,int theLen);
#define DUMP(a,b,c) trace_dump(a,b,c)
#ifdef WIN32
class DebugStream : public ostream
{
private:
class DebugStreamBuf : public std::strstreambuf
{
protected:
virtual int sync()
{
sputc('\0');
Sleep(0); // MS workaround, but you can continue to have strange problems...
OutputDebugString(str());
Sleep(0);
freeze(false);
setp(pbase(), pbase(), epptr());
return 0;
}
};
DebugStreamBuf m_buf;
public:
DebugStream() : ostream(&m_buf) {};
~DebugStream() { m_buf.pubsync();};
};
#define TRACE(a) \
if(IsDebuggerPresent()) \
{ \
DebugStream dout; \
dout << __FILE__ << "(" << __LINE__ << ") #" << GetCurrentThreadId() << ": " << a << endl << ends; \
} \
else \
{ \
cout << __FILE__ << "(" << __LINE__ << ") #" << GetCurrentThreadId() << ": " << a << endl; \
}
#else
#define TRACE(a) \
cout << __FILE__ << "(" << __LINE__ << ") #" << pthread_self() << ": " << a << endl;
#endif
#else
#define TRACE(a) ;
#define DUMP(a,b,c)
#endif
#endif
syntax highlighted by Code2HTML, v. 0.9.1