summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2004-11-12 05:34:31 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2004-11-12 05:34:31 +0000
commitcb918cdb02c1c1fed54a86776a0888e236d2e198 (patch)
treea606b43b376cd1eeb9d3586634f20493d2b84635
parent26cbda1b88e5e57533468cde10d51cd5baeeb871 (diff)
downloadgdk-pixbuf-cb918cdb02c1c1fed54a86776a0888e236d2e198.tar.gz
Changes to make gdk-pixbuf threadsafe (#157310, #157306, Colin Walters):
2004-11-12 Matthias Clasen <mclasen@redhat.com> Changes to make gdk-pixbuf threadsafe (#157310, #157306, Colin Walters): * gdk-pixbuf-io.h (enum GdkPixbufFormatFlags): Add GDK_PIXBUF_FORMAT_THREADSAFE to indicate that an image loader is threadsafe. * gdk-pixbuf-io.c (get_file_formats, _gdk_pixbuf_load_module): Use a lock to make initialization of global data structures threadsafe. * gdk-pixbuf-private.h: * gdk-pixbuf-io.c (_gdk_pixbuf_lock, _gdk_pixbuf_unlock): Auxiliary functions which use another lock to protect threadunsafe image loaders. * gdk-pixbuf-io.c (gdk_pixbuf_real_save): (save_to_callback_with_tmp_file): (gdk_pixbuf_real_save_to_callback): (gdk_pixbuf_new_from_xpm_data): (_gdk_pixbuf_generic_image_load): * gdk-pixbuf-animation.c (gdk_pixbuf_animation_new_from_file): * gdk-pixbuf-loader.c (gdk_pixbuf_loader_load_module): (gdk_pixbuf_loader_close): (gdk_pixbuf_loader_finalize): Use _gdk_pixbuf_lock() and _gdk_pixbuf_unlock(). * io-ani.c, io-bmp.c, io-gif.c, io-ico.c: * io-jpeg.c, io-pcx.c, io-png.c, io-pnm.c: * io-ras.c, io-tga.c, io-wbmp.c, io-xbm.c: * io-xpm.c: Mark as threadsafe. * io-tiff.c: Remove pointless locking, mark as threadunsafe.
-rw-r--r--docs/reference/ChangeLog5
-rw-r--r--docs/reference/gdk-pixbuf/tmpl/module_interface.sgml3
-rw-r--r--gdk-pixbuf/ChangeLog36
-rw-r--r--gdk-pixbuf/gdk-pixbuf-animation.c7
-rw-r--r--gdk-pixbuf/gdk-pixbuf-io.c201
-rw-r--r--gdk-pixbuf/gdk-pixbuf-io.h3
-rw-r--r--gdk-pixbuf/gdk-pixbuf-loader.c18
-rw-r--r--gdk-pixbuf/gdk-pixbuf-private.h3
-rw-r--r--gdk-pixbuf/io-ani.c2
-rw-r--r--gdk-pixbuf/io-bmp.c2
-rw-r--r--gdk-pixbuf/io-gif.c2
-rw-r--r--gdk-pixbuf/io-ico.c2
-rw-r--r--gdk-pixbuf/io-jpeg.c2
-rw-r--r--gdk-pixbuf/io-pcx.c2
-rw-r--r--gdk-pixbuf/io-png.c2
-rw-r--r--gdk-pixbuf/io-pnm.c2
-rw-r--r--gdk-pixbuf/io-ras.c2
-rw-r--r--gdk-pixbuf/io-tga.c2
-rw-r--r--gdk-pixbuf/io-tiff.c18
-rw-r--r--gdk-pixbuf/io-wbmp.c2
-rw-r--r--gdk-pixbuf/io-xbm.c2
-rw-r--r--gdk-pixbuf/io-xpm.c2
22 files changed, 211 insertions, 109 deletions
diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog
index 4916e93e7..31be71cac 100644
--- a/docs/reference/ChangeLog
+++ b/docs/reference/ChangeLog
@@ -1,3 +1,8 @@
+2004-11-12 Matthias Clasen <mclasen@redhat.com>
+
+ * gdk-pixbuf/tmpl/module_interface.sgml: Document
+ GDK_PIXBUF_FORMAT_THREADSAFE.
+
2004-11-09 Matthias Clasen <mclasen@redhat.com>
* gtk/gtk-sections.txt: Add gtk_action_get_accel_path.
diff --git a/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml b/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml
index cca46f9bc..cfc176e31 100644
--- a/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml
+++ b/docs/reference/gdk-pixbuf/tmpl/module_interface.sgml
@@ -193,6 +193,9 @@ operations.
@GDK_PIXBUF_FORMAT_WRITABLE: the module can write out images in the format.
@GDK_PIXBUF_FORMAT_SCALABLE: the image format is scalable
+@GDK_PIXBUF_FORMAT_THREADSAFE: the module is threadsafe. If this flag is not
+ set, &gdk-pixbuf; will use a lock to prevent multiple threads from using
+ this module at the same time. (Since 2.6)
@Since: 2.2
<!-- ##### STRUCT GdkPixbufModulePattern ##### -->
diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog
index 44d768f5e..e4bfddb80 100644
--- a/gdk-pixbuf/ChangeLog
+++ b/gdk-pixbuf/ChangeLog
@@ -1,3 +1,39 @@
+2004-11-12 Matthias Clasen <mclasen@redhat.com>
+
+ Changes to make gdk-pixbuf threadsafe (#157310, #157306,
+ Colin Walters):
+
+ * gdk-pixbuf-io.h (enum GdkPixbufFormatFlags): Add
+ GDK_PIXBUF_FORMAT_THREADSAFE to indicate that an image loader
+ is threadsafe.
+
+ * gdk-pixbuf-io.c (get_file_formats, _gdk_pixbuf_load_module):
+ Use a lock to make initialization of global data structures
+ threadsafe.
+ * gdk-pixbuf-private.h:
+ * gdk-pixbuf-io.c (_gdk_pixbuf_lock, _gdk_pixbuf_unlock):
+ Auxiliary functions which use another lock to protect
+ threadunsafe image loaders.
+
+ * gdk-pixbuf-io.c (gdk_pixbuf_real_save):
+ (save_to_callback_with_tmp_file):
+ (gdk_pixbuf_real_save_to_callback):
+ (gdk_pixbuf_new_from_xpm_data):
+ (_gdk_pixbuf_generic_image_load):
+ * gdk-pixbuf-animation.c (gdk_pixbuf_animation_new_from_file):
+ * gdk-pixbuf-loader.c (gdk_pixbuf_loader_load_module):
+ (gdk_pixbuf_loader_close):
+ (gdk_pixbuf_loader_finalize):
+ Use _gdk_pixbuf_lock() and _gdk_pixbuf_unlock().
+
+ * io-ani.c, io-bmp.c, io-gif.c, io-ico.c:
+ * io-jpeg.c, io-pcx.c, io-png.c, io-pnm.c:
+ * io-ras.c, io-tga.c, io-wbmp.c, io-xbm.c:
+ * io-xpm.c: Mark as threadsafe.
+
+ * io-tiff.c: Remove pointless locking, mark as
+ threadunsafe.
+
2004-11-10 Matthias Clasen <mclasen@redhat.com>
* gdk-pixbuf-animation.c:
diff --git a/gdk-pixbuf/gdk-pixbuf-animation.c b/gdk-pixbuf/gdk-pixbuf-animation.c
index 5ea1ef6ee..fa6968c15 100644
--- a/gdk-pixbuf/gdk-pixbuf-animation.c
+++ b/gdk-pixbuf/gdk-pixbuf-animation.c
@@ -181,6 +181,8 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
return NULL;
}
+ _gdk_pixbuf_lock (image_module);
+
if (image_module->load_animation == NULL) {
GdkPixbuf *pixbuf;
@@ -208,7 +210,8 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
if (pixbuf == NULL) {
g_free (display_name);
- return NULL;
+ animation = NULL;
+ goto out_unlock;
}
animation = gdk_pixbuf_non_anim_new (pixbuf);
@@ -241,6 +244,8 @@ gdk_pixbuf_animation_new_from_file (const char *filename,
g_free (display_name);
+ out_unlock:
+ _gdk_pixbuf_unlock (image_module);
return animation;
}
diff --git a/gdk-pixbuf/gdk-pixbuf-io.c b/gdk-pixbuf/gdk-pixbuf-io.c
index 7e12ee6e1..9ad408748 100644
--- a/gdk-pixbuf/gdk-pixbuf-io.c
+++ b/gdk-pixbuf/gdk-pixbuf-io.c
@@ -76,6 +76,25 @@ format_check (GdkPixbufModule *module, guchar *buffer, int size)
return 0;
}
+G_LOCK_DEFINE_STATIC (init_lock);
+G_LOCK_DEFINE_STATIC (threadunsafe_loader_lock);
+
+void
+_gdk_pixbuf_lock (GdkPixbufModule *image_module)
+{
+ if (!(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
+ G_LOCK (threadunsafe_loader_lock);
+ }
+}
+
+void
+_gdk_pixbuf_unlock (GdkPixbufModule *image_module)
+{
+ if (!(image_module->info->flags & GDK_PIXBUF_FORMAT_THREADSAFE)) {
+ G_UNLOCK (threadunsafe_loader_lock);
+ }
+}
+
static GSList *file_formats = NULL;
static void gdk_pixbuf_io_init ();
@@ -83,8 +102,10 @@ static void gdk_pixbuf_io_init ();
static GSList *
get_file_formats (void)
{
+ G_LOCK (init_lock);
if (file_formats == NULL)
gdk_pixbuf_io_init ();
+ G_UNLOCK (init_lock);
return file_formats;
}
@@ -396,9 +417,9 @@ gdk_pixbuf_io_init (void)
/* actually load the image handler - gdk_pixbuf_get_module only get a */
/* reference to the module to load, it doesn't actually load it */
/* perhaps these actions should be combined in one function */
-gboolean
-_gdk_pixbuf_load_module (GdkPixbufModule *image_module,
- GError **error)
+static gboolean
+_gdk_pixbuf_load_module_unlocked (GdkPixbufModule *image_module,
+ GError **error)
{
char *path;
GModule *module;
@@ -433,6 +454,19 @@ _gdk_pixbuf_load_module (GdkPixbufModule *image_module,
return FALSE;
}
}
+
+gboolean
+_gdk_pixbuf_load_module (GdkPixbufModule *image_module,
+ GError **error)
+{
+ gboolean ret;
+
+ G_LOCK (init_lock);
+ ret = _gdk_pixbuf_load_module_unlocked (image_module, error);
+ G_UNLOCK (init_lock);
+
+ return ret;
+}
#else
#define module(type) \
@@ -593,11 +627,11 @@ gdk_pixbuf_io_init ()
};
gchar **name;
GdkPixbufModule *module = NULL;
-
+
for (name = included_formats; *name; name++) {
module = g_new0 (GdkPixbufModule, 1);
module->module_name = *name;
- if (_gdk_pixbuf_load_module (module, NULL))
+ if (_gdk_pixbuf_load_module_unlocked (module, NULL))
file_formats = g_slist_prepend (file_formats, module);
else
g_free (module);
@@ -703,37 +737,37 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
GdkPixbufAnimation *animation = NULL;
gpointer context;
- if (module->load != NULL)
- return (* module->load) (f, error);
-
- if (module->begin_load != NULL) {
+ _gdk_pixbuf_lock (module);
+
+ if (module->load != NULL) {
+ pixbuf = (* module->load) (f, error);
+ } else if (module->begin_load != NULL) {
context = module->begin_load (NULL, prepared_notify, NULL, &pixbuf, error);
if (!context)
- return NULL;
+ goto out;
while (!feof (f) && !ferror (f)) {
length = fread (buffer, 1, sizeof (buffer), f);
if (length > 0)
if (!module->load_increment (context, buffer, length, error)) {
module->stop_load (context, NULL);
- if (pixbuf != NULL)
+ if (pixbuf != NULL) {
g_object_unref (pixbuf);
- return NULL;
+ pixbuf = NULL;
+ }
+ goto out;
}
}
if (!module->stop_load (context, error)) {
- if (pixbuf != NULL)
+ if (pixbuf != NULL) {
g_object_unref (pixbuf);
- return NULL;
+ pixbuf = NULL;
+ }
}
-
- return pixbuf;
- }
-
- if (module->load_animation != NULL) {
+ } else if (module->load_animation != NULL) {
animation = (* module->load_animation) (f, error);
if (animation != NULL) {
pixbuf = gdk_pixbuf_animation_get_static_image (animation);
@@ -741,12 +775,12 @@ _gdk_pixbuf_generic_image_load (GdkPixbufModule *module,
g_object_ref (pixbuf);
g_object_unref (animation);
-
- return pixbuf;
}
}
- return NULL;
+ out:
+ _gdk_pixbuf_unlock (module);
+ return pixbuf;
}
/**
@@ -1134,14 +1168,18 @@ gdk_pixbuf_new_from_xpm_data (const char **data)
return NULL;
}
}
-
+
+ _gdk_pixbuf_lock (xpm_module);
+
if (xpm_module->load_xpm_data == NULL) {
g_warning ("gdk-pixbuf XPM module lacks XPM data capability");
- return NULL;
- } else
+ pixbuf = NULL;
+ } else {
load_xpm_data = xpm_module->load_xpm_data;
+ pixbuf = (* load_xpm_data) (data);
+ }
- pixbuf = (* load_xpm_data) (data);
+ _gdk_pixbuf_unlock (xpm_module);
return pixbuf;
}
@@ -1210,39 +1248,43 @@ gdk_pixbuf_real_save (GdkPixbuf *pixbuf,
gchar **values,
GError **error)
{
- GdkPixbufModule *image_module = NULL;
+ gboolean ret;
+ GdkPixbufModule *image_module = NULL;
- image_module = _gdk_pixbuf_get_named_module (type, error);
+ image_module = _gdk_pixbuf_get_named_module (type, error);
- if (image_module == NULL)
- return FALSE;
+ if (image_module == NULL)
+ return FALSE;
- if (image_module->module == NULL)
- if (!_gdk_pixbuf_load_module (image_module, error))
- return FALSE;
+ if (image_module->module == NULL)
+ if (!_gdk_pixbuf_load_module (image_module, error))
+ return FALSE;
- if (image_module->save) {
- /* save normally */
- return (* image_module->save) (filehandle, pixbuf,
+ _gdk_pixbuf_lock (image_module);
+
+ if (image_module->save) {
+ /* save normally */
+ ret = (* image_module->save) (filehandle, pixbuf,
keys, values,
error);
- }
- else if (image_module->save_to_callback) {
- /* save with simple callback */
- return (* image_module->save_to_callback) (save_to_file_callback,
+ } else if (image_module->save_to_callback) {
+ /* save with simple callback */
+ ret = (* image_module->save_to_callback) (save_to_file_callback,
filehandle, pixbuf,
keys, values,
error);
- }
- else {
- /* can't save */
- g_set_error (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
- _("This build of gdk-pixbuf does not support saving the image format: %s"),
- type);
- return FALSE;
- }
+ } else {
+ /* can't save */
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
+ _("This build of gdk-pixbuf does not support saving the image format: %s"),
+ type);
+ ret = FALSE;
+ }
+
+ _gdk_pixbuf_unlock (image_module);
+ return ret;
}
#define TMP_FILE_BUF_SIZE 4096
@@ -1283,8 +1325,13 @@ save_to_callback_with_tmp_file (GdkPixbufModule *image_module,
_("Failed to open temporary file"));
goto end;
}
- if (!(* image_module->save) (f, pixbuf, keys, values, error))
+
+ _gdk_pixbuf_lock (image_module);
+ retval = (image_module->save) (f, pixbuf, keys, values, error);
+ _gdk_pixbuf_unlock (image_module);
+ if (!retval)
goto end;
+
rewind (f);
for (;;) {
n = fread (buf, 1, TMP_FILE_BUF_SIZE, f);
@@ -1326,39 +1373,43 @@ gdk_pixbuf_real_save_to_callback (GdkPixbuf *pixbuf,
gchar **values,
GError **error)
{
- GdkPixbufModule *image_module = NULL;
+ gboolean ret;
+ GdkPixbufModule *image_module = NULL;
- image_module = _gdk_pixbuf_get_named_module (type, error);
+ image_module = _gdk_pixbuf_get_named_module (type, error);
- if (image_module == NULL)
- return FALSE;
+ if (image_module == NULL)
+ return FALSE;
- if (image_module->module == NULL)
- if (!_gdk_pixbuf_load_module (image_module, error))
- return FALSE;
+ if (image_module->module == NULL)
+ if (!_gdk_pixbuf_load_module (image_module, error))
+ return FALSE;
+
+ _gdk_pixbuf_lock (image_module);
- if (image_module->save_to_callback) {
- /* save normally */
- return (* image_module->save_to_callback) (save_func, user_data,
+ if (image_module->save_to_callback) {
+ /* save normally */
+ ret = (* image_module->save_to_callback) (save_func, user_data,
pixbuf, keys, values,
error);
- }
- else if (image_module->save) {
- /* use a temporary file */
- return save_to_callback_with_tmp_file (image_module, pixbuf,
+ } else if (image_module->save) {
+ /* use a temporary file */
+ ret = save_to_callback_with_tmp_file (image_module, pixbuf,
save_func, user_data,
keys, values,
error);
- }
- else {
- /* can't save */
- g_set_error (error,
- GDK_PIXBUF_ERROR,
- GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
- _("This build of gdk-pixbuf does not support saving the image format: %s"),
- type);
- return FALSE;
- }
+ } else {
+ /* can't save */
+ g_set_error (error,
+ GDK_PIXBUF_ERROR,
+ GDK_PIXBUF_ERROR_UNSUPPORTED_OPERATION,
+ _("This build of gdk-pixbuf does not support saving the image format: %s"),
+ type);
+ ret = FALSE;
+ }
+
+ _gdk_pixbuf_unlock (image_module);
+ return ret;
}
diff --git a/gdk-pixbuf/gdk-pixbuf-io.h b/gdk-pixbuf/gdk-pixbuf-io.h
index 3eafd5f82..e64bee7e0 100644
--- a/gdk-pixbuf/gdk-pixbuf-io.h
+++ b/gdk-pixbuf/gdk-pixbuf-io.h
@@ -144,7 +144,8 @@ gboolean gdk_pixbuf_set_option (GdkPixbuf *pixbuf,
typedef enum /*< skip >*/
{
GDK_PIXBUF_FORMAT_WRITABLE = 1 << 0,
- GDK_PIXBUF_FORMAT_SCALABLE = 1 << 1
+ GDK_PIXBUF_FORMAT_SCALABLE = 1 << 1,
+ GDK_PIXBUF_FORMAT_THREADSAFE = 1 << 2
} GdkPixbufFormatFlags;
struct _GdkPixbufFormat {
diff --git a/gdk-pixbuf/gdk-pixbuf-loader.c b/gdk-pixbuf/gdk-pixbuf-loader.c
index b5c53d603..0ce63605d 100644
--- a/gdk-pixbuf/gdk-pixbuf-loader.c
+++ b/gdk-pixbuf/gdk-pixbuf-loader.c
@@ -50,7 +50,6 @@ static void gdk_pixbuf_loader_finalize (GObject *loader);
static gpointer parent_class = NULL;
static guint pixbuf_loader_signals[LAST_SIGNAL] = { 0 };
-
/* Internal data */
#define LOADER_HEADER_SIZE 128
@@ -59,6 +58,7 @@ typedef struct
{
GdkPixbufAnimation *animation;
gboolean closed;
+ gboolean holds_threadlock;
guchar header_buf[LOADER_HEADER_SIZE];
gint header_buf_offset;
GdkPixbufModule *image_module;
@@ -225,8 +225,12 @@ gdk_pixbuf_loader_finalize (GObject *object)
loader = GDK_PIXBUF_LOADER (object);
priv = loader->priv;
- if (!priv->closed)
+ if (!priv->closed) {
g_warning ("GdkPixbufLoader finalized without calling gdk_pixbuf_loader_close() - this is not allowed. You must explicitly end the data stream to the loader before dropping the last reference.");
+ if (priv->holds_threadlock) {
+ _gdk_pixbuf_unlock (priv->image_module);
+ }
+ }
if (priv->animation)
g_object_unref (priv->animation);
@@ -382,6 +386,11 @@ gdk_pixbuf_loader_load_module (GdkPixbufLoader *loader,
return 0;
}
+ if (!priv->holds_threadlock) {
+ _gdk_pixbuf_lock (priv->image_module);
+ priv->holds_threadlock = TRUE;
+ }
+
priv->context = priv->image_module->begin_load (gdk_pixbuf_loader_size_func,
gdk_pixbuf_loader_prepare,
gdk_pixbuf_loader_update,
@@ -736,6 +745,11 @@ gdk_pixbuf_loader_close (GdkPixbufLoader *loader,
}
priv->closed = TRUE;
+ if (priv->image_module) {
+ g_assert (priv->holds_threadlock);
+ _gdk_pixbuf_unlock (priv->image_module);
+ priv->holds_threadlock = FALSE;
+ }
if (priv->needs_scale)
{
diff --git a/gdk-pixbuf/gdk-pixbuf-private.h b/gdk-pixbuf/gdk-pixbuf-private.h
index e81478f99..59053a99d 100644
--- a/gdk-pixbuf/gdk-pixbuf-private.h
+++ b/gdk-pixbuf/gdk-pixbuf-private.h
@@ -79,6 +79,9 @@ struct _GdkPixbufClass {
#ifdef GDK_PIXBUF_ENABLE_BACKEND
+void _gdk_pixbuf_lock (GdkPixbufModule *image_module);
+void _gdk_pixbuf_unlock (GdkPixbufModule *image_module);
+
GdkPixbufModule *_gdk_pixbuf_get_module (guchar *buffer, guint size,
const gchar *filename,
GError **error);
diff --git a/gdk-pixbuf/io-ani.c b/gdk-pixbuf/io-ani.c
index 5e7b6beb9..5568ad65d 100644
--- a/gdk-pixbuf/io-ani.c
+++ b/gdk-pixbuf/io-ani.c
@@ -676,7 +676,7 @@ MODULE_ENTRY (ani, fill_info) (GdkPixbufFormat *info)
info->description = N_("The ANI image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-bmp.c b/gdk-pixbuf/io-bmp.c
index 015eca8da..14b7caa93 100644
--- a/gdk-pixbuf/io-bmp.c
+++ b/gdk-pixbuf/io-bmp.c
@@ -1132,7 +1132,7 @@ MODULE_ENTRY (bmp, fill_info) (GdkPixbufFormat *info)
info->description = N_("The BMP image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-gif.c b/gdk-pixbuf/io-gif.c
index 1320922e7..fd78e586a 100644
--- a/gdk-pixbuf/io-gif.c
+++ b/gdk-pixbuf/io-gif.c
@@ -1643,6 +1643,6 @@ MODULE_ENTRY (gif, fill_info) (GdkPixbufFormat *info)
info->description = N_("The GIF image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-ico.c b/gdk-pixbuf/io-ico.c
index 86612dd71..022c93a3c 100644
--- a/gdk-pixbuf/io-ico.c
+++ b/gdk-pixbuf/io-ico.c
@@ -1210,7 +1210,7 @@ MODULE_ENTRY (ico, fill_info) (GdkPixbufFormat *info)
info->description = N_("The ICO image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = GDK_PIXBUF_FORMAT_WRITABLE;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-jpeg.c b/gdk-pixbuf/io-jpeg.c
index 1bf4bede1..7f2159476 100644
--- a/gdk-pixbuf/io-jpeg.c
+++ b/gdk-pixbuf/io-jpeg.c
@@ -1071,6 +1071,6 @@ MODULE_ENTRY (jpeg, fill_info) (GdkPixbufFormat *info)
info->description = N_("The JPEG image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = GDK_PIXBUF_FORMAT_WRITABLE;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-pcx.c b/gdk-pixbuf/io-pcx.c
index 0b1f9b159..d1042cb7d 100644
--- a/gdk-pixbuf/io-pcx.c
+++ b/gdk-pixbuf/io-pcx.c
@@ -758,6 +758,6 @@ MODULE_ENTRY (pcx, fill_info) (GdkPixbufFormat *info)
info->description = N_("The PCX image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-png.c b/gdk-pixbuf/io-png.c
index 3d4501fa2..7e9fb36de 100644
--- a/gdk-pixbuf/io-png.c
+++ b/gdk-pixbuf/io-png.c
@@ -994,6 +994,6 @@ MODULE_ENTRY (png, fill_info) (GdkPixbufFormat *info)
info->description = N_("The PNG image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = GDK_PIXBUF_FORMAT_WRITABLE;
+ info->flags = GDK_PIXBUF_FORMAT_WRITABLE | GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-pnm.c b/gdk-pixbuf/io-pnm.c
index 7d9401450..4d2fb1ff3 100644
--- a/gdk-pixbuf/io-pnm.c
+++ b/gdk-pixbuf/io-pnm.c
@@ -1082,6 +1082,6 @@ MODULE_ENTRY (pnm, fill_info) (GdkPixbufFormat *info)
info->description = N_("The PNM/PBM/PGM/PPM image format family");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-ras.c b/gdk-pixbuf/io-ras.c
index 9fe936161..6c20654c2 100644
--- a/gdk-pixbuf/io-ras.c
+++ b/gdk-pixbuf/io-ras.c
@@ -543,7 +543,7 @@ MODULE_ENTRY (ras, fill_info) (GdkPixbufFormat *info)
info->description = N_("The Sun raster image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-tga.c b/gdk-pixbuf/io-tga.c
index f4102bdf2..2dc753822 100644
--- a/gdk-pixbuf/io-tga.c
+++ b/gdk-pixbuf/io-tga.c
@@ -995,6 +995,6 @@ MODULE_ENTRY (tga, fill_info) (GdkPixbufFormat *info)
info->description = N_("The Targa image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-tiff.c b/gdk-pixbuf/io-tiff.c
index 9beb045b0..c58d9cb49 100644
--- a/gdk-pixbuf/io-tiff.c
+++ b/gdk-pixbuf/io-tiff.c
@@ -62,10 +62,6 @@ struct _TiffContext
-/* There's no user data for the error handlers, so we just have to
- * put a big-ass lock on the whole TIFF loader
- */
-G_LOCK_DEFINE_STATIC (tiff_loader);
static char *global_error = NULL;
static TIFFErrorHandler orig_error_handler = NULL;
static TIFFErrorHandler orig_warning_handler = NULL;
@@ -242,10 +238,8 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
return NULL;
}
- G_UNLOCK (tiff_loader);
if (context)
(* context->prepare_func) (pixbuf, NULL, context->user_data);
- G_LOCK (tiff_loader);
#if TIFFLIB_VERSION >= 20031226
if (tifflibversion(&major, &minor, &revision) && major == 3 &&
@@ -330,10 +324,8 @@ tiff_image_parse (TIFF *tiff, TiffContext *context, GError **error)
_TIFFfree (rast);
}
- G_UNLOCK (tiff_loader);
if (context)
(* context->update_func) (pixbuf, 0, 0, width, height, context->user_data);
- G_LOCK (tiff_loader);
return pixbuf;
}
@@ -351,8 +343,6 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
g_return_val_if_fail (f != NULL, NULL);
- G_LOCK (tiff_loader);
-
tiff_push_handlers ();
fd = fileno (f);
@@ -371,7 +361,6 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
_("Failed to open TIFF image"));
tiff_pop_handlers ();
- G_UNLOCK (tiff_loader);
return NULL;
}
@@ -386,8 +375,6 @@ gdk_pixbuf__tiff_image_load (FILE *f, GError **error)
tiff_pop_handlers ();
- G_UNLOCK (tiff_loader);
-
return pixbuf;
}
@@ -504,8 +491,6 @@ gdk_pixbuf__tiff_image_stop_load (gpointer data,
g_return_val_if_fail (data != NULL, FALSE);
- G_LOCK (tiff_loader);
-
tiff_push_handlers ();
tiff = TIFFClientOpen ("libtiff-pixbuf", "r", data,
@@ -546,8 +531,6 @@ gdk_pixbuf__tiff_image_stop_load (gpointer data,
tiff_pop_handlers ();
- G_UNLOCK (tiff_loader);
-
return retval;
}
@@ -627,6 +610,7 @@ MODULE_ENTRY (tiff, fill_info) (GdkPixbufFormat *info)
info->description = N_("The TIFF image format");
info->mime_types = mime_types;
info->extensions = extensions;
+ /* not threadsafe, due the the error handler handling */
info->flags = 0;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-wbmp.c b/gdk-pixbuf/io-wbmp.c
index 098c8c805..24779b97e 100644
--- a/gdk-pixbuf/io-wbmp.c
+++ b/gdk-pixbuf/io-wbmp.c
@@ -368,6 +368,6 @@ MODULE_ENTRY (wbmp, fill_info) (GdkPixbufFormat *info)
info->description = N_("The WBMP image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-xbm.c b/gdk-pixbuf/io-xbm.c
index 45d4be79e..6c9244cf6 100644
--- a/gdk-pixbuf/io-xbm.c
+++ b/gdk-pixbuf/io-xbm.c
@@ -476,6 +476,6 @@ MODULE_ENTRY (xbm, fill_info) (GdkPixbufFormat *info)
info->description = N_("The XBM image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}
diff --git a/gdk-pixbuf/io-xpm.c b/gdk-pixbuf/io-xpm.c
index 67b1b011e..f8267d5b7 100644
--- a/gdk-pixbuf/io-xpm.c
+++ b/gdk-pixbuf/io-xpm.c
@@ -1559,6 +1559,6 @@ MODULE_ENTRY (xpm, fill_info) (GdkPixbufFormat *info)
info->description = N_("The XPM image format");
info->mime_types = mime_types;
info->extensions = extensions;
- info->flags = 0;
+ info->flags = GDK_PIXBUF_FORMAT_THREADSAFE;
info->license = "LGPL";
}