<p>related to <a href="https://github.com/kamailio/kamailio/commit/be46742ebe162a2c48ee5ce27e09497b23b66ea5" class="commit-link"><tt>be46742</tt></a></p>
<p>the below patch solves it, but i'm not sure of the implications<br>
why not let the expire routine do its job instead of checking expiration when adding a value ?<br>
also moved the <code>ht_handle_expired_record</code> after the record is removed</p>
<pre><code>diff --git a/src/modules/htable/ht_api.c b/src/modules/htable/ht_api.c
index 1bbd079..92a9421 100644
--- a/src/modules/htable/ht_api.c
+++ b/src/modules/htable/ht_api.c
@@ -674,29 +674,29 @@
                                && strncmp(name->s, it->name.s, name->len)==0)
                {
                        /* found */
-                       if(now>0 && it->expire!=0 && it->expire<now) {
-                               /* entry has expired */
-                               ht_handle_expired_record(ht, it);
-
-                               if(ht->flags==PV_VAL_INT) {
-                                       /* initval is integer, use it to create a fresh entry */
-                                       it->flags &= ~AVP_VAL_STR;
-                                       it->value.n = ht->initval.n;
-                                       /* increment will be done below */
-                               } else {
-                                       /* delete expired entry */
-                                       if(it->prev==NULL)
-                                               ht->entries[idx].first = it->next;
-                                       else
-                                               it->prev->next = it->next;
-                                       if(it->next)
-                                               it->next->prev = it->prev;
-                                       ht->entries[idx].esize--;
-                                       if(mode) ht_slot_unlock(ht, idx);
-                                       ht_cell_free(it);
-                                       return NULL;
-                               }
-                       }
+//                     if(now>0 && it->expire!=0 && it->expire<now) {
+//                             /* entry has expired */
+//                             ht_handle_expired_record(ht, it);
+//
+//                             if(ht->flags==PV_VAL_INT) {
+//                                     /* initval is integer, use it to create a fresh entry */
+//                                     it->flags &= ~AVP_VAL_STR;
+//                                     it->value.n = ht->initval.n;
+//                                     /* increment will be done below */
+//                             } else {
+//                                     /* delete expired entry */
+//                                     if(it->prev==NULL)
+//                                             ht->entries[idx].first = it->next;
+//                                     else
+//                                             it->prev->next = it->next;
+//                                     if(it->next)
+//                                             it->next->prev = it->prev;
+//                                     ht->entries[idx].esize--;
+//                                     if(mode) ht_slot_unlock(ht, idx);
+//                                     ht_cell_free(it);
+//                                     return NULL;
+//                             }
+//                     }
                        /* update value */
                        if(it->flags&AVP_VAL_STR)
                        {
@@ -803,21 +803,21 @@
                                && strncmp(name->s, it->name.s, name->len)==0)
                {
                        /* found */
-                       if(ht->htexpire>0 && it->expire!=0 && it->expire<time(NULL)) {
-                               /* entry has expired, delete it and return NULL */
-                               ht_handle_expired_record(ht, it);
-
-                               if(it->prev==NULL)
-                                       ht->entries[idx].first = it->next;
-                               else
-                                       it->prev->next = it->next;
-                               if(it->next)
-                                       it->next->prev = it->prev;
-                               ht->entries[idx].esize--;
-                               ht_slot_unlock(ht, idx);
-                               ht_cell_free(it);
-                               return NULL;
-                       }
+//                     if(ht->htexpire>0 && it->expire!=0 && it->expire<time(NULL)) {
+//                             /* entry has expired, delete it and return NULL */
+//                             ht_handle_expired_record(ht, it);
+//
+//                             if(it->prev==NULL)
+//                                     ht->entries[idx].first = it->next;
+//                             else
+//                                     it->prev->next = it->next;
+//                             if(it->next)
+//                                     it->next->prev = it->prev;
+//                             ht->entries[idx].esize--;
+//                             ht_slot_unlock(ht, idx);
+//                             ht_cell_free(it);
+//                             return NULL;
+//                     }
                        if(old!=NULL)
                        {
                                if(old->msize>=it->msize)
@@ -1056,7 +1056,6 @@
                                        if(it->expire!=0 && it->expire<now)
                                        {
                                                /* expired */
-                                               ht_handle_expired_record(ht, it);
                                                if(it->prev==NULL)
                                                        ht->entries[i].first = it->next;
                                                else
@@ -1064,6 +1063,7 @@
                                                if(it->next)
                                                        it->next->prev = it->prev;
                                                ht->entries[i].esize--;
+                                               ht_handle_expired_record(ht, it);
                                                ht_cell_free(it);
                                        }
                                        it = it0;
</code></pre>

<p style="font-size:small;-webkit-text-size-adjust:none;color:#666;">—<br />You are receiving this because you are subscribed to this thread.<br />Reply to this email directly, <a href="https://github.com/kamailio/kamailio/issues/1152">view it on GitHub</a>, or <a href="https://github.com/notifications/unsubscribe-auth/AF36ZVJ0aBs8Eksya1_O7_sAe6-2kT1Rks5sFmLTgaJpZM4N-IWr">mute the thread</a>.<img alt="" height="1" src="https://github.com/notifications/beacon/AF36ZTy2G1x9mn78c0mYaVfjb9KooEGjks5sFmLTgaJpZM4N-IWr.gif" width="1" /></p>
<div itemscope itemtype="http://schema.org/EmailMessage">
<div itemprop="action" itemscope itemtype="http://schema.org/ViewAction">
  <link itemprop="url" href="https://github.com/kamailio/kamailio/issues/1152"></link>
  <meta itemprop="name" content="View Issue"></meta>
</div>
<meta itemprop="description" content="View this Issue on GitHub"></meta>
</div>

<script type="application/json" data-scope="inboxmarkup">{"api_version":"1.0","publisher":{"api_key":"05dde50f1d1a384dd78767c55493e4bb","name":"GitHub"},"entity":{"external_key":"github/kamailio/kamailio","title":"kamailio/kamailio","subtitle":"GitHub repository","main_image_url":"https://cloud.githubusercontent.com/assets/143418/17495839/a5054eac-5d88-11e6-95fc-7290892c7bb5.png","avatar_image_url":"https://cloud.githubusercontent.com/assets/143418/15842166/7c72db34-2c0b-11e6-9aed-b52498112777.png","action":{"name":"Open in GitHub","url":"https://github.com/kamailio/kamailio"}},"updates":{"snippets":[{"icon":"DESCRIPTION","message":"htable race condition on expired keys (#1152)"}],"action":{"name":"View Issue","url":"https://github.com/kamailio/kamailio/issues/1152"}}}</script>