This is an automated email from the ASF dual-hosted git repository.

maskit pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/master by this push:
     new 482e30a  Destroy MIMEFieldBlockImpl that doesn't have fields in use
482e30a is described below

commit 482e30accbe2e755c73fd1f8dd7e4b2c40705171
Author: Masakazu Kitajo <mas...@apache.org>
AuthorDate: Fri Apr 19 17:06:37 2019 +0900

    Destroy MIMEFieldBlockImpl that doesn't have fields in use
    
    Because MIMEFieldBlocks are destroyed only when MIMEHdr is destroyed, the 
block
    chain never be short. With this change, a block will be destroyed when all 
fields
    in a block are deleted, and the block will be removed from a block chain.
---
 proxy/hdrs/MIME.cc | 40 +++++++++++++++++++++++++++-------------
 proxy/hdrs/MIME.h  |  3 +++
 2 files changed, 30 insertions(+), 13 deletions(-)

diff --git a/proxy/hdrs/MIME.cc b/proxy/hdrs/MIME.cc
index 28388f4..7107401 100644
--- a/proxy/hdrs/MIME.cc
+++ b/proxy/hdrs/MIME.cc
@@ -1642,20 +1642,8 @@ mime_hdr_field_delete(HdrHeap *heap, MIMEHdrImpl *mh, 
MIMEField *field, bool del
 {
   if (delete_all_dups) {
     while (field) {
-      // NOTE: we pass zero to field_detach for detach_all_dups
-      //       since this loop will already detach each dup
       MIMEField *next = field->m_next_dup;
-
-      heap->free_string(field->m_ptr_name, field->m_len_name);
-      heap->free_string(field->m_ptr_value, field->m_len_value);
-
-      MIME_HDR_SANITY_CHECK(mh);
-      mime_hdr_field_detach(mh, field, false);
-
-      MIME_HDR_SANITY_CHECK(mh);
-      mime_field_destroy(mh, field);
-
-      MIME_HDR_SANITY_CHECK(mh);
+      mime_hdr_field_delete(heap, mh, field, false);
       field = next;
     }
   } else {
@@ -1667,6 +1655,32 @@ mime_hdr_field_delete(HdrHeap *heap, MIMEHdrImpl *mh, 
MIMEField *field, bool del
 
     MIME_HDR_SANITY_CHECK(mh);
     mime_field_destroy(mh, field);
+
+    MIMEFieldBlockImpl *prev_block = nullptr;
+    bool can_destroy_block         = true;
+    for (auto fblock = &(mh->m_first_fblock); fblock != nullptr; fblock = 
fblock->m_next) {
+      if (prev_block != nullptr) {
+        if (fblock->m_freetop == MIME_FIELD_BLOCK_SLOTS && 
fblock->contains(field)) {
+          // Check if fields in all slots are deleted
+          for (int i = 0; i < MIME_FIELD_BLOCK_SLOTS; ++i) {
+            if (fblock->m_field_slots[i].m_readiness != 
MIME_FIELD_SLOT_READINESS_DELETED) {
+              can_destroy_block = false;
+              break;
+            }
+          }
+          // Destroy a block and maintain the chain
+          if (can_destroy_block) {
+            prev_block->m_next = fblock->m_next;
+            _mime_field_block_destroy(heap, fblock);
+            if (prev_block->m_next == nullptr) {
+              mh->m_fblock_list_tail = prev_block;
+            }
+          }
+          break;
+        }
+      }
+      prev_block = fblock;
+    }
   }
 
   MIME_HDR_SANITY_CHECK(mh);
diff --git a/proxy/hdrs/MIME.h b/proxy/hdrs/MIME.h
index b42f286..1752ad3 100644
--- a/proxy/hdrs/MIME.h
+++ b/proxy/hdrs/MIME.h
@@ -718,6 +718,9 @@ void mime_hdr_field_attach(MIMEHdrImpl *mh, MIMEField 
*field, int check_for_dups
 void mime_hdr_field_detach(MIMEHdrImpl *mh, MIMEField *field, bool 
detach_all_dups = false);
 void mime_hdr_field_delete(HdrHeap *heap, MIMEHdrImpl *mh, MIMEField *field, 
bool delete_all_dups = false);
 
+/**
+ * Returned slotnum is not a persistent value. A slotnum may refer a different 
field after making changes to a mime header.
+ */
 int mime_hdr_field_slotnum(MIMEHdrImpl *mh, MIMEField *field);
 inkcoreapi MIMEField *mime_hdr_prepare_for_value_set(HdrHeap *heap, 
MIMEHdrImpl *mh, const char *name, int name_length);
 

Reply via email to