Index: libs/thread/src/read_write_mutex.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/thread/src/read_write_mutex.cpp,v
retrieving revision 1.13
diff -u -w -r1.13 read_write_mutex.cpp
--- libs/thread/src/read_write_mutex.cpp	26 Sep 2004 09:32:04 -0000	1.13
+++ libs/thread/src/read_write_mutex.cpp	3 Mar 2005 11:19:25 -0000
@@ -14,17 +14,9 @@
 #include <boost/assert.hpp>
 #include <boost/thread/read_write_mutex.hpp>
 #include <boost/thread/xtime.hpp>
-
-#ifdef BOOST_HAS_WINTHREADS
+#ifdef _WIN32
     #include <windows.h>
-    #include <tchar.h>
-
-    #if !((_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400))
-        inline bool IsDebuggerPresent(void)
-        {
-            return false;
-        }
-    #endif
+#  include <stdio.h>
 #endif
 
 #if defined(BOOST_ASSERT)
@@ -33,26 +25,62 @@
 #   define BOOST_ASSERT_ELSE(expr) if (false) {} else
 #endif
 
-bool boost_error(char const* expr, char const* func, char const* file, long line)
-{
-    #if WINVER
-        using namespace std;
 
-        #ifndef ELEMENTS
-        #define ELEMENTS(a) (sizeof(a)/sizeof(*(a)))
-        #endif
 
-        TCHAR message[200];
-        _sntprintf(message,ELEMENTS(message),TEXT("Assertion failed (func=%s, file=%s, line=%d): %s"), func, file, line, expr);
+namespace // anonymous
+{
+#ifdef _WIN32
+/* There is a function that can sometimes detect if a debugger is present so
+we can issue a debug break in boost_error. The 'sometimes' means it is only
+available on some win32 platforms (98, NT4 an newer, not on CE) and it fails
+to detect some debuggers (GDB).
+For portability to older win32, we try to resolve the symbol dynamically and
+default to false.
+*/
+    bool debugger_present()
+    {
+        HMODULE kernel_module = GetModuleHandle(TEXT("KERNEL32.DLL"));
+        if(!kernel_module)
+            return false;// irks, this is rather an internal error, should search different module
+        void* idp = GetProcAddress( kernel_module, TEXT("IsDebuggerPresent"));
+        if(!idp)
+            return false;// not supported
+        typedef BOOL is_present_fn(void);
+        // TODO: there is no cast from pointer to functionpointer, might need compiler-dependent wrapper
+        is_present_fn* pfn = (is_present_fn*)idp;
 
-        ::OutputDebugString(message);
+        return 0!=(*pfn)();
+    }
 
-        if(::IsDebuggerPresent())
-            ::DebugBreak();
+    bool boost_error(char const* expr, char const* func, char const* file, long line)
+    {
+        // format string + function name + expression + filename(MAX_PATH/255)
+        unsigned const size = 400;
+#  if defined(BOOST_NO_ANSI_APIS)
+        wchar_t msg[size+1];
+        // Note: '%S' is MSC specific for writing a char-string to a wchar_t-string.
+        // Since the functions with an underscore are MSC anyway, this doesn't matter.
+        _snwprintf( msg, size, L"Assertion failed (func=%S, file=%S, line=%ld): %S\n", func, file, line, expr);
+        msg[size] = L'\0';
+        ::OutputDebugStringW( msg);
+#  else
+        char msg[size+1];
+        _snprintf( msg, size, "Assertion failed (func=%s, file=%s, line=%ld): %s\n", func, file, line, expr);
+        msg[size] = '\0';
+        ::OutputDebugStringA( msg);
     #endif
+        if(debugger_present())
+            ::DebugBreak();
 
     return false;
 }
+#else
+    bool boost_error(char const* expr, char const* func, char const* file, long line)
+    {
+        return false;
+    }
+#endif
+}
 
 namespace boost {
 namespace detail {

