if (dwarf->mem_tails != NULL)
free (dwarf->mem_tails);
pthread_rwlock_destroy (&dwarf->mem_rwl);
+ rwlock_fini (dwarf->dwarf_lock);
/* Free the pubnames helper structure. */
free (dwarf->pubnames_sets);
}
}
+/* find_debug_altlink() modifies "dbg->alt_dwarf".
+ dwarf_getalt() reads "main->alt_dwarf".
+ Mutual exclusion is enforced to prevent a race. */
+
Dwarf *
dwarf_getalt (Dwarf *main)
{
- /* Only try once. */
- if (main == NULL || main->alt_dwarf == (void *) -1)
+ if (main == NULL)
return NULL;
+ rwlock_wrlock(main->dwarf_lock);
+
+ /* Only try once. */
+ if (main->alt_dwarf == (void *) -1)
+ {
+ rwlock_unlock (main->dwarf_lock);
+ return NULL;
+ }
+
+ /* Assign result before releasing the lock. */
+ Dwarf *result;
+
if (main->alt_dwarf != NULL)
- return main->alt_dwarf;
+ {
+ result = main->alt_dwarf;
+ rwlock_unlock (main->dwarf_lock);
+ return result;
+ }
find_debug_altlink (main);
if (main->alt_dwarf == NULL)
{
main->alt_dwarf = (void *) -1;
+ rwlock_unlock (main->dwarf_lock);
return NULL;
}
- return main->alt_dwarf;
+ result = main->alt_dwarf;
+ rwlock_unlock (main->dwarf_lock);
+
+ return result;
}
INTDEF (dwarf_getalt)
void
dwarf_setalt (Dwarf *main, Dwarf *alt)
{
+ rwlock_wrlock (main->dwarf_lock);
+
if (main->alt_fd != -1)
{
INTUSE(dwarf_end) (main->alt_dwarf);
}
main->alt_dwarf = alt;
+ rwlock_unlock (main->dwarf_lock);
}
INTDEF (dwarf_setalt)
allocations for this Dwarf. */
pthread_rwlock_t mem_rwl;
+ /* The dwarf_lock is a read-write lock designed to ensure thread-safe access
+ and modification of an entire Dwarf object. */
+ rwlock_define(, dwarf_lock);
+
/* Internal memory handling. This is basically a simplified thread-local
reimplementation of obstacks. Unfortunately the standard obstack
implementation is not usable in libraries. */