Revision: 1110
http://geeqie.svn.sourceforge.net/geeqie/?rev=1110&view=rev
Author: nadvornik
Date: 2008-08-30 20:15:47 +0000 (Sat, 30 Aug 2008)
Log Message:
-----------
run image loader in separate thread
this feature is disabled by default for now, it must be enabled by
configure --enable-threads
Modified Paths:
--------------
trunk/configure.in
trunk/src/Makefile.am
trunk/src/image-load.c
trunk/src/image-load.h
trunk/src/main.c
Modified: trunk/configure.in
===================================================================
--- trunk/configure.in 2008-08-30 13:04:06 UTC (rev 1109)
+++ trunk/configure.in 2008-08-30 20:15:47 UTC (rev 1110)
@@ -167,21 +167,6 @@
AM_CONDITIONAL(HAVE_WINDRES, test "x$WINDRES" != "x:")
AC_SUBST(WINDRES)
-have_libpthread=no
-AC_CHECK_LIB([pthread], [main],
- [AC_CHECK_HEADER([pthread.h],
- have_libpthread=yes,
- have_libpthread=no)],
- [AC_MSG_ERROR([Can't find the POSIX thread libraries])], [-lpthread])
-if test "x${have_libpthread}" = "xyes"; then
- LIBPTHREAD='-lpthread'
- AC_DEFINE(HAVE_LIBPTHREAD, 1, [Define if pthread is available])
-else
- AC_MSG_WARN([POSIX thread header not installed])
-fi
-AC_MSG_CHECKING(for libpthread)
-AC_MSG_RESULT([${have_libpthread}])
-
dnl reasonable guesses for where stuff is installed
if test "x$prefix" = "xNONE"; then
prefix="/usr/local"
@@ -189,7 +174,26 @@
prefix=$prefix
fi
+AM_PATH_GLIB_2_0(2.4.0,,AC_MSG_ERROR(GLIB >= 2.4.0 not installed.))
AM_PATH_GTK_2_0(2.4.0,,AC_MSG_ERROR(GTK+ >= 2.4.0 not installed.))
+
+have_gthread="no"
+AC_ARG_ENABLE([threads],
+ AC_HELP_STRING([--enable-threads], [enable thread support]),
+[
+if test "x${enableval}" = "xyes"; then
+ PKG_CHECK_MODULES(GTHREAD, [gthread-2.0], have_gthread="yes",
[AC_MSG_WARN("No thread support in glib")])
+fi
+], )
+
+
+if test "x$have_gthread" != "xno"; then
+ AC_DEFINE(HAVE_GTHREAD, 1, Define if you have gthread library)
+ GLIB_CFLAGS="$GTHREAD_CFLAGS"
+ GLIB_LIBS="$GTHREAD_LIBS"
+fi
+
+
AC_PATH_PROGS(GDK_PIXBUF_CSOURCE, "gdk-pixbuf-csource")
AC_PATH_PROG(GLIB_GENMARSHAL, glib-genmarshal)
@@ -376,7 +380,7 @@
CXXFLAGS: $CXXFLAGS
Gtk: $GTK_CFLAGS
Glib: $GLIB_CFLAGS
- Thread: $LIBPTHREAD
+ Thread: $GTHREAD_LIBS
Others: $LCMS_LIBS $EXIV2_LIBS
Localization:
Modified: trunk/src/Makefile.am
===================================================================
--- trunk/src/Makefile.am 2008-08-30 13:04:06 UTC (rev 1109)
+++ trunk/src/Makefile.am 2008-08-30 20:15:47 UTC (rev 1110)
@@ -123,6 +123,7 @@
filefilter.h \
gq-marshal.c \
gq-marshal.h \
+ gq-marshal.list \
format_canon.c \
format_canon.h \
format_fuji.c \
Modified: trunk/src/image-load.c
===================================================================
--- trunk/src/image-load.c 2008-08-30 13:04:06 UTC (rev 1109)
+++ trunk/src/image-load.c 2008-08-30 20:15:47 UTC (rev 1110)
@@ -85,6 +85,10 @@
il->requested_width = 0;
il->requested_height = 0;
il->shrunk = FALSE;
+
+#ifdef HAVE_GTHREAD
+ il->data_mutex = g_mutex_new();
+#endif
DEBUG_1("new image loader %p, bufsize=%u idle_loop=%u", il,
il->read_buffer_size, il->idle_read_loop_count);
}
@@ -167,6 +171,9 @@
if (il->pixbuf) gdk_pixbuf_unref(il->pixbuf);
file_data_unref(il->fd);
+#ifdef HAVE_GTHREAD
+ g_mutex_free(il->data_mutex);
+#endif
}
void image_loader_free(ImageLoader *il)
@@ -207,8 +214,10 @@
ImageLoaderAreaParam *par = data;
ImageLoader *il = par->il;
g_signal_emit(il, signals[SIGNAL_AREA_READY], 0, par->x, par->y,
par->w, par->h);
+ g_mutex_lock(il->data_mutex);
il->area_param_list = g_list_remove(il->area_param_list, par);
g_free(par);
+ g_mutex_unlock(il->data_mutex);
return FALSE;
}
@@ -230,7 +239,7 @@
static gint image_loader_emit_percent_cb(gpointer data)
{
ImageLoader *il = data;
- g_signal_emit(il, signals[SIGNAL_PERCENT], 0, (gdouble)il->bytes_read /
il->bytes_total);
+ g_signal_emit(il, signals[SIGNAL_PERCENT], 0,
image_loader_get_percent(il));
return FALSE;
}
@@ -262,7 +271,10 @@
par->w = w;
par->h = h;
+ g_mutex_lock(il->data_mutex);
il->area_param_list = g_list_prepend(il->area_param_list, par);
+ g_mutex_unlock(il->data_mutex);
+
g_idle_add_full(G_PRIORITY_HIGH, image_loader_emit_area_ready_cb, par,
NULL);
}
@@ -272,16 +284,27 @@
static void image_loader_sync_pixbuf(ImageLoader *il)
{
GdkPixbuf *pb;
+
+ g_mutex_lock(il->data_mutex);
+
+ if (!il->loader)
+ {
+ g_mutex_unlock(il->data_mutex);
+ return;
+ }
- if (!il->loader) return;
-
pb = gdk_pixbuf_loader_get_pixbuf(il->loader);
- if (pb == il->pixbuf) return;
+ if (pb == il->pixbuf)
+ {
+ g_mutex_unlock(il->data_mutex);
+ return;
+ }
if (il->pixbuf) gdk_pixbuf_unref(il->pixbuf);
il->pixbuf = pb;
if (il->pixbuf) gdk_pixbuf_ref(il->pixbuf);
+ g_mutex_unlock(il->data_mutex);
}
static void image_loader_area_updated_cb(GdkPixbufLoader *loader,
@@ -290,10 +313,10 @@
{
ImageLoader *il = data;
- if (!il->pixbuf)
+ if (!image_loader_get_pixbuf(il))
{
image_loader_sync_pixbuf(il);
- if (!il->pixbuf)
+ if (!image_loader_get_pixbuf(il))
{
log_printf("critical: area_ready signal with NULL
pixbuf (out of mem?)\n");
}
@@ -336,7 +359,13 @@
gint scale = FALSE;
gint n;
- if (il->requested_width < 1 || il->requested_height < 1) return;
+ g_mutex_lock(il->data_mutex);
+ if (il->requested_width < 1 || il->requested_height < 1)
+ {
+ g_mutex_unlock(il->data_mutex);
+ return;
+ }
+ g_mutex_unlock(il->data_mutex);
format = gdk_pixbuf_loader_get_format(loader);
if (!format) return;
@@ -352,6 +381,8 @@
if (!scale) return;
+ g_mutex_lock(il->data_mutex);
+
if (width > il->requested_width || height > il->requested_height)
{
gint nw, nh;
@@ -372,6 +403,8 @@
gdk_pixbuf_loader_set_size(loader, nw, nh);
il->shrunk = TRUE;
}
+ g_mutex_unlock(il->data_mutex);
+
}
static void image_loader_stop_loader(ImageLoader *il)
@@ -392,7 +425,10 @@
static void image_loader_setup_loader(ImageLoader *il)
{
+ g_mutex_lock(il->data_mutex);
il->loader = gdk_pixbuf_loader_new();
+ g_mutex_unlock(il->data_mutex);
+
g_signal_connect(G_OBJECT(il->loader), "area_updated",
G_CALLBACK(image_loader_area_updated_cb), il);
g_signal_connect(G_OBJECT(il->loader), "size_prepared",
@@ -606,6 +642,11 @@
il->idle_id = -1;
}
+ if (il->thread)
+ {
+ il->stopping = TRUE;
+ g_thread_join(il->thread);
+ }
image_loader_stop_loader(il);
image_loader_stop_source(il);
@@ -647,6 +688,36 @@
}
/**************************************************************************************/
+/* execution via thread */
+
+gpointer image_loader_thread_run(gpointer data)
+{
+ ImageLoader *il = data;
+ gint cont = image_loader_begin(il);
+
+ while (cont && !il->done && !il->stopping)
+ {
+ cont = image_loader_continue(il);
+ }
+ return NULL;
+}
+
+gint image_loader_start_thread(ImageLoader *il)
+{
+ if (!il) return FALSE;
+
+ if (!il->fd) return FALSE;
+
+ if (!image_loader_setup_source(il)) return FALSE;
+
+ il->thread = g_thread_create(image_loader_thread_run, il, TRUE, NULL);
+ if (!il->thread) return FALSE;
+
+ return TRUE;
+}
+
+
+/**************************************************************************************/
/* public interface */
@@ -656,16 +727,24 @@
if (!il->fd) return FALSE;
+#ifdef HAVE_GTHREAD
+ return image_loader_start_thread(il);
+#else
return image_loader_start_idle(il);
+#endif
}
/* don't forget to gdk_pixbuf_ref() it if you want to use it after
image_loader_free() */
GdkPixbuf *image_loader_get_pixbuf(ImageLoader *il)
{
+ GdkPixbuf *ret;
if (!il) return NULL;
-
- return il->pixbuf;
+
+ g_mutex_lock(il->data_mutex);
+ ret = il->pixbuf;
+ g_mutex_unlock(il->data_mutex);
+ return ret;
}
gchar *image_loader_get_format(ImageLoader *il)
@@ -693,53 +772,82 @@
{
if (!il) return;
+ g_mutex_lock(il->data_mutex);
il->requested_width = width;
il->requested_height = height;
+ g_mutex_unlock(il->data_mutex);
}
void image_loader_set_buffer_size(ImageLoader *il, guint count)
{
if (!il) return;
+ g_mutex_lock(il->data_mutex);
il->idle_read_loop_count = count ? count : 1;
+ g_mutex_unlock(il->data_mutex);
}
void image_loader_set_priority(ImageLoader *il, gint priority)
{
if (!il) return;
+ g_mutex_lock(il->data_mutex);
il->idle_priority = priority;
+ g_mutex_unlock(il->data_mutex);
}
gdouble image_loader_get_percent(ImageLoader *il)
{
- if (!il || il->bytes_total == 0) return 0.0;
-
- return (gdouble)il->bytes_read / il->bytes_total;
+ gdouble ret;
+ if (!il) return 0.0;
+
+ g_mutex_lock(il->data_mutex);
+ if (il->bytes_total == 0)
+ {
+ ret = 0.0;
+ }
+ else
+ {
+ ret = (gdouble)il->bytes_read / il->bytes_total;
+ }
+ g_mutex_unlock(il->data_mutex);
+ return ret;
}
gint image_loader_get_is_done(ImageLoader *il)
{
+ gint ret;
if (!il) return FALSE;
- return il->done;
+ g_mutex_lock(il->data_mutex);
+ ret = il->done;
+ g_mutex_unlock(il->data_mutex);
+
+ return ret;
}
FileData *image_loader_get_fd(ImageLoader *il)
{
+ FileData *ret;
if (!il) return NULL;
- return il->fd;
-
+ g_mutex_lock(il->data_mutex);
+ ret = il->fd;
+ g_mutex_unlock(il->data_mutex);
+
+ return ret;
}
gint image_loader_get_shrunk(ImageLoader *il)
{
+ gint ret;
if (!il) return FALSE;
- return il->shrunk;
-
+ g_mutex_lock(il->data_mutex);
+ ret = il->shrunk;
+ g_mutex_unlock(il->data_mutex);
+ return ret;
}
Modified: trunk/src/image-load.h
===================================================================
--- trunk/src/image-load.h 2008-08-30 13:04:06 UTC (rev 1109)
+++ trunk/src/image-load.h 2008-08-30 20:15:47 UTC (rev 1110)
@@ -45,6 +45,10 @@
gint idle_done_id;
GList *area_param_list;
+
+ GThread *thread;
+ GMutex *data_mutex;
+ gint stopping;
guchar *mapped_file;
gint read_buffer_size;
Modified: trunk/src/main.c
===================================================================
--- trunk/src/main.c 2008-08-30 13:04:06 UTC (rev 1109)
+++ trunk/src/main.c 2008-08-30 20:15:47 UTC (rev 1110)
@@ -669,6 +669,10 @@
gchar *bufl;
CollectionData *cd = NULL;
+#ifdef HAVE_GTHREAD
+ g_thread_init (NULL);
+#endif
+
/* init execution time counter (debug only) */
init_exec_time();
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Geeqie-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geeqie-svn