<commit_before>diff --git zkc-3.4.5-orig/c/src/zookeeper.c zkc-3.4.5/c/src/zookeeper.c
index de58c62..2347ff4 100644
--- zkc-3.4.5-orig/c/src/zookeeper.c
+++ zkc-3.4.5/c/src/zookeeper.c
@@ -1167,25 +1167,20 @@ void free_completions(zhandle_t *zh,int callCompletion,int reason)
             zh->outstanding_sync--;
             destroy_completion_entry(cptr);
         } else if (callCompletion) {
-            if(cptr->xid == PING_XID){
-                // Nothing to do with a ping response
-                destroy_completion_entry(cptr);
-            } else {
-                // Fake the response
-                buffer_list_t *bptr;
-                h.xid = cptr->xid;
-                h.zxid = -1;
-                h.err = reason;
-                oa = create_buffer_oarchive();
-                serialize_ReplyHeader(oa, "header", &h);
-                bptr = calloc(sizeof(*bptr), 1);
-                assert(bptr);
-                bptr->len = get_buffer_len(oa);
-                bptr->buffer = get_buffer(oa);
-                close_buffer_oarchive(&oa, 0);
-                cptr->buffer = bptr;
-                queue_completion(&zh->completions_to_process, cptr, 0);
-            }
+            // Fake the response
+            buffer_list_t *bptr;
+            h.xid = cptr->xid;
+            h.zxid = -1;
+            h.err = reason;
+            oa = create_buffer_oarchive();
+            serialize_ReplyHeader(oa, "header", &h);
+            bptr = calloc(sizeof(*bptr), 1);
+            assert(bptr);
+            bptr->len = get_buffer_len(oa);
+            bptr->buffer = get_buffer(oa);
+            close_buffer_oarchive(&oa, 0);
+            cptr->buffer = bptr;
+            queue_completion(&zh->completions_to_process, cptr, 0);
         }
     }
     a_list.completion = NULL;
@@ -1526,7 +1521,6 @@ static struct timeval get_timeval(int interval)
     rc = serialize_RequestHeader(oa, "header", &h);
     enter_critical(zh);
     gettimeofday(&zh->last_ping, 0);
-    rc = rc < 0 ? rc : add_void_completion(zh, h.xid, 0, 0);
     rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
             get_buffer_len(oa));
     leave_critical(zh);
