]> git.sur5r.net Git - openldap/commitdiff
ITS#8486 Don't keep sl_mutex locked when playing the sessionlog
authorHoward Chu <hyc@openldap.org>
Fri, 19 Jan 2018 17:11:49 +0000 (17:11 +0000)
committerHoward Chu <hyc@openldap.org>
Sun, 11 Feb 2018 16:47:47 +0000 (16:47 +0000)
servers/slapd/overlays/syncprov.c

index 8d355e0d68979674cecd5393ec1f74ed3b12d270..fbb06050ff0877962d979cf2430d3773a6467064 100644 (file)
@@ -131,6 +131,7 @@ typedef struct sessionlog {
        int             sl_numcsns;
        int             sl_num;
        int             sl_size;
+       int             sl_playing;
        slog_entry *sl_head;
        slog_entry *sl_tail;
        ldap_pvt_thread_mutex_t sl_mutex;
@@ -1552,12 +1553,15 @@ syncprov_add_slog( Operation *op )
                         * wipe out anything in the log if we see them.
                         */
                        ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
+                       /* can only do this if no one else is reading the log at the moment */
+                       if (!sl->sl_playing) {
                        while ( se = sl->sl_head ) {
                                sl->sl_head = se->se_next;
                                ch_free( se );
                        }
                        sl->sl_tail = NULL;
                        sl->sl_num = 0;
+                       }
                        ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
                        return;
                }
@@ -1608,6 +1612,7 @@ syncprov_add_slog( Operation *op )
                        }
                }
                sl->sl_num++;
+               if (!sl->sl_playing) {
                while ( sl->sl_num > sl->sl_size ) {
                        int i;
                        se = sl->sl_head;
@@ -1624,6 +1629,7 @@ syncprov_add_slog( Operation *op )
                        ch_free( se );
                        sl->sl_num--;
                }
+               }
                ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
        }
 }
@@ -1658,6 +1664,8 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
        num = sl->sl_num;
        i = 0;
        nmods = 0;
+       sl->sl_playing++;
+       ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
 
        uuids = op->o_tmpalloc( (num+1) * sizeof( struct berval ) +
                num * UUID_LEN, op->o_tmpmemctx );
@@ -1714,6 +1722,8 @@ syncprov_playlog( Operation *op, SlapReply *rs, sessionlog *sl,
                AC_MEMCPY(uuids[j].bv_val, se->se_uuid.bv_val, UUID_LEN);
                uuids[j].bv_len = UUID_LEN;
        }
+       ldap_pvt_thread_mutex_lock( &sl->sl_mutex );
+       sl->sl_playing--;
        ldap_pvt_thread_mutex_unlock( &sl->sl_mutex );
 
        ndel = i;