Commit b40d4f1ff6eabc0a7c94a5a5253751a93a104f1e

Thomas de Grivel 2020-05-14T11:05:26

Fix rtbuf_new when running. Add user pointer to s_rtbuf. Add callbacks for core rtbuf operations.

diff --git a/librtbuf/include/rtbuf/rtbuf.h b/librtbuf/include/rtbuf/rtbuf.h
index c29a31d..bbabab5 100644
--- a/librtbuf/include/rtbuf/rtbuf.h
+++ b/librtbuf/include/rtbuf/rtbuf.h
@@ -21,8 +21,10 @@
 #include <rtbuf/type.h>
 #include <rtbuf/proc.h>
 
-#define RTBUF_SORT   0x0001
-#define RTBUF_DELETE 0x0002
+#define RTBUF_SORT     0x0001
+#define RTBUF_DELETE   0x0002
+#define RTBUF_NEW      0x0004
+#define RTBUF_READY    0x0008
 
 struct rtbuf_binding
 {
@@ -38,6 +40,7 @@ struct rtbuf
   unsigned int    refc;
   s_rtbuf_binding in[RTBUF_PROC_IN_MAX];
   unsigned int    in_n;
+  void           *user_ptr;
 };
 
 #define RTBUF_MAX         10000
@@ -47,10 +50,23 @@ extern s_data_alloc g_rtbuf_alloc;
 extern s_rtbuf     *g_rtbuf;
 extern int          g_rtbuf_run;
 
+typedef void (*f_rtbuf_new_cb) (s_rtbuf *rtb);
+typedef void (*f_rtbuf_delete_cb) (s_rtbuf *rtb);
+typedef void (*f_rtbuf_bind_cb) (s_rtbuf *src, unsigned int out,
+                                 s_rtbuf *dest, unsigned int in);
+typedef void (*f_rtbuf_unbind_cb) (s_rtbuf *src, unsigned int out,
+                                   s_rtbuf *dest, unsigned int in);
+
+extern f_rtbuf_new_cb    g_rtbuf_new_cb;
+extern f_rtbuf_delete_cb g_rtbuf_delete_cb;
+extern f_rtbuf_bind_cb   g_rtbuf_bind_cb;
+extern f_rtbuf_unbind_cb g_rtbuf_unbind_cb;
+
 int   librtbuf_init ();
 
 int   rtbuf_err (const char *msg);
 int   rtbuf_new (s_rtbuf_proc *rp);
+int   rtbuf_new_ptr (s_rtbuf_proc *rp, void *user_ptr);
 void  rtbuf_in_unbind (s_rtbuf *rtb, unsigned int in);
 void  rtbuf_out_unbind (s_rtbuf *rtb, unsigned int out);
 void  rtbuf_unbind_all (s_rtbuf *rtb);
@@ -59,7 +75,7 @@ int   rtbuf_clone (s_rtbuf *rtb);
 int   rtbuf_find (symbol sym);
 int   rtbuf_in_find (s_rtbuf *rtb, const char *x);
 void  rtbuf_bind (unsigned int src, unsigned int out,
-                  s_rtbuf *dest, unsigned int var);
+                  s_rtbuf *dest, unsigned int in);
 int   rtbuf_out_find (s_rtbuf *rtb, symbol sym);
 int   rtbuf_data_set (s_rtbuf *rtb, symbol name, void *value,
                       unsigned int size);
diff --git a/librtbuf/rtbuf.c b/librtbuf/rtbuf.c
index 5e19779..9354139 100644
--- a/librtbuf/rtbuf.c
+++ b/librtbuf/rtbuf.c
@@ -36,6 +36,11 @@ unsigned int  g_rtbuf_sort = 0;
 unsigned int  g_rtbuf_sorted[RTBUF_MAX];
 unsigned int  g_rtbuf_sorted_n = 0;
 
+f_rtbuf_new_cb    g_rtbuf_new_cb = 0;
+f_rtbuf_delete_cb g_rtbuf_delete_cb = 0;
+f_rtbuf_bind_cb   g_rtbuf_bind_cb = 0;
+f_rtbuf_unbind_cb g_rtbuf_unbind_cb = 0;
+
 int librtbuf_init ()
 {
   libdata_init();
@@ -52,6 +57,11 @@ int librtbuf_init ()
 
 int rtbuf_new (s_rtbuf_proc *rp)
 {
+  return rtbuf_new_ptr(rp, NULL);
+}
+
+int rtbuf_new_ptr (s_rtbuf_proc *rp, void *user_ptr)
+{
   int i;
   s_rtbuf *rtb;
   void *data;
@@ -67,8 +77,9 @@ int rtbuf_new (s_rtbuf_proc *rp)
                      "please increase RTBUF_MAX");
   rtb = &g_rtbuf[i];
   rtb->data = data;
-  rtb->flags = 0;
+  rtb->flags = RTBUF_NEW;
   rtb->proc = rp;
+  rtb->user_ptr = user_ptr;
   j = 0;
   while (j < RTBUF_PROC_IN_MAX) {
     rtb->in[j].rtb = -1;
@@ -80,7 +91,10 @@ int rtbuf_new (s_rtbuf_proc *rp)
     *uv = rp->in[j].def;
     j++;
   }
+  rtb->flags |= RTBUF_READY;
   g_rtbuf_sort = 1;
+  if (g_rtbuf_new_cb)
+    g_rtbuf_new_cb(rtb);
   return i;
 }
 
