From 890b3d282f73710f20ee584e234aaf190cbb4daa Mon Sep 17 00:00:00 2001
From: Dmitry Gerasimov <dmitriy.gerasimov@demlabs.net>
Date: Mon, 16 May 2022 12:59:47 +0700
Subject: [PATCH] [*] Fix for proc_thread [*] dap_chain_add_callback_notify()
 now add list of callback, not set one

---
 dap-sdk/net/core/dap_proc_thread.c |  2 +-
 modules/chain/dap_chain.c          | 23 +++++++++++++++++++----
 modules/chain/dap_chain_cell.c     | 14 ++++++++------
 modules/chain/include/dap_chain.h  | 14 ++++++++++++--
 4 files changed, 40 insertions(+), 13 deletions(-)

diff --git a/dap-sdk/net/core/dap_proc_thread.c b/dap-sdk/net/core/dap_proc_thread.c
index 235ac45a27..a1344ffd80 100644
--- a/dap-sdk/net/core/dap_proc_thread.c
+++ b/dap-sdk/net/core/dap_proc_thread.c
@@ -109,7 +109,7 @@ void dap_proc_thread_deinit()
     }
     // Cleaning custom proc threads
     pthread_rwlock_wrlock(&s_custom_threads_rwlock);
-    for ( dap_list_t * i = s_custom_threads; i=dap_list_next(i); i){
+    for ( dap_list_t * i = s_custom_threads; i; i=dap_list_next(i)){
         dap_proc_thread_t * l_proc_thread = (dap_proc_thread_t*) i->data;
         dap_events_socket_event_signal(l_proc_thread->event_exit, 1);
         pthread_join(l_proc_thread->thread_id, NULL);
diff --git a/modules/chain/dap_chain.c b/modules/chain/dap_chain.c
index f2a9f44538..39d3ea02f6 100644
--- a/modules/chain/dap_chain.c
+++ b/modules/chain/dap_chain.c
@@ -143,9 +143,9 @@ dap_chain_t * dap_chain_create(dap_ledger_t* a_ledger, const char * a_chain_net_
     l_ret->name = strdup (a_chain_name);
     l_ret->net_name = strdup (a_chain_net_name);
     l_ret->ledger = a_ledger;
+    pthread_rwlock_init(&l_ret->rwlock, NULL);
     pthread_rwlock_init(&l_ret->atoms_rwlock,NULL);
     pthread_rwlock_init(&l_ret->cell_rwlock,NULL);
-
     dap_chain_item_t * l_ret_item = DAP_NEW_Z(dap_chain_item_t);
     l_ret_item->chain = l_ret;
     memcpy(l_ret_item->item_id.id.raw ,a_chain_id.raw,sizeof(a_chain_id));
@@ -548,10 +548,25 @@ void dap_chain_info_dump_log(dap_chain_t * a_chain)
  */
 void dap_chain_add_callback_notify(dap_chain_t * a_chain, dap_chain_callback_notify_t a_callback, void * a_callback_arg)
 {
-    if(!a_chain)
+    if(!a_chain){
+        log_it(L_ERROR, "NULL chain passed to dap_chain_add_callback_notify()");
+        return;
+    }
+    if(!a_callback){
+        log_it(L_ERROR, "NULL callback passed to dap_chain_add_callback_notify()");
         return;
-    a_chain->callback_notify = a_callback;
-    a_chain->callback_notify_arg = a_callback_arg;
+    }
+    dap_chain_atom_notifier_t * l_notifier = DAP_NEW_Z(dap_chain_atom_notifier_t);
+    if (l_notifier == NULL){
+        log_it(L_ERROR, "Can't allocate memory for notifier in dap_chain_add_callback_notify()");
+        return;
+    }
+
+    l_notifier->callback = a_callback;
+    l_notifier->arg = a_callback_arg;
+    pthread_rwlock_wrlock(&a_chain->rwlock);
+    a_chain->atom_notifiers = dap_list_append(a_chain->atom_notifiers, l_notifier);
+    pthread_rwlock_unlock(&a_chain->rwlock);
 }
 
 /**
diff --git a/modules/chain/dap_chain_cell.c b/modules/chain/dap_chain_cell.c
index 92a600460b..b63aa8d905 100644
--- a/modules/chain/dap_chain_cell.c
+++ b/modules/chain/dap_chain_cell.c
@@ -317,12 +317,14 @@ int dap_chain_cell_file_append( dap_chain_cell_t * a_cell, const void* a_atom, s
             break;
         }
         l_total_wrote_bytes += l_atom_size;
-        if(a_cell->chain && a_cell->chain->callback_notify)
-            a_cell->chain->callback_notify(a_cell->chain->callback_notify_arg,
-                                           a_cell->chain,
-                                           a_cell->id,
-                                           (void *)l_atom,
-                                           l_atom_size);
+
+
+        if(a_cell->chain && a_cell->chain->atom_notifiers ){
+            for( dap_list_t * l_iter = a_cell->chain->atom_notifiers;l_iter; l_iter = dap_list_next(l_iter) ){
+                dap_chain_atom_notifier_t * i = (dap_chain_atom_notifier_t *) l_iter->data;
+                i->callback(i->arg, a_cell->chain, a_cell->id, (void *)l_atom, l_atom_size);
+            }
+        }
     }
     if (l_total_wrote_bytes > 0) {
         fflush(a_cell->file_storage);
diff --git a/modules/chain/include/dap_chain.h b/modules/chain/include/dap_chain.h
index 51dce44437..e852f5a599 100644
--- a/modules/chain/include/dap_chain.h
+++ b/modules/chain/include/dap_chain.h
@@ -105,7 +105,11 @@ typedef enum dap_chain_type
     CHAIN_TYPE_LAST
 } dap_chain_type_t;
 
+
+
 typedef struct dap_chain{
+    pthread_rwlock_t rwlock; // Common rwlock for the whole structure
+
     dap_chain_id_t id;
     dap_chain_net_id_t net_id;
     char * name;
@@ -157,8 +161,9 @@ typedef struct dap_chain{
     dap_chain_callback_get_count_tx callback_count_tx;
     dap_chain_callback_get_txs callback_get_txs;
 
-    dap_chain_callback_notify_t callback_notify;
-    void *callback_notify_arg;
+    dap_list_t * atom_notifiers;
+//    dap_chain_callback_notify_t callback_notify;
+//    void *callback_notify_arg;
 
     /*
     dap_chain_datum_callback_iter_create_t callback_datum_iter_create;
@@ -175,6 +180,11 @@ typedef struct dap_chain_gdb_notifier {
     void *cb_arg;
 } dap_chain_gdb_notifier_t;
 
+typedef struct dap_chain_atom_notifier {
+    dap_chain_callback_notify_t callback;
+    void *arg;
+} dap_chain_atom_notifier_t;
+
 #define DAP_CHAIN(a) ( (dap_chain_t *) (a)->_inheritor)
 
 int dap_chain_init(void);
-- 
GitLab