Commit b59ab3ffb359eda90c7593aaf6a96087de794552

Thomas de Grivel 2024-12-04T11:07:22

buf rwlock

diff --git a/lib/kc3/0.1/buf.kc3 b/lib/kc3/0.1/buf.kc3
index 0d6c826..ce161bc 100644
--- a/lib/kc3/0.1/buf.kc3
+++ b/lib/kc3/0.1/buf.kc3
@@ -8,6 +8,7 @@ defmodule Buf do
              read_only: false,
              refill: (Ptr) 0,
              rpos: (Uw) 0,
+             rwlock: (Ptr) 0,
              save: (Ptr) 0,
              seek: (Ptr) 0,
              size: (Uw) 0,
diff --git a/libkc3/buf.c b/libkc3/buf.c
index 5c3abd5..f8525ba 100644
--- a/libkc3/buf.c
+++ b/libkc3/buf.c
@@ -25,6 +25,7 @@
 void buf_clean (s_buf *buf)
 {
   assert(buf);
+  buf_lock_clean(buf);
   if (buf->free)
     free(buf->ptr.p);
 }
@@ -194,6 +195,7 @@ s_buf * buf_init (s_buf *buf, bool p_free, uw size, char *p)
   tmp.line = 1;
   tmp.ptr.pchar = p;
   tmp.size = size;
+  buf_lock_init(&tmp);
   *buf = tmp;
   return buf;
 }
@@ -298,6 +300,54 @@ s_buf * buf_init_str_copy (s_buf *buf, const s_str *str)
   return buf;
 }
 
+void buf_lock_clean (s_buf *buf)
+{
+  if (pthread_rwlock_destroy(buf->rwlock)) {
+    err_puts("buf_lock_init: pthread_rwlock_destroy");
+    assert(! "buf_lock_init: pthread_rwlock_destroy");
+    abort();
+  }
+  free(buf->rwlock);
+}
+
+void buf_lock_init (s_buf *buf)
+{
+  if (! (buf->rwlock = alloc(sizeof(pthread_rwlock_t))))
+    abort();
+  if (pthread_rwlock_init(buf->rwlock, NULL)) {
+    err_puts("buf_lock_init: pthread_rwlock_init");
+    assert(! "buf_lock_init: pthread_rwlock_init");
+    abort();
+  }
+}
+
+void buf_lock_r (s_buf *buf)
+{
+  if (pthread_rwlock_rdlock(buf->rwlock)) {
+    err_puts("buf_lock_init: pthread_rwlock_rdlock");
+    assert(! "buf_lock_init: pthread_rwlock_rdlock");
+    abort();
+  }
+}
+
+void buf_lock_unlock (s_buf *buf)
+{
+  if (pthread_rwlock_unlock(buf->rwlock)) {
+    err_puts("buf_lock_init: pthread_rwlock_unlock");
+    assert(! "buf_lock_init: pthread_rwlock_unlock");
+    abort();
+  }
+}
+
+void buf_lock_w (s_buf *buf)
+{
+  if (pthread_rwlock_wrlock(buf->rwlock)) {
+    err_puts("buf_lock_init: pthread_rwlock_wrlock");
+    assert(! "buf_lock_init: pthread_rwlock_wrlock");
+    abort();
+  }
+}
+
 s_buf * buf_new (bool p_free, uw size, char *p)
 {
   s_buf *buf;
diff --git a/libkc3/buf.h b/libkc3/buf.h
index 180383a..a7316b0 100644
--- a/libkc3/buf.h
+++ b/libkc3/buf.h
@@ -52,6 +52,11 @@ sw      buf_ignore_line (s_buf *buf);
 sw      buf_ignore_newline (s_buf *buf);
 sw      buf_ignore_spaces (s_buf *buf);
 sw      buf_ignore_spaces_but_newline (s_buf *buf);
+void    buf_lock_clean (s_buf *buf);
+void    buf_lock_init (s_buf *buf);
+void    buf_lock_r (s_buf *buf);
+void    buf_lock_unlock (s_buf *buf);
+void    buf_lock_w (s_buf *buf);
 sw      buf_peek_1 (s_buf *buf, const char *p);
 sw      buf_peek_character_utf8 (s_buf *buf, character *p);
 sw      buf_peek_f32 (s_buf *buf, f32 *p);
diff --git a/libkc3/types.h b/libkc3/types.h
index 1828a78..385af55 100644
--- a/libkc3/types.h
+++ b/libkc3/types.h
@@ -392,19 +392,20 @@ struct var {
 /* 2 */
 
 struct buf {
-  sw        (*flush) (s_buf *buf);
-  bool        free;
-  sw          line;
-  s_pretty    pretty;
-  u_ptr_w     ptr;
-  bool        read_only;
-  sw        (*refill) (s_buf *buf);
-  uw          rpos;
-  s_buf_save *save;
-  sw        (*seek) (s_buf *buf, sw offset, u8 whence);
-  uw          size;
-  void *      user_ptr;
-  uw          wpos;
+  sw              (*flush) (s_buf *buf);
+  bool              free;
+  sw                line;
+  s_pretty          pretty;
+  u_ptr_w           ptr;
+  bool              read_only;
+  sw              (*refill) (s_buf *buf);
+  uw                rpos;
+  pthread_rwlock_t *rwlock;
+  s_buf_save       *save;
+  sw              (*seek) (s_buf *buf, sw offset, u8 whence);
+  uw                size;
+  void *            user_ptr;
+  uw                wpos;
 };
 
 struct facts_spec_cursor {