@@ -89,10 +103,13 @@ void rtbuf_in_unbind (s_rtbuf *rtb, unsigned int in)
   s_rtbuf_binding *v = &rtb->in[in];
   if (v->rtb >= 0) {
     s_rtbuf *src = &g_rtbuf[v->rtb];
+    unsigned int out = v->out;
     src->refc--;
     v->rtb = -1;
     v->out = 0;
     rtb->in_n--;
+    if (g_rtbuf_unbind_cb)
+      g_rtbuf_unbind_cb(src, out, rtb, in);
   }
 }
 
@@ -196,7 +213,10 @@ void rtbuf_delete (s_rtbuf *rtb)
 {
   assert(rtb);
   rtb->flags |= RTBUF_DELETE;
+  rtbuf_unbind_all(rtb);
   g_rtbuf_sort = 1;
+  if (g_rtbuf_delete_cb)
+    g_rtbuf_delete_cb(rtb);
 }
 
 int rtbuf_clone (s_rtbuf *rtb)
@@ -210,6 +230,9 @@ int rtbuf_clone (s_rtbuf *rtb)
   new = &g_rtbuf[new_i];
   while (j < rtb->proc->in_n) {
     new->in[j] = rtb->in[j];
+    if (g_rtbuf_bind_cb && new->in[j].rtb >= 0)
+      g_rtbuf_bind_cb(&g_rtbuf[new->in[j].rtb], new->in[j].out,
+                      new, j);
     j++;
   }
   new->in_n = rtb->in_n;
@@ -228,6 +251,8 @@ void rtbuf_bind (unsigned int src, unsigned int out,
   dest->in_n++;
   g_rtbuf[src].refc++;
   g_rtbuf_sort = 1;
+  if (g_rtbuf_bind_cb)
+    g_rtbuf_bind_cb(&g_rtbuf[src], out, dest, in);
 }
 
 int rtbuf_data_set (s_rtbuf *rtb, symbol name, void *value,
@@ -245,6 +270,7 @@ int rtbuf_data_set (s_rtbuf *rtb, symbol name, void *value,
   return 0;
 }
 
+/* XXX needs rewrite */
 typedef struct rtbuf_in_ptr {
   unsigned int rtb;
   unsigned int in;
@@ -324,6 +350,7 @@ void rtbuf_find_roots (s_rtbuf_in_stack *rvs)
   /* printf(" rtbuf_find_roots => %u\n", c); */
 }
 
+/* XXX needs rewrite */
 void rtbuf_sort_push_child (s_rtbuf_in_stack *rvs,
                             s_rtbuf_in_ptr *ptr)
 {
@@ -350,6 +377,7 @@ void rtbuf_sort_push_child (s_rtbuf_in_stack *rvs,
   }
 }
 
+/* XXX needs rewrite */
 void rtbuf_sort ()
 {
   s_rtbuf_in_stack rvs;
@@ -380,7 +408,7 @@ int rtbuf_start ()
   while (i < g_rtbuf_sorted_n) {
     s_rtbuf *rtb = &g_rtbuf[g_rtbuf_sorted[i]];
     assert(rtb->data);
-    if (rtb->proc->start) {
+    if (rtb->flags & RTBUF_READY && rtb->proc->start) {
       /* printf(" start ");
          rtbuf_print(g_rtbuf_sorted[i]);
          printf(" ");
@@ -388,6 +416,7 @@ int rtbuf_start ()
          printf("\n"); */
       if (rtb->proc->start(rtb))
         return 1;
+      rtb->flags &= ~RTBUF_NEW;
     }
     i++;
   }
@@ -405,10 +434,17 @@ int rtbuf_run ()
     /* printf(" rtbuf_run %i ", i);
        rtbuf_print(g_rtbuf_sorted[i]);
        printf("\n"); */
-    assert(rtb->data);
-    if (rtb->proc->f)
-      if (rtb->proc->f(rtb))
-        return 1;
+    if (rtb->flags & RTBUF_READY) {
+      if (rtb->flags & RTBUF_NEW) {
+        if (rtb->proc->start)
+          if (rtb->proc->start(rtb))
+            return 1;
+        rtb->flags &= ~RTBUF_NEW;
+      }
+      if (rtb->proc->f)
+        if (rtb->proc->f(rtb))
+          return 1;
+    }
     i++;
   }
   /* printf(" rtbuf_run => %u\n", i); */