MooAsyncJob

This commit is contained in:
Yevgen Muntyan 2008-08-27 23:03:37 -05:00
parent 5cfd19a67e
commit 0f389b62b6
4 changed files with 244 additions and 6 deletions

View File

@ -29,6 +29,7 @@ thread_sources = \
mooutils-thread.h
mooutils_sources = \
$(thread_sources) \
mdhistorymgr.c \
mdhistorymgr.h \
moo-environ.h \
@ -147,11 +148,7 @@ mooutils_sources = \
moopython.lo: mooutils-fli.lo
if MOO_OS_MINGW
mooutils_sources += $(thread_sources) $(win32_sources)
else
if MOO_ENABLE_TESTS
mooutils_sources += $(thread_sources)
endif
mooutils_sources += $(win32_sources)
endif
if MOO_ENABLE_UNIT_TESTS
mooutils_sources += $(test_sources)
@ -160,7 +157,6 @@ endif
EXTRA_DIST += \
moo-intltool-merge \
py2h.sh \
$(thread_sources) \
$(win32_sources) \
$(test_sources) \
moowin32/mingw/fnmatch.h \

View File

@ -20,6 +20,7 @@
#include "mooutils/mooutils-treeview.h"
#include "mooutils/moomarkup.h"
#include "mooutils/mooprefs.h"
#include "mooutils/mooutils-thread.h"
#include "marshals.h"
#include <stdarg.h>
@ -1157,6 +1158,56 @@ create_tree_view (void)
return tree_view;
}
// typedef struct {
// GtkWidget *tree_view;
// GtkListStore *store;
// GQueue *files;
// GList *link;
// } Data;
//
// typedef struct {
// GdkPixbuf *pixbuf;
// char *display_basename;
// char *display_name;
// char *uri;
// } Entry;
// static gboolean
// thread_func (gpointer user_data)
// {
// Data *data = user_data;
// int i;
//
// for (i = 0; i < 100 && data->link != data->files->tail; ++i, data->link = data->link->next)
// {
// MdHistoryItem *item = data->link->data;
// char *display_name, *display_basename;
// GdkPixbuf *pixbuf;
// GtkTreeIter iter;
//
// display_basename = uri_get_basename (item->uri);
// display_name = uri_get_display_name (item->uri);
//
// gdk_threads_enter ();
// /* XXX */
// pixbuf = _moo_get_icon_for_path (display_name, data->tree_view, GTK_ICON_SIZE_MENU);
// gdk_threads_leave ();
//
// gtk_list_store_append (data->store, &iter);
// gtk_list_store_set (data->store, &iter,
// COLUMN_PIXBUF, pixbuf,
// COLUMN_NAME, display_basename,
// COLUMN_TOOLTIP, display_name,
// COLUMN_URI, md_history_item_get_uri (item),
// -1);
//
// g_free (display_basename);
// g_free (display_name);
// }
//
// return data->link != data->files->tail;
// }
static void
populate_tree_view (MdHistoryMgr *mgr,
GtkWidget *tree_view)
@ -1170,6 +1221,17 @@ populate_tree_view (MdHistoryMgr *mgr,
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
store = GTK_LIST_STORE (model);
// {
// Data *data = g_new0 (Data, 1);
// data->tree_view = tree_view;
// data->store = store;
// data->files = mgr->priv->files;
// data->link = mgr->priv->files->head;
// MooAsyncJob *job = moo_async_job_new (thread_func, data, g_free);
// moo_async_job_start (job);
// moo_async_job_unref (job);
// }
for (l = mgr->priv->files->head; l != NULL; l = l->next)
{
MdHistoryItem *item = l->data;

View File

@ -14,6 +14,7 @@
#include "mooutils/mooutils-thread.h"
#include "mooutils/mooutils-misc.h"
#include "mooutils/mooutils-debug.h"
#include "mooutils/mootype-macros.h"
#include <stdio.h>
#include <errno.h>
@ -372,3 +373,172 @@ _moo_message_async (const char *format,
_moo_event_queue_push (message_event_id, msg, g_free);
}
}
struct MooAsyncJob {
GObject base;
MooAsyncJobCallback callback;
gpointer data;
GDestroyNotify data_notify;
GThread *thread;
GMutex *mutex;
guint cancelled : 1;
};
typedef struct {
GObjectClass base_class;
} MooAsyncJobClass;
MOO_DEFINE_TYPE_STATIC (MooAsyncJob, moo_async_job, G_TYPE_OBJECT)
static void
moo_async_job_dispose (GObject *object)
{
MooAsyncJob *job = (MooAsyncJob*) object;
if (job->data_notify)
{
GDestroyNotify notify = job->data_notify;
job->data_notify = NULL;
notify (job->data);
job->data = NULL;
}
g_assert (!job->thread);
if (job->mutex)
{
g_mutex_free (job->mutex);
job->mutex = NULL;
}
G_OBJECT_CLASS (moo_async_job_parent_class)->dispose (object);
}
static void
moo_async_job_class_init (MooAsyncJobClass *klass)
{
G_OBJECT_CLASS (klass)->dispose = moo_async_job_dispose;
}
static void
moo_async_job_init (MooAsyncJob *job)
{
job->callback = NULL;
job->data = NULL;
job->data_notify = NULL;
job->thread = NULL;
job->mutex = g_mutex_new ();
job->cancelled = FALSE;
}
MooAsyncJob *
moo_async_job_new (MooAsyncJobCallback callback,
gpointer data,
GDestroyNotify data_notify)
{
MooAsyncJob *job;
g_return_val_if_fail (callback != NULL, NULL);
job = g_object_new (moo_async_job_get_type (), NULL);
job->callback = callback;
job->data = data;
job->data_notify = data_notify;
return job;
}
static gpointer
moo_async_job_thread_func (MooAsyncJob *job)
{
gboolean proceed = TRUE;
while (proceed)
{
g_mutex_lock (job->mutex);
if (job->cancelled)
{
_moo_print_async ("%s: job cancelled\n", G_STRFUNC);
g_mutex_unlock (job->mutex);
break;
}
g_mutex_unlock (job->mutex);
proceed = job->callback (job->data);
if (!proceed)
_moo_print_async ("%s: job finished\n", G_STRFUNC);
if (proceed)
g_usleep (1000);
}
g_mutex_lock (job->mutex);
if (job->data_notify)
{
GDestroyNotify notify = job->data_notify;
job->data_notify = NULL;
notify (job->data);
}
job->thread = NULL;
g_mutex_unlock (job->mutex);
g_object_unref (job);
return NULL;
}
void
moo_async_job_start (MooAsyncJob *job)
{
GError *error = NULL;
g_return_if_fail (job != NULL);
g_return_if_fail (job->thread == NULL);
g_mutex_lock (job->mutex);
job->thread = g_thread_create ((GThreadFunc) moo_async_job_thread_func,
g_object_ref (job),
FALSE, &error);
if (!job->thread)
{
g_critical ("%s: could not start thread: %s", G_STRLOC, error->message);
g_error_free (error);
goto out;
}
out:
g_mutex_unlock (job->mutex);
}
void
moo_async_job_cancel (MooAsyncJob *job)
{
g_return_if_fail (job != NULL);
g_mutex_lock (job->mutex);
job->cancelled = TRUE;
g_mutex_unlock (job->mutex);
}
void
moo_async_job_ref (MooAsyncJob *job)
{
g_return_if_fail (job != NULL);
g_object_ref (job);
}
void
moo_async_job_unref (MooAsyncJob *job)
{
g_return_if_fail (job != NULL);
g_object_unref (job);
}

View File

@ -21,6 +21,16 @@ G_BEGIN_DECLS
typedef void (*MooEventQueueCallback) (GList *events,
gpointer data);
typedef struct MooAsyncJob MooAsyncJob;
typedef gboolean (*MooAsyncJobCallback) (gpointer data);
MooAsyncJob *moo_async_job_new (MooAsyncJobCallback callback,
gpointer data,
GDestroyNotify data_notify);
void moo_async_job_start (MooAsyncJob *job);
void moo_async_job_cancel (MooAsyncJob *job);
void moo_async_job_ref (MooAsyncJob *job);
void moo_async_job_unref (MooAsyncJob *job);
guint _moo_event_queue_connect (MooEventQueueCallback callback,
gpointer data,