@@ -2063,12 +2057,8 @@ static void deserialize_response(int type, int xid, int failed, int rc, completi
     case COMPLETION_VOID:
         LOG_DEBUG(("Calling COMPLETION_VOID for xid=%#x failed=%d rc=%d",
                     cptr->xid, failed, rc));
-        if (xid == PING_XID) {
-            // We want to skip the ping
-        } else {
-            assert(cptr->c.void_result);
-            cptr->c.void_result(rc, cptr->data);
-        }
+        assert(cptr->c.void_result);
+        cptr->c.void_result(rc, cptr->data);
         break;
     case COMPLETION_MULTI:
         LOG_DEBUG(("Calling COMPLETION_MULTI for xid=%#x failed=%d rc=%d",
@@ -2184,7 +2174,15 @@ int zookeeper_process(zhandle_t *zh, int events)
             // fprintf(stderr, "Got %#x for %#x\n", hdr.zxid, hdr.xid);
         }
 
-        if (hdr.xid == WATCHER_EVENT_XID) {
+        if (hdr.xid == PING_XID) {
+            // Ping replies can arrive out-of-order
+            int elapsed = 0;
+            struct timeval now;
+            gettimeofday(&now, 0);
+            elapsed = calculate_interval(&zh->last_ping, &now);
+            LOG_DEBUG(LOGCALLBACK(zh), "Got ping response in %d ms", elapsed);
+            free_buffer(bptr);
+        } else if (hdr.xid == WATCHER_EVENT_XID) {
             struct WatcherEvent evt;
             int type = 0;
             char *path = NULL;
@@ -2250,22 +2248,9 @@ int zookeeper_process(zhandle_t *zh, int events)
             activateWatcher(zh, cptr->watcher, rc);
 
             if (cptr->c.void_result != SYNCHRONOUS_MARKER) {
-                if(hdr.xid == PING_XID){
-                    int elapsed = 0;
-                    struct timeval now;
-                    gettimeofday(&now, 0);
-                    elapsed = calculate_interval(&zh->last_ping, &now);
-                    LOG_DEBUG(("Got ping response in %d ms", elapsed));
-
-                    // Nothing to do with a ping response
-                    free_buffer(bptr);
-                    destroy_completion_entry(cptr);
-                } else {
-                    LOG_DEBUG(("Queueing asynchronous response"));
-
-                    cptr->buffer = bptr;
-                    queue_completion(&zh->completions_to_process, cptr, 0);
-                }
+                LOG_DEBUG(LOGCALLBACK(zh), "Queueing asynchronous response");
+                cptr->buffer = bptr;
+                queue_completion(&zh->completions_to_process, cptr, 0);
             } else {
                 struct sync_completion
                         *sc = (struct sync_completion*)cptr->data;
diff --git zkc-3.4.5-orig/c/tests/TestOperations.cc zkc-3.4.5/c/tests/TestOperations.cc
index b0370e9..27d9270 100644
--- zkc-3.4.5-orig/c/tests/TestOperations.cc
+++ zkc-3.4.5/c/tests/TestOperations.cc
@@ -29,6 +29,7 @@ class Zookeeper_operations : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST_SUITE(Zookeeper_operations);
 #ifndef THREADED
     CPPUNIT_TEST(testPing);
+    CPPUNIT_TEST(testUnsolicitedPing);
     CPPUNIT_TEST(testTimeoutCausedByWatches1);
     CPPUNIT_TEST(testTimeoutCausedByWatches2);<commit_msg>Fix incompatible LOG_DEBUG change from HEAD<commit_after>diff --git zkc-3.4.5-orig/c/src/zookeeper.c zkc-3.4.5/c/src/zookeeper.c
index de58c62..2347ff4 100644
--- zkc-3.4.5-orig/c/src/zookeeper.c
+++ zkc-3.4.5/c/src/zookeeper.c
@@ -1167,25 +1167,20 @@ void free_completions(zhandle_t *zh,int callCompletion,int reason)
             zh->outstanding_sync--;
             destroy_completion_entry(cptr);
         } else if (callCompletion) {
-            if(cptr->xid == PING_XID){
-                // Nothing to do with a ping response
-                destroy_completion_entry(cptr);
-            } else {
-                // Fake the response
-                buffer_list_t *bptr;
-                h.xid = cptr->xid;
-                h.zxid = -1;
-                h.err = reason;
-                oa = create_buffer_oarchive();
-                serialize_ReplyHeader(oa, "header", &h);
-                bptr = calloc(sizeof(*bptr), 1);
-                assert(bptr);
-                bptr->len = get_buffer_len(oa);
-                bptr->buffer = get_buffer(oa);
-                close_buffer_oarchive(&oa, 0);
-                cptr->buffer = bptr;
-                queue_completion(&zh->completions_to_process, cptr, 0);
-            }
+            // Fake the response
+            buffer_list_t *bptr;
+            h.xid = cptr->xid;
+            h.zxid = -1;
+            h.err = reason;
+            oa = create_buffer_oarchive();
+            serialize_ReplyHeader(oa, "header", &h);
+            bptr = calloc(sizeof(*bptr), 1);
+            assert(bptr);
+            bptr->len = get_buffer_len(oa);
+            bptr->buffer = get_buffer(oa);
+            close_buffer_oarchive(&oa, 0);
+            cptr->buffer = bptr;
+            queue_completion(&zh->completions_to_process, cptr, 0);
         }
     }
     a_list.completion = NULL;
@@ -1526,7 +1521,6 @@ static struct timeval get_timeval(int interval)
     rc = serialize_RequestHeader(oa, "header", &h);
     enter_critical(zh);
     gettimeofday(&zh->last_ping, 0);
-    rc = rc < 0 ? rc : add_void_completion(zh, h.xid, 0, 0);
     rc = rc < 0 ? rc : queue_buffer_bytes(&zh->to_send, get_buffer(oa),
             get_buffer_len(oa));
     leave_critical(zh);
@@ -2063,12 +2057,8 @@ static void deserialize_response(int type, int xid, int failed, int rc, completi
     case COMPLETION_VOID:
         LOG_DEBUG(("Calling COMPLETION_VOID for xid=%#x failed=%d rc=%d",
                     cptr->xid, failed, rc));
-        if (xid == PING_XID) {
-            // We want to skip the ping
-        } else {
-            assert(cptr->c.void_result);
-            cptr->c.void_result(rc, cptr->data);
-        }
+        assert(cptr->c.void_result);
+        cptr->c.void_result(rc, cptr->data);
         break;
     case COMPLETION_MULTI:
         LOG_DEBUG(("Calling COMPLETION_MULTI for xid=%#x failed=%d rc=%d",
@@ -2184,7 +2174,15 @@ int zookeeper_process(zhandle_t *zh, int events)
             // fprintf(stderr, "Got %#x for %#x\n", hdr.zxid, hdr.xid);
         }
 
-        if (hdr.xid == WATCHER_EVENT_XID) {
+        if (hdr.xid == PING_XID) {
+            // Ping replies can arrive out-of-order
+            int elapsed = 0;
+            struct timeval now;
+            gettimeofday(&now, 0);
+            elapsed = calculate_interval(&zh->last_ping, &now);
+            LOG_DEBUG(("Got ping response in %d ms", elapsed));
+            free_buffer(bptr);
+        } else if (hdr.xid == WATCHER_EVENT_XID) {
             struct WatcherEvent evt;
             int type = 0;
             char *path = NULL;
@@ -2250,22 +2248,9 @@ int zookeeper_process(zhandle_t *zh, int events)
             activateWatcher(zh, cptr->watcher, rc);
 
             if (cptr->c.void_result != SYNCHRONOUS_MARKER) {
-                if(hdr.xid == PING_XID){
-                    int elapsed = 0;
-                    struct timeval now;
-                    gettimeofday(&now, 0);
-                    elapsed = calculate_interval(&zh->last_ping, &now);
-                    LOG_DEBUG(("Got ping response in %d ms", elapsed));
-
-                    // Nothing to do with a ping response
-                    free_buffer(bptr);
-                    destroy_completion_entry(cptr);
-                } else {
-                    LOG_DEBUG(("Queueing asynchronous response"));
-
-                    cptr->buffer = bptr;
-                    queue_completion(&zh->completions_to_process, cptr, 0);
-                }
+                LOG_DEBUG(("Queueing asynchronous response"));
+                cptr->buffer = bptr;
+                queue_completion(&zh->completions_to_process, cptr, 0);
             } else {
                 struct sync_completion
                         *sc = (struct sync_completion*)cptr->data;
diff --git zkc-3.4.5-orig/c/tests/TestOperations.cc zkc-3.4.5/c/tests/TestOperations.cc
index b0370e9..27d9270 100644
--- zkc-3.4.5-orig/c/tests/TestOperations.cc
+++ zkc-3.4.5/c/tests/TestOperations.cc
@@ -29,6 +29,7 @@ class Zookeeper_operations : public CPPUNIT_NS::TestFixture
     CPPUNIT_TEST_SUITE(Zookeeper_operations);
 #ifndef THREADED
     CPPUNIT_TEST(testPing);
+    CPPUNIT_TEST(testUnsolicitedPing);
     CPPUNIT_TEST(testTimeoutCausedByWatches1);
     CPPUNIT_TEST(testTimeoutCausedByWatches2);
{'fraction_non_alphanumeric': 0.13550340651021953, 'fraction_numerical': 0.026305828917486753, 'mean_word_length': 1.796031746031746, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 63, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7049915', 'n_tokens_mistral': 3792, 'n_tokens_neox': 3485, 'n_words': 644}