[babl] icc: make babl_space_from_icc threadsafe
- From: Øyvind "pippin" Kolås <ok src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [babl] icc: make babl_space_from_icc threadsafe
- Date: Wed, 3 Feb 2021 00:12:06 +0000 (UTC)
commit c8d2ca843e10271c1532863f27dd8c7725085394
Author: Øyvind Kolås <pippin gimp org>
Date: Wed Feb 3 01:08:27 2021 +0100
icc: make babl_space_from_icc threadsafe
When multiple threads concurrently try to use ICC profiles / spaces
races during construction could cause broken internal representation of
profiles.
babl/babl-icc.c | 21 +++++++++++++++++++++
babl/babl-internal.c | 2 ++
babl/babl-internal.h | 1 +
3 files changed, 24 insertions(+)
---
diff --git a/babl/babl-icc.c b/babl/babl-icc.c
index 52a35d2a5..0bbb47e1d 100644
--- a/babl/babl-icc.c
+++ b/babl/babl-icc.c
@@ -957,6 +957,8 @@ babl_space_from_icc (const char *icc_data,
sign_t profile_class, color_space, pcs;
+ babl_mutex_lock (babl_space_mutex);
+
if (!error) error = &int_err;
*error = NULL;
@@ -973,13 +975,22 @@ babl_space_from_icc (const char *icc_data,
{
ret = _babl_space_for_lcms (icc_data, icc_length);
if (!ret)
+ {
+ babl_mutex_unlock (babl_space_mutex);
return NULL;
+ }
if (ret->space.icc_type == BablICCTypeCMYK)
+ {
+ babl_mutex_unlock (babl_space_mutex);
return ret;
+ }
ret->space.icc_length = icc_length;
ret->space.icc_profile = malloc (icc_length);
if (!ret->space.icc_profile)
+ {
+ babl_mutex_unlock (babl_space_mutex);
return NULL;
+ }
memcpy (ret->space.icc_profile, icc_data, icc_length);
#ifdef HAVE_LCMS
@@ -1010,6 +1021,7 @@ babl_space_from_icc (const char *icc_data,
cmsCloseProfile (ret->space.cmyk.lcms_profile); // XXX keep it open in case of CMYK to CMYK
transforms needed?
#endif
ret->space.icc_type = BablICCTypeCMYK;
+ babl_mutex_unlock (babl_space_mutex);
return ret;
}
@@ -1113,6 +1125,7 @@ babl_space_from_icc (const char *icc_data,
{
babl_free (state);
+ babl_mutex_unlock (babl_space_mutex);
return NULL;
}
@@ -1130,6 +1143,7 @@ babl_space_from_icc (const char *icc_data,
ret->space.icc_profile = malloc (icc_length);
memcpy (ret->space.icc_profile, icc_data, icc_length);
babl_free (state);
+ babl_mutex_unlock (babl_space_mutex);
return ret;
@@ -1175,6 +1189,7 @@ babl_space_from_icc (const char *icc_data,
*error = "Inconsistent ICC profile detected, profile contains both cLUTs and a matrix with
swapped primaries, this likely means it is an intentionally inconsistent Argyll profile is in use; this
profile is only capable of high accuracy rendering and does not permit acceleration for interactive
previews.";
fprintf (stderr, "babl ICC warning: %s\n", *error);
babl_free (state);
+ babl_mutex_unlock (babl_space_mutex);
return NULL;
}
}
@@ -1184,6 +1199,7 @@ babl_space_from_icc (const char *icc_data,
if (ret)
{
babl_free (state);
+ babl_mutex_unlock (babl_space_mutex);
return ret;
}
@@ -1199,6 +1215,7 @@ babl_space_from_icc (const char *icc_data,
ret->space.icc_length = icc_length;
ret->space.icc_profile = malloc (icc_length);
memcpy (ret->space.icc_profile, icc_data, icc_length);
+ babl_mutex_unlock (babl_space_mutex);
return ret;
}
}
@@ -1216,11 +1233,13 @@ babl_space_from_icc (const char *icc_data,
if (phosporant != 0)
{
*error = "unhandled phosporants, please report bug against babl with profile";
+ babl_mutex_unlock (babl_space_mutex);
return NULL;
}
if (channels != 3)
{
*error = "unexpected non 3 count of channels";
+ babl_mutex_unlock (babl_space_mutex);
return NULL;
}
@@ -1250,6 +1269,7 @@ babl_space_from_icc (const char *icc_data,
ret->space.icc_profile = malloc (icc_length);
memcpy (ret->space.icc_profile, icc_data, icc_length);
+ babl_mutex_unlock (babl_space_mutex);
return ret;
}
}
@@ -1257,6 +1277,7 @@ babl_space_from_icc (const char *icc_data,
}
babl_free (state);
+ babl_mutex_unlock (babl_space_mutex);
return NULL;
}
diff --git a/babl/babl-internal.c b/babl/babl-internal.c
index f7939a1b3..94043d3c4 100644
--- a/babl/babl-internal.c
+++ b/babl/babl-internal.c
@@ -84,6 +84,7 @@ BablMutex *babl_format_mutex;
BablMutex *babl_debug_mutex;
#endif
BablMutex *babl_reference_mutex;
+BablMutex *babl_space_mutex;
void
babl_internal_init (void)
@@ -93,6 +94,7 @@ babl_internal_init (void)
babl_fish_mutex = babl_mutex_new ();
babl_format_mutex = babl_mutex_new ();
babl_reference_mutex = babl_mutex_new ();
+ babl_space_mutex = babl_mutex_new ();
#if BABL_DEBUG_MEM
babl_debug_mutex = babl_mutex_new ();
#endif
diff --git a/babl/babl-internal.h b/babl/babl-internal.h
index 56e95e4a2..8b8ebd64d 100644
--- a/babl/babl-internal.h
+++ b/babl/babl-internal.h
@@ -249,6 +249,7 @@ extern int babl_in_fish_path;
extern BablMutex *babl_format_mutex;
extern BablMutex *babl_fish_mutex;
extern BablMutex *babl_reference_mutex;
+extern BablMutex *babl_space_mutex;
#define BABL_DEBUG_MEM 0
#if BABL_DEBUG_MEM
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]