|
From: Carlo W. <li...@us...> - 2002-02-03 04:15:23
|
CVSROOT : /cvsroot/libcw
Module : src
Commit time: 2002-01-03 04:15:22 UTC
Modified files:
libcwd/Makefile.am libcwd/bfd.cc libcwd/configure.in
libcwd/debug.cc libcwd/debugmalloc.cc libcwd/elf32.cc
libcwd/threading.cc libcwd/include/raw_write.h
libcwd/include/libcw/macro_ForAllDebugChannels.h
libcwd/include/libcw/macro_ForAllDebugObjects.h
libcwd/include/libcw/private_struct_TSD.h
libcwd/include/libcw/private_threading.h
Log message:
Now compiles again without --enable-libcwd-threading.
Now is cancel-safe: No cancellation point syscalls are done
inside libcwd critical areas or cancellation is disabled
first or a cleanup handler is installed (it is not certain that
these cleanup handlers do the right thing though, but they
should at least unlock all locks).
---------------------- diff included ----------------------
Index: src/libcwd/Makefile.am
diff -u src/libcwd/Makefile.am:1.44 src/libcwd/Makefile.am:1.45
--- src/libcwd/Makefile.am:1.44 Wed Jan 30 20:42:08 2002
+++ src/libcwd/Makefile.am Sat Feb 2 20:15:11 2002
@@ -28,7 +28,7 @@
demangle3.cc \
strerrno.cc \
type_info.cc \
- wrapcnclpnts.c
+ wrapcnclpnts.cc
libcwd_la_LDFLAGS = -version-info $(VERSIONINFO) $(LIB_THREADS_SHARED)
Index: src/libcwd/bfd.cc
diff -u src/libcwd/bfd.cc:1.98 src/libcwd/bfd.cc:1.99
--- src/libcwd/bfd.cc:1.98 Thu Jan 31 21:21:05 2002
+++ src/libcwd/bfd.cc Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/bfd.cc,v 1.98 2002/02/01 05:21:05 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/bfd.cc,v 1.99 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2000 - 2001, by
//
@@ -78,8 +78,8 @@
#define BFD_RELEASE_READ_LOCK rwlock_tct<object_files_instance>::rdunlock();
#define BFD_ACQUIRE_READ2WRITE_LOCK rwlock_tct<object_files_instance>::rd2wrlock();
#define BFD_ACQUIRE_WRITE2READ_LOCK rwlock_tct<object_files_instance>::wr2rdlock();
-#define DLOPEN_MAP_ACQUIRE_LOCK LIBCWD_DEFER_PUSH_LOCKMUTEX(dlopen_map_instance, &mutex_tct<dlopen_map_instance>::unlock);
-#define DLOPEN_MAP_RELEASE_LOCK LIBCWD_UNLOCKMUTEX_POP_RESTORE(dlopen_map_instance)
+#define DLOPEN_MAP_ACQUIRE_LOCK mutex_tct<dlopen_map_instance>::lock();
+#define DLOPEN_MAP_RELEASE_LOCK mutex_tct<dlopen_map_instance>::unlock();
#else // !LIBCWD_THREAD_SAFE
#define BFD_INITIALIZE_LOCK
#define BFD_ACQUIRE_WRITE_LOCK
@@ -1013,19 +1013,12 @@
// Load executable
// No write lock is really needed because this is a Single Threaded function,
// but the sanity checks inside the allocators used in load_object_file()
- // require the lock to be set. Fortunately is therefore also doesn't hurt
+ // require the lock to be set. Fortunately it therefore also doesn't hurt
// that we keep the lock a long time (during the execution of ldd_prog).
// Same thing for the LIBCWD_DEFER_CANCEL, needed for the sanity checks.
- // However - here we have another sanity check that controls if we aren't
- // setting the cancel state too often (recursively), and in *this* case
- // that is unavoidable. Therefore we decrement these sanity check counters
- // in order to fool the check, right after we set the lock.
BFD_INITIALIZE_LOCK
- LIBCWD_DEFER_CANCEL
+ LIBCWD_DEFER_CLEANUP_PUSH(_private_::fatal_cancellation, const_cast<char*>("while reading debug information from a shared library"))
BFD_ACQUIRE_WRITE_LOCK
-#ifdef DEBUGDEBUGTHREADS
- --__libcwd_tsd.cancel_explicitely_deferred;
-#endif
load_object_file(fullpath.value->data(), 0);
// Load all shared objects
@@ -1052,9 +1045,6 @@
load_object_file(l->l_name, reinterpret_cast<void*>(l->l_addr));
}
NEEDS_WRITE_LOCK_object_files().sort(object_file_greater());
-#ifdef DEBUGDEBUGTHREADS
- ++__libcwd_tsd.cancel_explicitely_deferred;
-#endif
BFD_RELEASE_WRITE_LOCK
set_alloc_checking_on(LIBCWD_TSD);
@@ -1062,7 +1052,7 @@
// ****************************************************************************
// We put this outside the 'internal' region because it might call __pthread_do_exit.
- LIBCWD_RESTORE_CANCEL
+ LIBCWD_CLEANUP_POP_RESTORE(false)
#ifdef ALWAYS_PRINT_LOADING
Debug( dc::bfd.restore(state2) );
@@ -1450,6 +1440,16 @@
namespace _private_ {
typedef std::map<void*, dlloaded_st, std::less<void*>, userspace_allocator::rebind<void*>::other> dlopen_map_ct;
static dlopen_map_ct dlopen_map;
+
+#ifdef LIBCWD_THREAD_SAFE
+void dlopen_cleanup1(void* arg)
+{
+ TSD_st& __libcwd_tsd = (*static_cast<TSD_st*>(arg));
+ set_alloc_checking_on(LIBCWD_TSD);
+ BFD_RELEASE_WRITE_LOCK
+}
+#endif
+
}
}
}
@@ -1464,35 +1464,26 @@
if ((flags & RTLD_NOLOAD))
return handle;
#endif
- set_alloc_checking_off(LIBCWD_TSD);
- LIBCWD_DEFER_CANCEL_NO_BRACE
+ cwbfd::object_file_ct* object_file;
+ LIBCWD_DEFER_CLEANUP_PUSH(libcw::debug::_private_::dlopen_cleanup1, &__libcwd_tsd) // In case we are cancelled inside cwbfd::load_object_file().
BFD_ACQUIRE_WRITE_LOCK;
- cwbfd::object_file_ct* object_file = cwbfd::load_object_file(name, cwbfd::unknown_l_addr);
+ set_alloc_checking_off(LIBCWD_TSD);
+ object_file = cwbfd::load_object_file(name, cwbfd::unknown_l_addr);
+ if (object_file)
+ cwbfd::NEEDS_WRITE_LOCK_object_files().sort(cwbfd::object_file_greater());
set_alloc_checking_on(LIBCWD_TSD);
+ BFD_RELEASE_WRITE_LOCK;
+ LIBCWD_CLEANUP_POP_RESTORE(false)
if (object_file)
{
- set_alloc_checking_off(LIBCWD_TSD);
- cwbfd::NEEDS_WRITE_LOCK_object_files().sort(cwbfd::object_file_greater());
- set_alloc_checking_on(LIBCWD_TSD);
- BFD_RELEASE_WRITE_LOCK;
- LIBCWD_RESTORE_CANCEL_NO_BRACE
// MT: dlopen_map uses a userspace_allocator and might therefore write to dc::malloc.
// This means that the thread can be cancelled inside the insert() call, leaving
// dlopen_map in an undefined state. Therefore we disable cancellation.
LIBCWD_DISABLE_CANCEL
- DLOPEN_MAP_ACQUIRE_LOCK;
+ DLOPEN_MAP_ACQUIRE_LOCK
libcw::debug::_private_::dlopen_map.insert(std::pair<void* const, dlloaded_st>(handle, dlloaded_st(object_file, flags)));
-#ifdef LIBCWD_THREAD_SAFE
- DLOPEN_MAP_RELEASE_LOCK;
- // If the thread is cancelled next, then we don't need to take action regarding dlopen_map:
- // The shared library will state loaded.
+ DLOPEN_MAP_RELEASE_LOCK
LIBCWD_ENABLE_CANCEL
-#endif
- }
- else
- {
- BFD_RELEASE_WRITE_LOCK;
- LIBCWD_RESTORE_CANCEL_NO_BRACE
}
return handle;
}
@@ -1502,8 +1493,8 @@
LIBCWD_TSD_DECLARATION
LIBCWD_ASSERT( !__libcwd_tsd.internal );
int ret = ::dlclose(handle);
- DLOPEN_MAP_ACQUIRE_LOCK;
- // MT: Cancellation is defered at this point. The first cancellation point is in DLOPEN_MAP_RELEASE_LOCK.
+ LIBCWD_DEFER_CANCEL
+ DLOPEN_MAP_ACQUIRE_LOCK
libcw::debug::_private_::dlopen_map_ct::iterator iter(libcw::debug::_private_::dlopen_map.find(handle));
if (iter != libcw::debug::_private_::dlopen_map.end())
{
@@ -1527,7 +1518,8 @@
pthread_setcancelstate(oldstate, NULL);
#endif
}
- DLOPEN_MAP_RELEASE_LOCK;
+ DLOPEN_MAP_RELEASE_LOCK
+ LIBCWD_RESTORE_CANCEL
return ret;
}
} // extern "C"
Index: src/libcwd/configure.in
diff -u src/libcwd/configure.in:1.100 src/libcwd/configure.in:1.101
--- src/libcwd/configure.in:1.100 Thu Jan 31 21:21:05 2002
+++ src/libcwd/configure.in Sat Feb 2 20:15:11 2002
@@ -1,5 +1,5 @@
dnl Process this file with autoconf to produce a configure script.
-AC_REVISION($Revision: 1.100 $)dnl
+AC_REVISION($Revision: 1.101 $)dnl
dnl General intialization of `autoconf' varaibles.
dnl Ensure that the directory specified with --srcdir was correct
@@ -344,8 +344,6 @@
CW_CONFIG_HAVE_PTHREADS=undef
AC_SUBST(LIB_THREADS)
AC_SUBST(LIB_THREADS_SHARED)
-CW_CONFIG_HAVE__PTHREAD_CLEANUP_BUFFER=undef
-AC_SUBST(CW_CONFIG_HAVE__PTHREAD_CLEANUP_BUFFER)
if test "$libcwd_config_threading" = yes; then
dnl Check if we have POSIX threads
@@ -382,8 +380,6 @@
dnl itself even!.
AC_CHECK_LIB(pthread, pthread_create, [LIB_THREADS_SHARED=-lpthread])
fi
-
- AC_CHECK_TYPE([struct _pthread_cleanup_buffer],[CW_CONFIG_HAVE__PTHREAD_CLEANUP_BUFFER=define],,[#include <pthread.h>])
fi
dnl This test needs the full set of libraries we just determined.
Index: src/libcwd/debug.cc
diff -u src/libcwd/debug.cc:1.60 src/libcwd/debug.cc:1.61
--- src/libcwd/debug.cc:1.60 Wed Jan 30 20:42:08 2002
+++ src/libcwd/debug.cc Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/debug.cc,v 1.60 2002/01/31 04:42:08 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/debug.cc,v 1.61 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2000 - 2001, by
//
@@ -75,7 +75,7 @@
char* buf;
bool used_malloc = false;
int curlen = rdbuf()->pubseekoff(0, ios_base::cur, ios_base::out) - rdbuf()->pubseekoff(0, ios_base::cur, ios_base::in);
- if (curlen > 512 || !(buf = (char*)alloca(curlen)))
+ if (curlen > 512 || !(buf = (char*)__builtin_alloca(curlen)))
{
set_alloc_checking_off(LIBCWD_TSD);
buf = (char*)malloc(curlen);
@@ -90,7 +90,9 @@
++__libcwd_tsd.library_call;
++LIBCWD_DO_TSD_MEMBER(libcw_do, _off);
#endif
+ LIBCWD_DISABLE_CANCEL // We don't want Dout() to be a cancellation point.
os->write(buf, curlen);
+ LIBCWD_ENABLE_CANCEL
#ifdef DEBUGMALLOC
--LIBCWD_DO_TSD_MEMBER(libcw_do, _off);
--__libcwd_tsd.library_call;
@@ -300,11 +302,8 @@
debug_objects_ct debug_objects; // List with all debug devices.
// _private_::
- void debug_channels_ct::internal_init(LIBCWD_TSD_PARAM)
+ void debug_channels_ct::init(LIBCWD_TSD_PARAM)
{
-#ifdef DEBUGDEBUGMALLOC
- LIBCWD_ASSERT( __libcwd_tsd.internal );
-#endif
#ifdef LIBCWD_THREAD_SAFE
_private_::rwlock_tct<_private_::debug_channels_instance>::initialize();
#endif
@@ -312,7 +311,9 @@
if (!WNS_debug_channels) // MT: `WNS_debug_channels' is only false when this object is still Non_Shared.
{
DEBUG_CHANNELS_ACQUIRE_READ2WRITE_LOCK
+ set_alloc_checking_off(LIBCWD_TSD);
WNS_debug_channels = new debug_channels_ct::container_type;
+ set_alloc_checking_on(LIBCWD_TSD);
DEBUG_CHANNELS_RELEASE_WRITE_LOCK
}
#ifdef LIBCWD_THREAD_SAFE
@@ -340,7 +341,7 @@
#endif
// _private_::
- void debug_objects_ct::internal_init(LIBCWD_TSD_PARAM)
+ void debug_objects_ct::init(LIBCWD_TSD_PARAM)
{
#ifdef LIBCWD_THREAD_SAFE
_private_::rwlock_tct<_private_::debug_objects_instance>::initialize();
@@ -354,7 +355,9 @@
init_debugmalloc();
#endif
DEBUG_OBJECTS_ACQUIRE_READ2WRITE_LOCK
+ set_alloc_checking_off(LIBCWD_TSD);
WNS_debug_objects = new debug_objects_ct::container_type;
+ set_alloc_checking_on(LIBCWD_TSD);
DEBUG_OBJECTS_RELEASE_WRITE_LOCK
}
#ifdef LIBCWD_THREAD_SAFE
@@ -762,53 +765,53 @@
++_off;
DEBUGDEBUG_CERR( "Entering debug_ct::finish(), _off became " << _off );
+ // Handle control flags, if any:
+ if ((current->mask & error_cf))
+ *current_oss << ": " << strerrno(current->err) << " (" << strerror(current->err) << ')';
+ if (!(current->mask & nonewline_cf))
+ current_oss->put('\n');
+
// Write buffer to ostream.
static_cast<buffer_ct*>(current_oss)->writeto(target_os LIBCWD_COMMA_TSD);
- channel_set.mask = current->mask;
- channel_set.label = current->label;
// Handle control flags, if any:
- if (channel_set.mask == 0)
- target_os->put('\n');
- else
+ if (current->mask != 0)
{
- if ((channel_set.mask & error_cf))
- *target_os << ": " << strerrno(current->err) << " (" << strerror(current->err) << ')';
- if ((channel_set.mask & coredump_maskbit))
- {
- if (!__libcwd_tsd.recursive_fatal)
- {
- __libcwd_tsd.recursive_fatal = true;
- *target_os << std::endl; // First time, try to write a new-line and flush.
- }
- core_dump();
- }
- if ((channel_set.mask & fatal_maskbit))
+ if ((current->mask & (coredump_maskbit|fatal_maskbit)))
{
+ set_alloc_checking_on(LIBCWD_TSD);
if (!__libcwd_tsd.recursive_fatal)
{
__libcwd_tsd.recursive_fatal = true;
- *target_os << std::endl;
+ LIBCWD_DISABLE_CANCEL
+ *target_os << std::flush; // First time, try to flush.
+ LIBCWD_ENABLE_CANCEL
}
+ if ((current->mask & coredump_maskbit))
+ core_dump();
DEBUGDEBUG_CERR( "Deleting `current' " << (void*)current );
delete current;
DEBUGDEBUG_CERR( "Done deleting `current'" );
set_alloc_checking_on(LIBCWD_TSD);
exit(254);
}
- if ((channel_set.mask & wait_cf))
+ if ((current->mask & wait_cf))
{
- *target_os << "\n(type return)";
+ *target_os << "(type return)";
if (debug_object.interactive)
{
*target_os << std::flush;
while(std::cin.get() != '\n');
}
}
- if (!(channel_set.mask & nonewline_cf))
- *target_os << '\n';
- if ((channel_set.mask & flush_cf))
+ if ((current->mask & flush_cf))
+ {
+ set_alloc_checking_on(LIBCWD_TSD);
+ LIBCWD_DISABLE_CANCEL
*target_os << std::flush;
+ LIBCWD_ENABLE_CANCEL
+ set_alloc_checking_off(LIBCWD_TSD);
+ }
}
DEBUGDEBUG_CERR( "Deleting `current' " << (void*)current );
@@ -825,11 +828,12 @@
// Restore previous buffer as being the current one, if any.
if (laf_stack.size())
{
+ control_flag_t mask = current->mask;
current = laf_stack.top();
DEBUGDEBUG_CERR( "current = " << (void*)current );
current_oss = ¤t->oss;
DEBUGDEBUG_CERR( "current_oss = " << (void*)current_oss );
- if ((channel_set.mask & flush_cf))
+ if ((mask & flush_cf))
current->mask |= flush_cf; // Propagate flush to real ostream.
}
else
@@ -857,7 +861,9 @@
DoutFatal( dc::core, "Don't use `DoutFatal' together with `continued_cf', use `Dout' instead. (This message can also occur when using DoutFatal correctly but from the constructor of a global object)." );
}
+#ifdef LIBCWD_THREAD_SAFE
int debug_ct::S_index_count = 0;
+#endif
void debug_ct::NS_init(void)
{
@@ -878,8 +884,8 @@
LIBCWD_TSD_DECLARATION
LIBCWD_DEFER_CANCEL
+ _private_::debug_objects.init(LIBCWD_TSD);
set_alloc_checking_off(LIBCWD_TSD); // debug_objects is internal.
- _private_::debug_objects.internal_init(LIBCWD_TSD);
DEBUG_OBJECTS_ACQUIRE_WRITE_LOCK
if (find(_private_::debug_objects.write_locked().begin(),
_private_::debug_objects.write_locked().end(), this)
@@ -1037,9 +1043,7 @@
channel_ct* tmp = NULL;
LIBCWD_TSD_DECLARATION
LIBCWD_DEFER_CANCEL
- set_alloc_checking_off(LIBCWD_TSD);
- _private_::debug_channels.internal_init(LIBCWD_TSD);
- set_alloc_checking_on(LIBCWD_TSD);
+ _private_::debug_channels.init(LIBCWD_TSD);
DEBUG_CHANNELS_ACQUIRE_READ_LOCK
for(_private_::debug_channels_ct::container_type::const_iterator i(_private_::debug_channels.read_locked().begin());
i != _private_::debug_channels.read_locked().end(); ++i)
@@ -1087,9 +1091,9 @@
if (LIBCWD_DO_TSD_MEMBER(debug_object, _off) < 0)
{
LIBCWD_DEFER_CANCEL
- set_alloc_checking_off(LIBCWD_TSD);
- _private_::debug_channels.internal_init(LIBCWD_TSD);
- set_alloc_checking_on(LIBCWD_TSD);
+ _private_::debug_channels.init(LIBCWD_TSD);
+ LIBCWD_RESTORE_CANCEL
+ LIBCWD_DEFER_CLEANUP_PUSH(&rwlock_tct<debug_channels_instance>::cleanup, NULL)
DEBUG_CHANNELS_ACQUIRE_READ_LOCK
for(_private_::debug_channels_ct::container_type::const_iterator i(_private_::debug_channels.read_locked().begin());
i != _private_::debug_channels.read_locked().end(); ++i)
@@ -1102,8 +1106,8 @@
LibcwDoutStream.write(": Disabled", 10);
LibcwDoutScopeEnd;
}
- DEBUG_CHANNELS_RELEASE_READ_LOCK
- LIBCWD_RESTORE_CANCEL
+ DEBUG_CHANNELS_RELEASE_READ_LOCK
+ LIBCWD_CLEANUP_POP_RESTORE(false)
}
}
@@ -1167,19 +1171,19 @@
// dependent on the order in which these global objects are
// initialized.
LIBCWD_DEFER_CANCEL
- set_alloc_checking_off(LIBCWD_TSD); // debug_channels is internal.
- _private_::debug_channels.internal_init(LIBCWD_TSD);
+ _private_::debug_channels.init(LIBCWD_TSD);
DEBUG_CHANNELS_ACQUIRE_WRITE_LOCK
{
+ set_alloc_checking_off(LIBCWD_TSD); // debug_channels is internal.
_private_::debug_channels_ct::container_type& channels(_private_::debug_channels.write_locked());
_private_::debug_channels_ct::container_type::iterator i(channels.begin());
for(; i != channels.end(); ++i)
if (strncmp((*i)->get_label(), WNS_label, max_label_len_c) > 0)
break;
channels.insert(i, this);
+ set_alloc_checking_on(LIBCWD_TSD);
}
DEBUG_CHANNELS_RELEASE_WRITE_LOCK
- set_alloc_checking_on(LIBCWD_TSD);
LIBCWD_RESTORE_CANCEL
// Turn debug channel "WARNING" on by default.
@@ -1378,6 +1382,9 @@
core_dump();
}
__libcwd_tsd.recursive_assert = true;
+#ifdef DEBUGDEBUGTHREADS
+ __libcwd_tsd.internal_debugging_code = true;
+#endif
#endif
DoutFatal(dc::core, file << ':' << line << ": " << function << ": Assertion `" << expr << "' failed.\n");
}
Index: src/libcwd/debugmalloc.cc
diff -u src/libcwd/debugmalloc.cc:1.77 src/libcwd/debugmalloc.cc:1.78
--- src/libcwd/debugmalloc.cc:1.77 Wed Jan 30 20:42:08 2002
+++ src/libcwd/debugmalloc.cc Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/debugmalloc.cc,v 1.77 2002/01/31 04:42:08 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/debugmalloc.cc,v 1.78 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2000 - 2001, by
//
@@ -1660,13 +1660,13 @@
__libcwd_tsd.internal = 0;
}
- LIBCWD_DEFER_CANCEL
+ LIBCWD_DEFER_CLEANUP_PUSH(&rwlock_tct<memblk_map_instance>::cleanup, NULL);
ACQUIRE_READ_LOCK
LibcwDout( channels, debug_object, dc_malloc, "Allocated memory: " << const_dm_alloc_ct::get_memsize() << " bytes in " << const_dm_alloc_ct::get_memblks() << " blocks." );
if (base_alloc_list)
const_cast<dm_alloc_ct const*>(base_alloc_list)->show_alloc_list(1, channels::dc_malloc);
RELEASE_READ_LOCK
- LIBCWD_RESTORE_CANCEL
+ LIBCWD_CLEANUP_POP_RESTORE(false);
}
//=============================================================================
Index: src/libcwd/elf32.cc
diff -u src/libcwd/elf32.cc:1.35 src/libcwd/elf32.cc:1.36
--- src/libcwd/elf32.cc:1.35 Fri Feb 1 07:48:21 2002
+++ src/libcwd/elf32.cc Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/elf32.cc,v 1.35 2002/02/01 15:48:21 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/elf32.cc,v 1.36 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2001, by
//
@@ -1928,8 +1928,10 @@
char* object_file_ct::allocate_and_read_section(int i)
{
char* p = new char[M_sections[i].section_header().sh_size];
+ LIBCWD_DISABLE_CANCEL
M_input_stream.rdbuf()->pubseekpos(M_sections[i].section_header().sh_offset);
M_input_stream.read(p, M_sections[i].section_header().sh_size);
+ LIBCWD_ENABLE_CANCEL
return p;
}
Index: src/libcwd/include/libcw/macro_ForAllDebugChannels.h
diff -u src/libcwd/include/libcw/macro_ForAllDebugChannels.h:1.4 src/libcwd/include/libcw/macro_ForAllDebugChannels.h:1.5
--- src/libcwd/include/libcw/macro_ForAllDebugChannels.h:1.4 Wed Jan 30 20:42:08 2002
+++ src/libcwd/include/libcw/macro_ForAllDebugChannels.h Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/macro_ForAllDebugChannels.h,v 1.4 2002/01/31 04:42:08 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/macro_ForAllDebugChannels.h,v 1.5 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2000 - 2001, by
//
@@ -44,7 +44,7 @@
typedef internal_vector<channel_ct*> container_type;
container_type* WNS_debug_channels;
public:
- void internal_init(LIBCWD_TSD_PARAM);
+ void init(LIBCWD_TSD_PARAM);
#ifdef LIBCWD_THREAD_SAFE
void init_and_rdlock(void);
#endif
Index: src/libcwd/include/libcw/macro_ForAllDebugObjects.h
diff -u src/libcwd/include/libcw/macro_ForAllDebugObjects.h:1.4 src/libcwd/include/libcw/macro_ForAllDebugObjects.h:1.5
--- src/libcwd/include/libcw/macro_ForAllDebugObjects.h:1.4 Wed Jan 30 20:42:08 2002
+++ src/libcwd/include/libcw/macro_ForAllDebugObjects.h Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/macro_ForAllDebugObjects.h,v 1.4 2002/01/31 04:42:08 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/macro_ForAllDebugObjects.h,v 1.5 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2000 - 2001, by
//
@@ -46,7 +46,7 @@
private:
container_type* WNS_debug_objects;
public:
- void internal_init(LIBCWD_TSD_PARAM);
+ void init(LIBCWD_TSD_PARAM);
#ifdef LIBCWD_THREAD_SAFE
void init_and_rdlock(void);
#endif
Index: src/libcwd/include/libcw/private_struct_TSD.h
diff -u src/libcwd/include/libcw/private_struct_TSD.h:1.3 src/libcwd/include/libcw/private_struct_TSD.h:1.4
--- src/libcwd/include/libcw/private_struct_TSD.h:1.3 Thu Jan 31 21:21:05 2002
+++ src/libcwd/include/libcw/private_struct_TSD.h Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/private_struct_TSD.h,v 1.3 2002/02/01 05:21:05 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/private_struct_TSD.h,v 1.4 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2001, by
//
@@ -84,6 +84,9 @@
#ifdef DEBUGDEBUGTHREADS
int cancel_explicitely_deferred;
int cancel_explicitely_disabled;
+ int inside_critical_area;
+ int cleanup_handler_installed;
+ int internal_debugging_code;
#endif
#endif
int off_cnt_array[256];
Index: src/libcwd/include/libcw/private_threading.h
diff -u src/libcwd/include/libcw/private_threading.h:1.17 src/libcwd/include/libcw/private_threading.h:1.18
--- src/libcwd/include/libcw/private_threading.h:1.17 Thu Jan 31 21:21:05 2002
+++ src/libcwd/include/libcw/private_threading.h Sat Feb 2 20:15:12 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/private_threading.h,v 1.17 2002/02/01 05:21:05 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/include/libcw/private_threading.h,v 1.18 2002/02/03 04:15:12 libcw Exp $
//
// Copyright (C) 2001 - 2002, by
//
@@ -35,10 +35,6 @@
#ifndef LIBCW_PRIVATE_STRUCT_TSD_H
#include <libcw/private_struct_TSD.h>
#endif
-#ifndef LIBCW_CASSERT
-#define LIBCW_CASSERT
-#include <cassert>
-#endif
#ifndef LIBCW_CSTRING
#define LIBCW_CSTRING
#include <cstring> // Needed for std::memset and std::memcpy.
@@ -56,7 +52,6 @@
#ifndef LIBCWD_USE_LINUXTHREADS
#define LIBCWD_USE_LINUXTHREADS 0
-#undef HAVE__PTHREAD_CLEANUP_BUFFER
#endif
#ifndef LIBCWD_USE_POSIX_THREADS
#define LIBCWD_USE_POSIX_THREADS 0
@@ -68,10 +63,9 @@
#define LibcwDebugThreads(x)
#endif
-#ifdef DEBUGDEBUGTHREADS
-#ifndef LIBCW_CASSERT
-#define LIBCW_CASSERT
-#include <cassert>
+#if defined(DEBUGDEBUGTHREADS) || defined(DEBUGDEBUG)
+#ifndef LIBCW_PRIVATE_ASSERT_H
+#include <libcw/private_assert.h>
#endif
#endif
@@ -203,13 +197,12 @@
LibcwDebugThreads(\
{ \
LIBCWD_TSD_DECLARATION; \
- if (--__libcwd_tsd.cancel_explicitely_disabled < 0) \
- ::libcw::debug::core_dump(); \
+ LIBCWD_ASSERT( __libcwd_tsd.cancel_explicitely_disabled > 0 ); \
+ --__libcwd_tsd.cancel_explicitely_disabled; \
/* pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) can call */ \
/* __pthread_do_exit() when the thread is cancelled in the meantime. */ \
/* This might free allocations that are allocated in userspace. */ \
- if (__libcwd_tsd.internal) \
- ::libcw::debug::core_dump(); \
+ LIBCWD_ASSERT( !__libcwd_tsd.internal || __libcwd_tsd.cancel_explicitely_disabled || __libcwd_tsd.cancel_explicitely_deferred ); \
} ) \
pthread_setcancelstate(__libcwd_oldstate, NULL);
#define LIBCWD_ENABLE_CANCEL \
@@ -231,13 +224,12 @@
LibcwDebugThreads(\
{ \
LIBCWD_TSD_DECLARATION; \
- if (--__libcwd_tsd.cancel_explicitely_deferred < 0) \
- ::libcw::debug::core_dump(); \
+ LIBCWD_ASSERT( __libcwd_tsd.cancel_explicitely_deferred > 0 ); \
+ --__libcwd_tsd.cancel_explicitely_deferred; \
/* pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) will calls */ \
/* __pthread_do_exit() when the thread is cancelled in the meantime. */ \
/* This might free allocations that are allocated in userspace. */ \
- if (__libcwd_tsd.internal) \
- ::libcw::debug::core_dump(); \
+ LIBCWD_ASSERT( !__libcwd_tsd.internal || __libcwd_tsd.cancel_explicitely_disabled || __libcwd_tsd.cancel_explicitely_deferred ); \
} ) \
pthread_setcanceltype(__libcwd_oldtype, NULL);
#define LIBCWD_RESTORE_CANCEL \
@@ -251,22 +243,33 @@
{ \
LIBCWD_TSD_DECLARATION; \
++__libcwd_tsd.cancel_explicitely_deferred; \
+ ++__libcwd_tsd.cleanup_handler_installed; \
} )
#define LIBCWD_CLEANUP_POP_RESTORE(execute) \
LibcwDebugThreads(\
{ \
LIBCWD_TSD_DECLARATION; \
- if (--__libcwd_tsd.cancel_explicitely_deferred < 0) \
- ::libcw::debug::core_dump(); \
- if (__libcwd_tsd.internal) \
- ::libcw::debug::core_dump(); \
+ --__libcwd_tsd.cleanup_handler_installed; \
+ LIBCWD_ASSERT( __libcwd_tsd.cancel_explicitely_deferred > 0 ); \
+ --__libcwd_tsd.cancel_explicitely_deferred; \
+ LIBCWD_ASSERT( !__libcwd_tsd.internal ); \
} ) \
pthread_cleanup_pop_restore_np(static_cast<int>(execute))
#else // !LIBCWD_USE_LINUXTHREADS
#define LIBCWD_DEFER_CLEANUP_PUSH(routine, arg) \
LIBCWD_DEFER_CANCEL \
+ LibcwDebugThreads( \
+ { \
+ LIBCWD_TSD_DECLARATION; \
+ ++__libcwd_tsd.cleanup_handler_installed; \
+ } ) \
pthread_cleanup_push(reinterpret_cast<void(*)(void*)>(routine), reinterpret_cast<void*>(arg))
#define LIBCWD_CLEANUP_POP_RESTORE(execute) \
+ LibcwDebugThreads( \
+ { \
+ LIBCWD_TSD_DECLARATION; \
+ --__libcwd_tsd.cleanup_handler_installed; \
+ } ) \
pthread_cleanup_pop(static_cast<int>(execute)); \
LIBCWD_RESTORE_CANCEL
#endif // !LIBCWD_USE_LINUXTHREADS
@@ -289,8 +292,7 @@
/* When entering a critical area, make sure that we have explictely deferred cancellation of this */ \
/* thread (or disabled that) because when cancellation would happen in the middle of the critical */ \
/* area then the lock would stay locked. */ \
- if (!__libcwd_tsd.cancel_explicitely_deferred && !__libcwd_tsd.cancel_explicitely_disabled) \
- ::libcw::debug::core_dump(); \
+ LIBCWD_ASSERT( __libcwd_tsd.cancel_explicitely_deferred || __libcwd_tsd.cancel_explicitely_disabled ); \
} )
template <int instance>
@@ -317,19 +319,21 @@
public:
static bool trylock(void) throw()
{
- LibcwDebugThreads( assert( S_initialized ) );
+ LibcwDebugThreads( LIBCWD_ASSERT( S_initialized ) );
LIBCWD_DEBUGDEBUG_ASSERT_CANCEL_DEFERRED
bool success = (pthread_mutex_trylock(&S_mutex) == 0);
#ifdef DEBUGDEBUG
if (success)
instance_locked[instance] += 1;
#endif
+ LibcwDebugThreads( if (success) { LIBCWD_TSD_DECLARATION; ++__libcwd_tsd.inside_critical_area; } );
return success;
}
static void lock(void) throw()
{
- LibcwDebugThreads( assert( S_initialized ) );
+ LibcwDebugThreads( LIBCWD_ASSERT( S_initialized ) );
LIBCWD_DEBUGDEBUG_ASSERT_CANCEL_DEFERRED
+ LibcwDebugThreads( if (instance != tsd_initialization_instance) { LIBCWD_TSD_DECLARATION ++__libcwd_tsd.inside_critical_area; } );
#if LIBCWD_DEBUGDEBUGRWLOCK
if (instance != tsd_initialization_instance) LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": locking mutex " << instance);
#endif
@@ -337,9 +341,7 @@
int res =
#endif
pthread_mutex_lock(&S_mutex);
-#ifdef DEBUGDEBUGTHREADS
- assert( res == 0 );
-#endif
+ LibcwDebugThreads( LIBCWD_ASSERT( res == 0 ) );
#if LIBCWD_DEBUGDEBUGRWLOCK
if (instance != tsd_initialization_instance) LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": mutex " << instance << " locked");
#endif
@@ -360,6 +362,7 @@
#if LIBCWD_DEBUGDEBUGRWLOCK
if (instance != tsd_initialization_instance) LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": mutex " << instance << " unlocked");
#endif
+ LibcwDebugThreads( if (instance != tsd_initialization_instance) { LIBCWD_TSD_DECLARATION --__libcwd_tsd.inside_critical_area; } );
}
};
@@ -454,7 +457,7 @@
public:
void wait(void) {
#ifdef DEBUGDEBUG
- assert( is_locked(instance) );
+ LIBCWD_ASSERT( is_locked(instance) );
#endif
pthread_cond_wait(&S_condition, &S_mutex);
}
@@ -545,7 +548,7 @@
}
static bool tryrdlock(void) throw()
{
- LibcwDebugThreads( assert( S_initialized ) );
+ LibcwDebugThreads( LIBCWD_ASSERT( S_initialized ) );
LIBCWD_DEBUGDEBUG_ASSERT_CANCEL_DEFERRED
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Calling rwlock_tct<" << instance << ">::tryrdlock()");
if (instance < end_recursive_types && pthread_equal(S_writer_id, pthread_self()))
@@ -560,12 +563,13 @@
if (success)
++S_holders_count; // Add one reader.
S_no_holders_condition.unlock();
+ LibcwDebugThreads( if (success) { LIBCWD_TSD_DECLARATION; ++__libcwd_tsd.inside_critical_area; } );
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Leaving rwlock_tct<" << instance << ">::tryrdlock()");
return success;
}
static bool trywrlock(void) throw()
{
- LibcwDebugThreads( assert( S_initialized ) );
+ LibcwDebugThreads( LIBCWD_ASSERT( S_initialized ) );
LIBCWD_DEBUGDEBUG_ASSERT_CANCEL_DEFERRED
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Calling rwlock_tct<" << instance << ">::trywrlock()");
bool success = mutex_tct<readers_instance>::trylock(); // Block new readers,
@@ -588,12 +592,13 @@
if (instance < end_recursive_types)
S_writer_id = pthread_self();
}
+ LibcwDebugThreads( if (success) { LIBCWD_TSD_DECLARATION; ++__libcwd_tsd.inside_critical_area; } );
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Leaving rwlock_tct<" << instance << ">::trywrlock()");
return success;
}
static void rdlock(void) throw()
{
- LibcwDebugThreads( assert( S_initialized ) );
+ LibcwDebugThreads( LIBCWD_ASSERT( S_initialized ) );
LIBCWD_DEBUGDEBUG_ASSERT_CANCEL_DEFERRED
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Calling rwlock_tct<" << instance << ">::rdlock()");
if (instance < end_recursive_types && pthread_equal(S_writer_id, pthread_self()))
@@ -612,6 +617,7 @@
S_no_holders_condition.wait(); // Wait for writer to finish.
++S_holders_count; // Add one reader.
S_no_holders_condition.unlock();
+ LibcwDebugThreads( LIBCWD_TSD_DECLARATION; ++__libcwd_tsd.inside_critical_area );
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Leaving rwlock_tct<" << instance << ">::rdlock()");
}
static void rdunlock(void) throw()
@@ -623,6 +629,7 @@
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Leaving rwlock_tct<" << instance << ">::rdunlock() (skipped: thread has write lock)");
return; // No error checking is done.
}
+ LibcwDebugThreads( LIBCWD_TSD_DECLARATION; --__libcwd_tsd.inside_critical_area );
S_no_holders_condition.lock();
if (--S_holders_count == 0) // Was this the last reader?
S_no_holders_condition.signal(); // Tell waiting threads.
@@ -631,7 +638,7 @@
}
static void wrlock(void) throw()
{
- LibcwDebugThreads( assert( S_initialized ) );
+ LibcwDebugThreads( LIBCWD_ASSERT( S_initialized ) );
LIBCWD_DEBUGDEBUG_ASSERT_CANCEL_DEFERRED
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Calling rwlock_tct<" << instance << ">::wrlock()");
mutex_tct<readers_instance>::lock(); // Block new readers,
@@ -645,6 +652,7 @@
S_no_holders_condition.unlock();
if (instance < end_recursive_types)
S_writer_id = pthread_self();
+ LibcwDebugThreads( LIBCWD_TSD_DECLARATION; ++__libcwd_tsd.inside_critical_area );
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Leaving rwlock_tct<" << instance << ">::wrlock()");
#ifdef DEBUGDEBUG
instance_locked[instance] += 1;
@@ -657,6 +665,7 @@
instance_locked[instance] -= 1;
#endif
LIBCWD_DEBUGDEBUGRWLOCK_CERR(pthread_self() << ": Calling rwlock_tct<" << instance << ">::wrunlock()");
+ LibcwDebugThreads( LIBCWD_TSD_DECLARATION; --__libcwd_tsd.inside_critical_area) ;
if (instance < end_recursive_types)
S_writer_id = 0;
S_no_holders_condition.lock();
@@ -756,10 +765,8 @@
LIBCWD_TSD_DECLARATION
set_alloc_checking_off(LIBCWD_TSD);
delete instance;
-#ifdef DEBUGDEBUGTHREADS
// Hopefully S_destroy doesn't get called in the thread itself!
- assert( instance != &thread_specific_data_tct<TSD>::instance() );
-#endif
+ LibcwDebugThreads( LIBCWD_ASSERT( instance != &thread_specific_data_tct<TSD>::instance() ) );
set_alloc_checking_on(LIBCWD_TSD);
}
@@ -815,10 +822,27 @@
// End of Thread Specific Data
//===================================================================================================
+extern void fatal_cancellation(void*) throw();
+
} // namespace _private_
} // namespace debug
} // namespace libcw
+#else // !LIBCWD_THREAD_SAFE
+#define LIBCWD_DISABLE_CANCEL
+#define LIBCWD_DISABLE_CANCEL_NO_BRACE
+#define LIBCWD_ENABLE_CANCEL_NO_BRACE
+#define LIBCWD_ENABLE_CANCEL
+#define LIBCWD_DEFER_CANCEL
+#define LIBCWD_DEFER_CANCEL_NO_BRACE
+#define LIBCWD_RESTORE_CANCEL_NO_BRACE
+#define LIBCWD_RESTORE_CANCEL
+#define LIBCWD_DEFER_CLEANUP_PUSH(routine, arg)
+#define LIBCWD_CLEANUP_POP_RESTORE(execute)
+#define LIBCWD_PUSH_DEFER_TRYLOCK_MUTEX(instance, unlock_routine)
+#define LIBCWD_DEFER_PUSH_LOCKMUTEX(instance, unlock_routine)
+#define LIBCWD_UNLOCKMUTEX_POP_RESTORE(instance)
+#define LIBCWD_DEBUGDEBUG_ASSERT_CANCEL_DEFERRED
#endif // LIBCWD_THREAD_SAFE
#endif // LIBCW_PRIVATE_THREADING_H
Index: src/libcwd/include/raw_write.h
diff -u src/libcwd/include/raw_write.h:1.2 src/libcwd/include/raw_write.h:1.3
--- src/libcwd/include/raw_write.h:1.2 Wed Jan 30 20:42:08 2002
+++ src/libcwd/include/raw_write.h Sat Feb 2 20:15:11 2002
@@ -1,5 +1,5 @@
// Generated automatically from sys.ho.in by configure.
-// $Header: /cvsroot/l/li/libcw/src/libcwd/include/raw_write.h,v 1.2 2002/01/31 04:42:08 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/include/raw_write.h,v 1.3 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2001, by
//
@@ -22,6 +22,11 @@
#include <libcw/debug_config.h>
#ifdef DEBUGDEBUG
+#ifdef DEBUGDEBUGTHREADS
+#define WRITE __libc_write
+#else
+#define WRITE write
+#endif
extern "C" ssize_t write(int fd, const void *buf, size_t count) throw();
#ifdef LIBCWD_THREAD_SAFE
@@ -39,12 +44,14 @@
do { \
if (1/*::libcw::debug::_private_::WST_ios_base_initialized FIXME: uncomment again*/) { \
LIBCWD_CANCELSTATE_DISABLE \
- ::write(2, "DEBUGDEBUG: ", 12); \
LIBCWD_TSD_DECLARATION \
+ LibcwDebugThreads( ++__libcwd_tsd.internal_debugging_code ); \
+ ::write(2, "DEBUGDEBUG: ", 12); \
/* __libcwd_lcwc means library_call write counter. Used to avoid the 'scope of for changed' warning. */ \
for (int __libcwd_lcwc = 0; __libcwd_lcwc < __libcwd_tsd.library_call; ++__libcwd_lcwc) \
::write(2, " ", 4); \
::libcw::debug::_private_::raw_write << x << '\n'; \
+ LibcwDebugThreads( --__libcwd_tsd.internal_debugging_code ); \
LIBCWD_CANCELSTATE_RESTORE \
} \
} while(0)
Index: src/libcwd/threading.cc
diff -u src/libcwd/threading.cc:1.4 src/libcwd/threading.cc:1.5
--- src/libcwd/threading.cc:1.4 Thu Jan 31 21:21:05 2002
+++ src/libcwd/threading.cc Sat Feb 2 20:15:11 2002
@@ -1,4 +1,4 @@
-// $Header: /cvsroot/l/li/libcw/src/libcwd/threading.cc,v 1.4 2002/02/01 05:21:05 libcw Exp $
+// $Header: /cvsroot/l/li/libcw/src/libcwd/threading.cc,v 1.5 2002/02/03 04:15:11 libcw Exp $
//
// Copyright (C) 2001, by
//
@@ -14,6 +14,7 @@
//
#include "sys.h"
+#include "cwd_debug.h"
#include <libcw/private_threading.h>
namespace libcw {
@@ -53,6 +54,12 @@
#else // !LIBCWD_THREAD_SAFE
TSD_st __libcwd_tsd;
#endif // !LIBCWD_THREAD_SAFE
+
+void fatal_cancellation(void* arg) throw()
+{
+ char* text = static_cast<char*>(arg);
+ Dout(dc::core, "Cancelling a thread " << text << ". This is not supported by libcwd, sorry.");
+}
} // namespace _private_
} // namespace debug
----------------------- End of diff -----------------------
|