Commit 6c1aa8733aedda34074c67ce9467f8570e96b932

Thomas de Grivel 2025-04-17T12:41:42

lock transactions rw

diff --git a/lib/kc3/0.1/httpd.kc3 b/lib/kc3/0.1/httpd.kc3
index 5d33522..9f71580 100644
--- a/lib/kc3/0.1/httpd.kc3
+++ b/lib/kc3/0.1/httpd.kc3
@@ -80,7 +80,9 @@ defmodule HTTPd do
 
   def http_client = fn (socket, events, client_ev, client) do
     if List.has?(events, :read) do
-      def concurrent_requests = concurrent_requests + 1
+      Facts.with_transaction(Facts.env_db(), do
+        def concurrent_requests = concurrent_requests + 1
+      end)
       # maybe_reload_app()
       request = void
       request = HTTP.Request.buf_parse(client.buf_rw.r)
@@ -117,7 +119,9 @@ defmodule HTTPd do
         Event.del(client_ev)
         File.close(socket)
       end
-      def concurrent_requests = concurrent_requests - 1
+      Facts.with_transaction(Facts.env_db(), do
+        def concurrent_requests = concurrent_requests - 1
+      end)
       result
     end
   end
@@ -159,8 +163,8 @@ defmodule HTTPd do
     end
   }
 
-  def thread_count = 1
-  #def thread_count = ncpu
+  #def thread_count = 1
+  def thread_count = ncpu
 
   def server = fn (host, port) {
     def socket = Socket.listen(host, port)
diff --git a/libkc3/env.c b/libkc3/env.c
index 2888411..fe32807 100644
--- a/libkc3/env.c
+++ b/libkc3/env.c
@@ -919,6 +919,7 @@ s_tag * env_facts_with_transaction (s_env *env, s_tag *facts_arg,
   facts = facts_tag.data.ptr.p;
   facts_transaction_start(facts, &transaction);
   if (! env_eval_tag(env, tag_arg, &tmp)) {
+    facts_transaction_end(facts, &transaction);
     tag_clean(&facts_tag);
     facts_transaction_clean(&transaction);
     return NULL;
@@ -2034,7 +2035,7 @@ s_struct_type ** env_struct_type_find (s_env *env,
                                        const s_sym *module,
                                        s_struct_type **dest)
 {
-  s_facts_with_cursor cursor;
+  s_facts_cursor cursor;
   s_fact *found;
   s_tag tag_struct_type;
   s_tag tag_module;
@@ -2044,7 +2045,7 @@ s_struct_type ** env_struct_type_find (s_env *env,
   assert(module);
   tag_init_sym(&tag_module, module);
   tag_init_sym(&tag_struct_type, &g_sym_struct_type);
-  tag_init_var(&tag_var, &g_sym_Tag);
+  tag_init_var(&tag_var, &g_sym_StructType);
   if (! env_module_maybe_reload(env, module)) {
     err_write_1("env_struct_type_find: env_module_maybe_reload(");
     err_inspect_sym(&module);
@@ -2052,23 +2053,22 @@ s_struct_type ** env_struct_type_find (s_env *env,
     assert(! "env_struct_type_find: env_module_maybe_reload");
     return NULL;
   }
-  if (! facts_with(env->facts, &cursor, (t_facts_spec) {
-                   &tag_module, &tag_struct_type, &tag_var,
-                   NULL, NULL })) {
-    err_write_1("env_struct_type_find: facts_with(");
+  if (! facts_with_tags(env->facts, &cursor,
+                        &tag_module, &tag_struct_type, &tag_var)) {
+    err_write_1("env_struct_type_find: facts_with_tags(");
     err_inspect_sym(&module);
     err_puts(", :struct_type, ?)");
     assert(! "env_struct_type_find: facts_with");
     return NULL;
   }
-  if (! facts_with_cursor_next(&cursor, &found)) {
+  if (! facts_cursor_next(&cursor, &found)) {
     err_puts("env_struct_type_find: facts_with_cursor_next");
     assert(! "env_struct_type_find: facts_with_cursor_next");
-    facts_with_cursor_clean(&cursor);
+    facts_cursor_clean(&cursor);
     return NULL;
   }
   if (! found) {
-    facts_with_cursor_clean(&cursor);
+    facts_cursor_clean(&cursor);
     *dest = NULL;
     return dest;
   }
@@ -2080,11 +2080,11 @@ s_struct_type ** env_struct_type_find (s_env *env,
     err_inspect_sym(&type);
     err_write_1("\n");
     assert(! "env_struct_type_find: invalid struct_type");
-    facts_with_cursor_clean(&cursor);
+    facts_cursor_clean(&cursor);
     return NULL;
   }
   *dest = found->object->data.pstruct_type;
-  facts_with_cursor_clean(&cursor);
+  facts_cursor_clean(&cursor);
   return dest;
 }
 
diff --git a/libkc3/facts_transaction.c b/libkc3/facts_transaction.c
index b5be1d9..efc65ea 100644
--- a/libkc3/facts_transaction.c
+++ b/libkc3/facts_transaction.c
@@ -17,7 +17,7 @@
 #include "facts.h"
 #include "facts_transaction.h"
 #include "list.h"
-#include "types.h"
+#include "rwlock.h"
 
 s_facts_transaction * facts_transaction_clean
 (s_facts_transaction *transaction)
@@ -38,6 +38,9 @@ void facts_transaction_end (s_facts *facts,
     abort();
   }
   facts->transaction = facts_transaction_clean(transaction);
+#if HAVE_PTHREAD
+  rwlock_unlock_w(&facts->rwlock);
+#endif
 }
 
 bool facts_transaction_find (s_facts *facts,
@@ -118,6 +121,10 @@ void facts_transaction_start (s_facts *facts,
 {
   assert(facts);
   assert(transaction);
+#if HAVE_PTHREAD
+  if (! rwlock_w(&facts->rwlock))
+    return;
+#endif
   transaction->log = NULL;
   transaction->next = facts->transaction;
   facts->transaction = transaction;