summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkira TAGOH <akira@tagoh.org>2006-09-04 11:33:05 +0000
committerAkira TAGOH <akira@tagoh.org>2006-09-04 11:33:05 +0000
commitbb8ae6d506fd5cc8bde650f9d844b8607d6894c3 (patch)
tree1373d3722487d9347ebcd2c31c5a02138c3cf63f
parentfe86d53f31d34426589c3af57db6611cb4539aed (diff)
* hieroglyph/hglist.c (_hg_list_iter_real_set_data): new function.
(hg_list_init): new function. (hg_list_finalize): new function. (hg_list_first): new function. (hg_list_last): new function. (hg_list_iter_new): use own memory pool to avoid an allocation failure, because it's quite likely so that it's used under set_flags where could be invoked during GC. (hg_list_iter_get_data): renamed. (hg_list_iter_set_data): new function. (hg_list_iter_set_object): new function. (hg_list_iter_delete_link): new function. (hg_list_find_iter): new function. (hg_list_find_iter_custom): new function. * hieroglyph/vm.c (_hg_vm_eval_file): allow NULL to not want to get an error result. * src/hgspy.c (_hgspy_quit_cb): try to shutdown VM. * hieroglyph/hgallocator-bfit.c (_hg_allocator_bfit_remove_block):
-rw-r--r--ChangeLog22
-rw-r--r--hieroglyph/hglist.c194
-rw-r--r--hieroglyph/hglist.h30
-rw-r--r--hieroglyph/hgtypes.h9
-rw-r--r--hieroglyph/version.h.in2
-rw-r--r--hieroglyph/vm.c11
-rw-r--r--src/hgspy.c4
-rw-r--r--tests/hglist.c8
8 files changed, 231 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index 3cd0736..54b10fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
2006-09-04 Akira TAGOH <at@gclab.org>
+ * hieroglyph/hglist.c (_hg_list_iter_real_set_data): new function.
+ (hg_list_init): new function.
+ (hg_list_finalize): new function.
+ (hg_list_first): new function.
+ (hg_list_last): new function.
+ (hg_list_iter_new): use own memory pool to avoid an allocation failure,
+ because it's quite likely so that it's used under set_flags where could
+ be invoked during GC.
+ (hg_list_iter_get_data): renamed.
+ (hg_list_iter_set_data): new function.
+ (hg_list_iter_set_object): new function.
+ (hg_list_iter_delete_link): new function.
+ (hg_list_find_iter): new function.
+ (hg_list_find_iter_custom): new function.
+
+ * hieroglyph/vm.c (_hg_vm_eval_file): allow NULL to not want to get
+ an error result.
+
+ * src/hgspy.c (_hgspy_quit_cb): try to shutdown VM.
+
+ * hieroglyph/hgallocator-bfit.c (_hg_allocator_bfit_remove_block):
+
* hieroglyph/operator.c (_hg_operator_real_set_flags): fixed outdated
function call.
diff --git a/hieroglyph/hglist.c b/hieroglyph/hglist.c
index d8e1635..868ea31 100644
--- a/hieroglyph/hglist.c
+++ b/hieroglyph/hglist.c
@@ -27,6 +27,7 @@
#include "hglist.h"
#include "hgmem.h"
+#include "hgallocator-bfit.h"
enum {
@@ -35,6 +36,13 @@ enum {
HG_LIST_MASK_OBJECT_NODE = 1 << 2,
};
+struct _HieroGlyphList {
+ HgObject object;
+ HgList *prev;
+ HgList *next;
+ gpointer data;
+};
+
struct _HieroGlyphListIter {
HgObject object;
HgList *top;
@@ -97,6 +105,9 @@ static HgObjectVTable __hg_list_iter_vtable = {
.copy = NULL,
.to_string = NULL,
};
+static HgAllocator *__hg_list_allocator = NULL;
+static HgMemPool *__hg_list_pool = NULL;
+static gboolean __hg_list_initialized = FALSE;
/*
* Private Functions
@@ -223,7 +234,7 @@ _hg_list_get_last_node(HgList *list)
/* assume that the initial position may be the top node */
while (tmp) {
- if (HG_LIST_IS_UNUSED ((HgObject *)tmp)) {
+ if (HG_LIST_IS_UNUSED (tmp)) {
/* validate node */
if (hg_list_next(tmp) != NULL ||
hg_list_previous(tmp) != NULL) {
@@ -234,7 +245,7 @@ _hg_list_get_last_node(HgList *list)
return tmp;
}
} else {
- if (HG_LIST_IS_LAST_NODE ((HgObject *)tmp)) {
+ if (HG_LIST_IS_LAST_NODE (tmp)) {
return tmp;
}
}
@@ -267,7 +278,7 @@ _hg_list_get_top_node(HgList *list)
return retval;
}
-HgList *
+static HgList *
_hg_list_real_append(HgList *list,
gpointer data,
gboolean is_object)
@@ -278,7 +289,7 @@ _hg_list_real_append(HgList *list,
g_return_val_if_fail (list != NULL, NULL);
if ((last = _hg_list_get_last_node(list)) != NULL) {
- if (!HG_LIST_IS_UNUSED ((HgObject *)last)) {
+ if (!HG_LIST_IS_UNUSED (last)) {
hg_mem_get_object__inline(last, obj);
if (obj == NULL) {
g_warning("[BUG] Invalid object %p is given to append a list.",
@@ -307,7 +318,7 @@ _hg_list_real_append(HgList *list,
return list;
}
-HgList *
+static HgList *
_hg_list_real_prepend(HgList *list,
gpointer data,
gboolean is_object)
@@ -318,7 +329,7 @@ _hg_list_real_prepend(HgList *list,
g_return_val_if_fail (list != NULL, NULL);
if ((top = _hg_list_get_top_node(list)) != NULL) {
- if (!HG_LIST_IS_UNUSED ((HgObject *)top)) {
+ if (!HG_LIST_IS_UNUSED (top)) {
hg_mem_get_object__inline(top, obj);
if (obj == NULL) {
g_warning("[BUG] Invalid object %p is given to prepend a list.",
@@ -345,9 +356,44 @@ _hg_list_real_prepend(HgList *list,
return list;
}
+static void
+_hg_list_iter_real_set_data(HgListIter iter,
+ gpointer data,
+ gboolean is_object)
+{
+ g_return_if_fail (iter != NULL);
+
+ iter->current->data = data;
+ HG_LIST_SET_OBJECT_NODE (iter->current, is_object);
+}
+
/*
* Public Functions
*/
+void
+hg_list_init(void)
+{
+ if (!__hg_list_initialized) {
+ hg_mem_init();
+ __hg_list_allocator = hg_allocator_new(hg_allocator_bfit_get_vtable());
+ __hg_list_pool = hg_mem_pool_new(__hg_list_allocator,
+ "HgList Pool",
+ 128, TRUE);
+ hg_mem_pool_use_garbage_collection(__hg_list_pool, FALSE);
+ __hg_list_initialized = TRUE;
+ }
+}
+
+void
+hg_list_finalize(void)
+{
+ if (__hg_list_initialized) {
+ hg_mem_pool_destroy(__hg_list_pool);
+ hg_allocator_destroy(__hg_list_allocator);
+ __hg_list_initialized = FALSE;
+ }
+}
+
HgList *
hg_list_new(HgMemPool *pool)
{
@@ -427,12 +473,14 @@ hg_list_remove(HgList *list,
g_return_val_if_fail (list != NULL, NULL);
do {
- if (HG_LIST_IS_LAST_NODE (l)) {
- top = hg_list_next(l);
- } else {
- prev = hg_list_previous(l);
- if (prev && HG_LIST_IS_LAST_NODE (prev)) {
- top = l;
+ if (top == NULL) {
+ if (HG_LIST_IS_LAST_NODE (l)) {
+ top = hg_list_next(l);
+ } else {
+ prev = hg_list_previous(l);
+ if (prev && HG_LIST_IS_LAST_NODE (prev)) {
+ top = l;
+ }
}
}
if (l->data == data) {
@@ -467,28 +515,36 @@ hg_list_remove(HgList *list,
return top;
}
+HgList *
+hg_list_first(HgList *list)
+{
+ return _hg_list_get_top_node(list);
+}
+
+HgList *
+hg_list_last(HgList *list)
+{
+ return _hg_list_get_last_node(list);
+}
+
+/* iterators */
HgListIter
hg_list_iter_new(HgList *list)
{
- HgMemObject *obj;
HgListIter iter;
g_return_val_if_fail (list != NULL, NULL);
g_return_val_if_fail (hg_list_previous(list) != NULL, NULL);
g_return_val_if_fail (HG_LIST_IS_LAST_NODE (hg_list_previous(list)), NULL);
- hg_mem_get_object__inline(list, obj);
- if (obj == NULL) {
- g_warning("[BUG] Invalid object %p is given to create an iter for HgList.",
- list);
- return NULL;
- }
- iter = hg_mem_alloc_with_flags(obj->pool, sizeof (struct _HieroGlyphListIter),
+ if (!__hg_list_initialized)
+ hg_list_init();
+ iter = hg_mem_alloc_with_flags(__hg_list_pool, sizeof (struct _HieroGlyphListIter),
HG_FL_RESTORABLE | HG_FL_COMPLEX | HG_FL_HGOBJECT);
if (iter == NULL)
return NULL;
HG_OBJECT_INIT_STATE (&iter->object);
- HG_OBJECT_SET_STATE (&iter->object, hg_mem_pool_get_default_access_mode(obj->pool));
+ HG_OBJECT_SET_STATE (&iter->object, hg_mem_pool_get_default_access_mode(__hg_list_pool));
hg_object_set_vtable(&iter->object, &__hg_list_iter_vtable);
iter->top = list;
@@ -529,13 +585,99 @@ hg_list_get_iter_next(HgList *list,
}
gpointer
-hg_list_get_iter_data(HgList *list,
- HgListIter iter)
+hg_list_iter_get_data(HgListIter iter)
{
- g_return_val_if_fail (list != NULL, NULL);
g_return_val_if_fail (iter != NULL, NULL);
- g_return_val_if_fail (iter->top == list, NULL);
- g_return_val_if_fail (iter->last == hg_list_previous(list), NULL);
return iter->current->data;
}
+
+void
+hg_list_iter_set_data(HgListIter iter,
+ gpointer data)
+{
+ _hg_list_iter_real_set_data(iter, data, FALSE);
+}
+
+void
+hg_list_iter_set_object(HgListIter iter,
+ HgObject *hobject)
+{
+ _hg_list_iter_real_set_data(iter, hobject, TRUE);
+}
+
+HgList *
+hg_list_iter_delete_link(HgListIter iter)
+{
+ HgList *list, *next, *prev;
+
+ g_return_val_if_fail (iter != NULL, NULL);
+
+ prev = hg_list_previous(iter->current);
+ next = hg_list_next(iter->current);
+ hg_list_next(prev) = next;
+ hg_list_previous(next) = prev;
+
+ if (HG_LIST_IS_LAST_NODE (iter->current)) {
+ HG_LIST_SET_LAST_NODE (iter->current, FALSE);
+ HG_LIST_SET_LAST_NODE (prev, TRUE);
+ HG_LIST_SET_UNUSED (iter->current, TRUE);
+ }
+ hg_list_next(iter->current) = NULL;
+ hg_list_previous(iter->current) = NULL;
+ if (iter->current == next)
+ iter->top = NULL;
+ else if (iter->current == iter->top)
+ iter->top = next;
+ list = iter->top;
+ iter->current = prev;
+
+ return list;
+}
+
+HgListIter
+hg_list_find_iter(HgList *list,
+ gconstpointer data)
+{
+ gpointer p;
+ HgListIter iter;
+
+ g_return_val_if_fail (list != NULL, NULL);
+
+ iter = hg_list_iter_new(list);
+ while (iter) {
+ p = hg_list_iter_get_data(iter);
+ if (p == data)
+ return iter;
+ if (!hg_list_get_iter_next(list, iter))
+ break;
+ }
+ if (iter)
+ hg_list_iter_free(iter);
+
+ return NULL;
+}
+
+HgListIter
+hg_list_find_iter_custom(HgList *list,
+ gconstpointer data,
+ HgCompareFunc func)
+{
+ gpointer p;
+ HgListIter iter;
+
+ g_return_val_if_fail (list != NULL, NULL);
+
+ iter = hg_list_iter_new(list);
+ while (iter) {
+ p = hg_list_iter_get_data(iter);
+ if (func(p, data))
+ return iter;
+ if (!hg_list_get_iter_next(list, iter))
+ break;
+ }
+ if (iter)
+ hg_list_iter_free(iter);
+
+ return NULL;
+}
diff --git a/hieroglyph/hglist.h b/hieroglyph/hglist.h
index a2f9e0a..4d28d4a 100644
--- a/hieroglyph/hglist.h
+++ b/hieroglyph/hglist.h
@@ -29,6 +29,9 @@
G_BEGIN_DECLS
+void hg_list_init (void);
+void hg_list_finalize(void);
+
HgList *hg_list_new (HgMemPool *pool);
HgList *hg_list_append (HgList *list,
gpointer data);
@@ -41,14 +44,27 @@ HgList *hg_list_prepend_object(HgList *list,
guint hg_list_length (HgList *list);
HgList *hg_list_remove (HgList *list,
gpointer data);
+HgList *hg_list_first (HgList *list);
+HgList *hg_list_last (HgList *list);
+
+#define hg_list_iter_free hg_mem_free
-HgListIter hg_list_iter_new (HgList *list);
-gboolean hg_list_get_iter_first(HgList *list,
- HgListIter iter);
-gboolean hg_list_get_iter_next (HgList *list,
- HgListIter iter);
-gpointer hg_list_get_iter_data (HgList *list,
- HgListIter iter);
+HgListIter hg_list_iter_new (HgList *list);
+gboolean hg_list_get_iter_first (HgList *list,
+ HgListIter iter);
+gboolean hg_list_get_iter_next (HgList *list,
+ HgListIter iter);
+HgListIter hg_list_find_iter (HgList *list,
+ gconstpointer data);
+HgListIter hg_list_find_iter_custom(HgList *list,
+ gconstpointer data,
+ HgCompareFunc func);
+gpointer hg_list_iter_get_data (HgListIter iter);
+void hg_list_iter_set_data (HgListIter iter,
+ gpointer data);
+void hg_list_iter_set_object (HgListIter iter,
+ HgObject *hobject);
+HgList *hg_list_iter_delete_link(HgListIter iter);
G_END_DECLS
diff --git a/hieroglyph/hgtypes.h b/hieroglyph/hgtypes.h
index 8fb49ed..03ab3c4 100644
--- a/hieroglyph/hgtypes.h
+++ b/hieroglyph/hgtypes.h
@@ -82,6 +82,8 @@ typedef struct _HieroGlyphMatrix HgMatrix;
typedef struct _HieroGlyphDeviceVTable HgDeviceVTable;
typedef struct _HieroGlyphDevice HgDevice;
+typedef gboolean (*HgCompareFunc) (gconstpointer a,
+ gconstpointer b);
typedef gboolean (*HgTraverseFunc) (gpointer key,
gpointer val,
gpointer data);
@@ -353,13 +355,6 @@ struct _HieroGlyphFileObjectCallback {
gint (* get_error_code) (gpointer user_data);
};
-struct _HieroGlyphList {
- HgObject object;
- HgList *prev;
- HgList *next;
- gpointer data;
-};
-
struct _HieroGlyphColor {
gboolean is_rgb;
union {
diff --git a/hieroglyph/version.h.in b/hieroglyph/version.h.in
index ed7f7f5..b8c0c06 100644
--- a/hieroglyph/version.h.in
+++ b/hieroglyph/version.h.in
@@ -29,7 +29,7 @@
G_BEGIN_DECLS
#define HIEROGLYPH_VERSION "@VERSION@"
-#define HIEROGLYPH_UUID "1419cd8a-a1ef-4993-ab8f-85e6f1f895f9"
+#define HIEROGLYPH_UUID "3caed44e-0bc1-47c4-9a96-7e5625d6b0a7"
const char *__hg_rcsid G_GNUC_UNUSED = "$Rev$";
diff --git a/hieroglyph/vm.c b/hieroglyph/vm.c
index 83c9d57..dde1923 100644
--- a/hieroglyph/vm.c
+++ b/hieroglyph/vm.c
@@ -36,6 +36,7 @@
#include "hgdict.h"
#include "hgfile.h"
#include "hglineedit.h"
+#include "hglist.h"
#include "hgplugins.h"
#include "hgstack.h"
#include "hgstring.h"
@@ -272,10 +273,12 @@ _hg_vm_eval_file(HgVM *vm,
hg_vm_main(vm);
hg_mem_free(node);
hg_mem_free(file);
- if (hg_vm_has_error(vm))
- *error = TRUE;
- else
+ if (hg_vm_has_error(vm)) {
+ if (error)
+ *error = TRUE;
+ } else {
retval = TRUE;
+ }
}
break;
}
@@ -338,6 +341,7 @@ hg_vm_init(void)
if (!__hg_vm_is_initialized) {
hg_mem_init();
hg_file_init();
+ hg_list_init();
__hg_vm_allocator = hg_allocator_new(hg_allocator_bfit_get_vtable());
__hg_vm_mem_pool = hg_mem_pool_new(__hg_vm_allocator,
@@ -357,6 +361,7 @@ hg_vm_finalize(void)
hg_mem_pool_destroy(__hg_vm_mem_pool);
hg_allocator_destroy(__hg_vm_allocator);
+ hg_list_finalize();
hg_file_finalize();
hg_mem_finalize();
diff --git a/src/hgspy.c b/src/hgspy.c
index 298e089..5bc5be5 100644
--- a/src/hgspy.c
+++ b/src/hgspy.c
@@ -387,8 +387,10 @@ _hgspy_quit_cb(GtkWidget *widget,
if (spy->vm) {
retval = _hgspy_ask_dialog(spy, N_("Hieroglyph VM is still running.\nAre you sure that you really want to quit?"));
+ if (retval)
+ hg_vm_shutdown(spy->vm, 0);
} else {
- retval = FALSE;
+ retval = TRUE;
}
if (retval) {
gtk_widget_unrealize(spy->window);
diff --git a/tests/hglist.c b/tests/hglist.c
index a3c76ac..dd93900 100644
--- a/tests/hglist.c
+++ b/tests/hglist.c
@@ -38,9 +38,9 @@ main(void)
}
for (i = 0; ; i++) {
- if (tc1[i] != GPOINTER_TO_INT (hg_list_get_iter_data(list, iter))) {
+ if (tc1[i] != GPOINTER_TO_INT (hg_list_iter_get_data(iter))) {
g_print("Failed to compare: expected %d, but actually %d",
- tc1[i], GPOINTER_TO_INT (hg_list_get_iter_data(list, iter)));
+ tc1[i], GPOINTER_TO_INT (hg_list_iter_get_data(iter)));
return 1;
}
if (!hg_list_get_iter_next(list, iter))
@@ -53,9 +53,9 @@ main(void)
list = hg_list_remove(list, GINT_TO_POINTER (2));
hg_list_get_iter_first(list, iter);
for (i = 0; ; i++) {
- if (tc2[i] != GPOINTER_TO_INT (hg_list_get_iter_data(list, iter))) {
+ if (tc2[i] != GPOINTER_TO_INT (hg_list_iter_get_data(iter))) {
g_print("Failed to compare: expected %d, but actually %d",
- tc2[i], GPOINTER_TO_INT (hg_list_get_iter_data(list, iter)));
+ tc2[i], GPOINTER_TO_INT (hg_list_iter_get_data(iter)));
return 1;
}
if (!hg_list_get_iter_next(list, iter))