From 9600496dd8d006b3cdfe42ada18d9355655991a6 Mon Sep 17 00:00:00 2001
From: "Dmitriy A. Gerasimov" <dmitriy.gerasimov@demlabs.net>
Date: Thu, 22 Oct 2020 22:03:54 +0700
Subject: [PATCH] [*] Context fixes

---
 dap-sdk/net/client/dap_client.c             | 37 ++++++++++++++-------
 dap-sdk/net/client/dap_client_pvt.c         | 18 ++++++----
 dap-sdk/net/client/include/dap_client_pvt.h |  3 +-
 3 files changed, 38 insertions(+), 20 deletions(-)

diff --git a/dap-sdk/net/client/dap_client.c b/dap-sdk/net/client/dap_client.c
index 54cc987894..8f807ffbbc 100644
--- a/dap-sdk/net/client/dap_client.c
+++ b/dap-sdk/net/client/dap_client.c
@@ -249,30 +249,43 @@ static void s_go_stage_on_client_worker_unsafe(dap_worker_t * a_worker,void * a_
 {
     (void) a_worker;
     assert(a_arg);
-    dap_client_stage_t a_stage_target = ((struct go_stage_arg*) a_arg)->stage_target;
-    dap_client_callback_t a_stage_end_callback= ((struct go_stage_arg*) a_arg)->stage_end_callback;
+    dap_client_stage_t l_stage_target = ((struct go_stage_arg*) a_arg)->stage_target;
+    dap_client_callback_t l_stage_end_callback= ((struct go_stage_arg*) a_arg)->stage_end_callback;
     dap_client_pvt_t * l_client_pvt = ((struct go_stage_arg*) a_arg)->client_pvt;
     DAP_DELETE(a_arg);
 
     dap_client_stage_t l_cur_stage = l_client_pvt->stage;
     dap_client_stage_status_t l_cur_stage_status= l_client_pvt->stage_status;
-
-    if (a_stage_target == l_cur_stage) {
-        log_it(L_DEBUG, "Already have target state %s", dap_client_stage_str(a_stage_target));
-        if (a_stage_end_callback) {
-            a_stage_end_callback(l_client_pvt->client, NULL);
+    if (l_stage_target == l_cur_stage){
+        switch ( l_cur_stage_status) {
+            case STAGE_STATUS_DONE:
+                log_it(L_DEBUG, "Already have target state %s", dap_client_stage_str(l_stage_target));
+                if (l_stage_end_callback) {
+                    l_stage_end_callback(l_client_pvt->client, NULL);
+                }
+            break;
+            case STAGE_STATUS_ERROR:
+                log_it(L_DEBUG, "Already moving target state %s, but status is error (%s)", dap_client_stage_str(l_stage_target),
+                       dap_client_get_error_str( l_client_pvt->client) );
+            break;
+            case STAGE_STATUS_IN_PROGRESS:
+                log_it(L_DEBUG, "Already moving target state %s", dap_client_stage_str(l_stage_target));
+            break;
+            default:
+                log_it(L_WARNING, "Unprocessed stage status %s for go to stage %s scheme ",  dap_client_stage_str(l_stage_target),
+                       dap_client_stage_status_str( l_cur_stage_status));
         }
         return;
     }
-    log_it(L_DEBUG, "Start transitions chain to %s", dap_client_stage_str(a_stage_target));
-    l_client_pvt->stage_target = a_stage_target;
-    l_client_pvt->stage_target_done_callback = a_stage_end_callback;
-    if (a_stage_target < l_cur_stage) {
+    log_it(L_DEBUG, "Start transitions chain for client %p from %s to %s", l_client_pvt->client, dap_client_stage_str(l_cur_stage ) , dap_client_stage_str(l_stage_target));
+    l_client_pvt->stage_target = l_stage_target;
+    l_client_pvt->stage_target_done_callback = l_stage_end_callback;
+    if (l_stage_target < l_cur_stage) {
         dap_client_pvt_stage_transaction_begin(l_client_pvt, STAGE_BEGIN, NULL);
     }
     l_cur_stage = l_client_pvt->stage;
     l_cur_stage_status= l_client_pvt->stage_status;
-    if (a_stage_target != l_cur_stage ){ // Going to stages downstairs
+    if (l_stage_target != l_cur_stage ){ // Going to stages downstairs
         switch(l_cur_stage_status ){
             case STAGE_STATUS_ABORTING:
                 log_it(L_ERROR, "Already aborting the stage %s"
diff --git a/dap-sdk/net/client/dap_client_pvt.c b/dap-sdk/net/client/dap_client_pvt.c
index 857a6bdb1f..9cbb91e4b0 100644
--- a/dap-sdk/net/client/dap_client_pvt.c
+++ b/dap-sdk/net/client/dap_client_pvt.c
@@ -150,8 +150,9 @@ static void s_client_pvt_disconnected(dap_client_t * a_client, void * a_arg )
     (void) a_arg;
     // To be sure thats cond waiter is waiting and unlocked mutex
     pthread_mutex_lock(&DAP_CLIENT_PVT(a_client)->disconnected_mutex);
-    pthread_cond_broadcast(&DAP_CLIENT_PVT(a_client)->disconnected_cond);
     pthread_mutex_unlock(&DAP_CLIENT_PVT(a_client)->disconnected_mutex);
+
+    pthread_cond_broadcast(&DAP_CLIENT_PVT(a_client)->disconnected_cond);
 }
 
 /**
@@ -164,13 +165,16 @@ int dap_client_pvt_disconnect_all_n_wait(dap_client_pvt_t *a_client_pvt)
     //dap_client_pvt_t *a_client_pvt = (a_client) ? DAP_CLIENT_PVT(a_client) : NULL;
     if(!a_client_pvt)
         return -1;
+    time_t l_ts_begin=time(NULL);
+    log_it(L_DEBUG,"Disconnect_n_wait called");
+
     pthread_mutex_lock(&a_client_pvt->disconnected_mutex);
     dap_client_go_stage(a_client_pvt->client, STAGE_BEGIN, s_client_pvt_disconnected );
-    while (a_client_pvt->stage != STAGE_BEGIN) {
-        pthread_cond_wait(&a_client_pvt->disconnected_cond, &a_client_pvt->disconnected_mutex);
-    }
+    pthread_cond_wait(&a_client_pvt->disconnected_cond, &a_client_pvt->disconnected_mutex);
     pthread_mutex_unlock(&a_client_pvt->disconnected_mutex);
-
+    time_t l_ts_end=time(NULL);
+    log_it(L_INFO,"Disconnected: achieved STAGE_BEGIN at time %d",
+           l_ts_end-l_ts_begin);
     return 0;
 }
 
@@ -570,6 +574,8 @@ static void s_stage_status_after(dap_client_pvt_t * a_client_pvt)
 void dap_client_pvt_stage_transaction_begin(dap_client_pvt_t * a_client_internal, dap_client_stage_t a_stage_next,
         dap_client_callback_t a_done_callback)
 {
+    assert(a_client_internal);
+    log_it(L_DEBUG, "Begin transaction for client %p to the next stage %s", a_client_internal->client, dap_client_stage_str(a_stage_next));
     a_client_internal->stage_status_done_callback = a_done_callback;
     a_client_internal->stage = a_stage_next;
     a_client_internal->stage_status = STAGE_STATUS_IN_PROGRESS;
@@ -985,7 +991,7 @@ static void s_stream_ctl_response(dap_client_t * a_client, void * a_data, size_t
                         dap_enc_key_new_generate(l_enc_type, l_stream_key, strlen(l_stream_key), NULL, 0,
                                 32);
 
-                l_client_internal->encrypted_headers = l_enc_headers;
+                l_client_internal->is_encrypted_headers = l_enc_headers;
 
                 if(l_client_internal->stage == STAGE_STREAM_CTL) { // We are on the right stage
                     l_client_internal->stage_status = STAGE_STATUS_DONE;
diff --git a/dap-sdk/net/client/include/dap_client_pvt.h b/dap-sdk/net/client/include/dap_client_pvt.h
index 7ca76b349c..961c08a9f2 100644
--- a/dap-sdk/net/client/include/dap_client_pvt.h
+++ b/dap-sdk/net/client/include/dap_client_pvt.h
@@ -79,8 +79,7 @@ typedef struct dap_client_internal
     int stage_errors;
 
     bool is_encrypted;
-    bool encrypted_headers;
-    bool is_reconnect;
+    bool is_encrypted_headers;
     bool is_close_session;// the last request in session, in the header will be added "SessionCloseAfterRequest: true"
     dap_client_callback_data_size_t request_response_callback;
     dap_client_callback_int_t request_error_callback;
-- 
GitLab