1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-04-30 03:40:34 +02:00

fix potential deadlock in issue-deprecation-warning

* libguile/deprecation.c (scm_c_issue_deprecation_warning): Avoid
  printing to a Scheme port while in a mutex.
This commit is contained in:
Andy Wingo 2011-02-10 21:06:14 +01:00
parent c2c550ca9d
commit c46345e69e

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2001, 2006, 2010 Free Software Foundation, Inc.
/* Copyright (C) 2001, 2006, 2010, 2011 Free Software Foundation, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@ -63,7 +63,28 @@ scm_c_issue_deprecation_warning (const char *msg)
scm_i_pthread_mutex_lock (&warn_lock);
for (iw = issued_warnings; iw; iw = iw->prev)
if (!strcmp (iw->message, msg))
goto done;
{
msg = NULL;
break;
}
if (msg)
{
msg = strdup (msg);
iw = malloc (sizeof (struct issued_warning));
if (msg == NULL || iw == NULL)
/* Nothing sensible to do if you can't allocate this small
amount of memory. */
abort ();
iw->message = msg;
iw->prev = issued_warnings;
issued_warnings = iw;
}
scm_i_pthread_mutex_unlock (&warn_lock);
/* All this dance is to avoid printing to a port inside a mutex,
which could recurse and deadlock. */
if (msg)
{
if (scm_gc_running_p)
fprintf (stderr, "%s\n", msg);
else
@ -71,16 +92,7 @@ scm_c_issue_deprecation_warning (const char *msg)
scm_puts (msg, scm_current_error_port ());
scm_newline (scm_current_error_port ());
}
msg = strdup (msg);
iw = malloc (sizeof (struct issued_warning));
if (msg == NULL || iw == NULL)
goto done;
iw->message = msg;
iw->prev = issued_warnings;
issued_warnings = iw;
done:
scm_i_pthread_mutex_unlock (&warn_lock);
}
}
}