static bfd_lock_unlock_fn_type unlock_fn;
static void *lock_data;
+/*
+INTERNAL_FUNCTION
+ _bfd_threading_enabled
+
+SYNOPSIS
+ bool _bfd_threading_enabled (void);
+
+DESCRIPTION
+ Return true if threading is enabled, false if not.
+*/
+
+bool
+_bfd_threading_enabled (void)
+{
+ return lock_fn != NULL;
+}
+
/*
FUNCTION
bfd_thread_init
success and false on error. DATA is passed verbatim to the
lock and unlock functions. The lock and unlock functions
should return true on success, or set the BFD error and return
- false on failure.
+ false on failure. Note also that the lock must be a recursive
+ lock: BFD may attempt to acquire the lock when it is already
+ held by the current thread.
*/
bool
if (htab == NULL)
return -1;
+ /* The access to _bfd_section_id here is unlocked, so for the time
+ being this function cannot be called in multi-threaded mode. */
+ BFD_ASSERT (!_bfd_threading_enabled ());
+
htab->sec_info_arr_size = _bfd_section_id;
amt = sizeof (*htab->sec_info) * (htab->sec_info_arr_size);
htab->sec_info = bfd_zmalloc (amt);
of an archive. */
orig_messages = _bfd_set_error_handler_caching (&messages);
+ /* Locking is required here in order to manage _bfd_section_id. */
+ if (!bfd_lock ())
+ return false;
+
preserve_match.marker = NULL;
if (!bfd_preserve_save (abfd, &preserve, NULL))
goto err_ret;
bfd_set_lto_type (abfd);
/* File position has moved, BTW. */
- return bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
+ bool ret = bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
+ if (!bfd_unlock ())
+ return false;
+ return ret;
}
if (match_count == 0)
_bfd_restore_error_handler_caching (orig_messages);
print_and_clear_messages (&messages, PER_XVEC_NO_TARGET);
bfd_cache_set_uncloseable (abfd, old_in_format_matches, NULL);
+ bfd_unlock ();
return false;
}
const char *_bfd_get_error_program_name (void) ATTRIBUTE_HIDDEN;
+bool _bfd_threading_enabled (void) ATTRIBUTE_HIDDEN;
+
bool bfd_lock (void) ATTRIBUTE_HIDDEN;
bool bfd_unlock (void) ATTRIBUTE_HIDDEN;
static asection *
bfd_section_init (bfd *abfd, asection *newsect)
{
+ /* Locking needed for the _bfd_section_id access. */
+ if (!bfd_lock ())
+ return NULL;
+
newsect->id = _bfd_section_id;
newsect->index = abfd->section_count;
newsect->owner = abfd;
_bfd_section_id++;
abfd->section_count++;
bfd_section_list_append (abfd, newsect);
+
+ if (!bfd_unlock ())
+ return NULL;
+
return newsect;
}