diff --git a/libc3/facts_cursor.c b/libc3/facts_cursor.c
index 14d5b52..2aee28c 100644
--- a/libc3/facts_cursor.c
+++ b/libc3/facts_cursor.c
@@ -96,8 +96,8 @@ s_facts_cursor * facts_cursor_lock_unlock (s_facts_cursor *cursor)
s_fact * facts_cursor_next (s_facts_cursor *cursor)
{
assert(cursor);
- facts_lock_r(cursor->facts);
facts_cursor_lock(cursor);
+ facts_lock_r(cursor->facts);
if (cursor->node) {
cursor->node = SKIPLIST_NODE_NEXT__fact(cursor->node, 0);
if (cursor->node &&
@@ -112,8 +112,8 @@ s_fact * facts_cursor_next (s_facts_cursor *cursor)
*cursor->var_predicate = *fact->predicate;
if (cursor->var_object)
*cursor->var_object = *fact->object;
- facts_cursor_lock_unlock(cursor);
facts_lock_unlock_r(cursor->facts);
+ facts_cursor_lock_unlock(cursor);
return fact;
}
if (cursor->var_subject)
@@ -122,7 +122,7 @@ s_fact * facts_cursor_next (s_facts_cursor *cursor)
tag_init_var(cursor->var_predicate);
if (cursor->var_object)
tag_init_var(cursor->var_object);
- facts_cursor_lock_unlock(cursor);
facts_lock_unlock_r(cursor->facts);
+ facts_cursor_lock_unlock(cursor);
return NULL;
}
diff --git a/libc3/facts_with.c b/libc3/facts_with.c
index 8096719..a7c163e 100644
--- a/libc3/facts_with.c
+++ b/libc3/facts_with.c
@@ -11,6 +11,7 @@
* THIS SOFTWARE.
*/
#include <assert.h>
+#include <err.h>
#include <stdlib.h>
#include "facts_cursor.h"
#include "facts_spec.h"
@@ -39,6 +40,8 @@ s_facts_with_cursor * facts_with (s_facts *facts,
cursor->spec = NULL;
}
cursor->level = 0;
+ if (pthread_mutex_init(&cursor->mutex, NULL))
+ errx(1, "facts_with: pthread_mutex_init");
return cursor;
}
diff --git a/libc3/facts_with_cursor.c b/libc3/facts_with_cursor.c
index 11e073a..24abd7c 100644
--- a/libc3/facts_with_cursor.c
+++ b/libc3/facts_with_cursor.c
@@ -33,6 +33,8 @@ void facts_with_cursor_clean (s_facts_with_cursor *cursor)
}
free(cursor->levels);
free(cursor->spec);
+ if (pthread_mutex_destroy(&cursor->mutex))
+ errx(1, "facts_with_cursor_clean: pthread_mutex_destroy");
}
s_fact * facts_with_cursor_next (s_facts_with_cursor *cursor)
@@ -41,8 +43,10 @@ s_fact * facts_with_cursor_next (s_facts_with_cursor *cursor)
s_facts_with_cursor_level *level;
p_facts_spec parent_spec;
assert(cursor);
+ if (pthread_mutex_lock(&cursor->mutex))
+ errx(1, "facts_with_cursor_next: pthread_mutex_lock");
if (! cursor->facts_count)
- return NULL;
+ goto ko;
if (cursor->level == cursor->facts_count) {
level = &cursor->levels[cursor->facts_count - 1];
#ifdef DEBUG_FACTS
@@ -60,14 +64,17 @@ s_fact * facts_with_cursor_next (s_facts_with_cursor *cursor)
buf_write_1(&g_c3_env.err, "\n");
buf_flush(&g_c3_env.err);
#endif
- if (level->fact)
+ if (level->fact) {
+ if (pthread_mutex_unlock(&cursor->mutex))
+ errx(1, "facts_with_cursor_next: pthread_mutex_unlock");
return level->fact;
+ }
free(level->spec);
level->spec = NULL;
cursor->level--;
if (! cursor->level) {
cursor->facts_count = 0;
- return NULL;
+ goto ko;
}
cursor->level--;
}
@@ -107,9 +114,15 @@ s_fact * facts_with_cursor_next (s_facts_with_cursor *cursor)
level->spec = NULL;
if (! cursor->level) {
cursor->facts_count = 0;
- return NULL;
+ goto ko;
}
cursor->level--;
}
+ if (pthread_mutex_unlock(&cursor->mutex))
+ errx(1, "facts_with_cursor_next: pthread_mutex_unlock");
return fact;
+ ko:
+ if (pthread_mutex_unlock(&cursor->mutex))
+ errx(1, "facts_with_cursor_next: pthread_mutex_unlock");
+ return NULL;
}
diff --git a/libc3/types.h b/libc3/types.h
index 31caff9..ae98d63 100644
--- a/libc3/types.h
+++ b/libc3/types.h
@@ -456,6 +456,7 @@ struct facts_with_cursor {
s_facts_with_cursor_level *levels;
size_t level;
p_facts_spec spec;
+ pthread_mutex_t mutex;
};
#endif /* TYPES_H */