This is a multi-part message in MIME format. --------------090802040703090609040601 Content-Type: text/plain; charset=windows-1251; format=flowed Content-Transfer-Encoding: 8bit
Patch update:
Detaching a syncops record from op-list CONDITIONALLY, only when it was freed by syncprov_free_syncop. The syncprov_drop_psearch() and syncprov_drop_psearch() now returns a flag, which is nonzero if the given syncops was freed.
Leonid.
29.12.2014 13:50, Leonid Yuriev ïèøåò:
Please review attached patch and merge-in.
Leonid.
The attached files is derived from OpenLDAP Software. All of the modifications to OpenLDAP Software represented in the following patch(es) were developed by Peter-Service LLC, Moscow, Russia. Peter-Service LLC has not assigned rights and/or interest in this work to any party. I, Leonid Yuriev am authorized by Peter-Service LLC, my employer, to release this work under the following terms.
Peter-Service LLC hereby places the following modifications to OpenLDAP Software (and only these modifications) into the public domain. Hence, these modifications may be freely used and/or redistributed for any purpose with or without attribution and/or other notice.
--------------090802040703090609040601 Content-Type: text/x-patch; name="its8012.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="its8012.patch"
commit 34d36d685ccb372dfd43a33730b480610ab369a0 Author: Leo Yuriev leo@yuriev.ru Date: 2014-12-29 13:40:59 +0300
ITS#5452, ITS#8012: fix syncops list iteration and detaching on freed;
Detaching a syncops record from op-list conditionally, only when it was freed by syncprov_free_syncop.
The syncprov_drop_psearch() and syncprov_drop_psearch() now returns a flag, which is nonzero if the given syncops was freed.
diff --git a/servers/slapd/overlays/syncprov.c b/servers/slapd/overlays/syncprov.c index 5ef2eaa..2eeda4c 100644 --- a/servers/slapd/overlays/syncprov.c +++ b/servers/slapd/overlays/syncprov.c @@ -790,7 +790,7 @@ static int dec_mutexint( mutexint *mi ) return i; }
-static void +static int syncprov_free_syncop( syncops *so ) { syncres *sr, *srnext; @@ -800,7 +800,7 @@ syncprov_free_syncop( syncops *so ) /* already being freed, or still in use */ if ( !so->s_inuse || --so->s_inuse > 0 ) { ldap_pvt_thread_mutex_unlock( &so->s_mutex ); - return; + return 0; } ldap_pvt_thread_mutex_unlock( &so->s_mutex ); if ( so->s_flags & PS_IS_DETACHED ) { @@ -824,6 +824,7 @@ syncprov_free_syncop( syncops *so ) } ldap_pvt_thread_mutex_destroy( &so->s_mutex ); ch_free( so ); + return 1; }
/* Send a persistent search response */ @@ -1104,9 +1105,7 @@ syncprov_drop_psearch( syncops *so, int lock ) if ( lock ) ldap_pvt_thread_mutex_unlock( &so->s_op->o_conn->c_mutex ); } - syncprov_free_syncop( so ); - - return 0; + return syncprov_free_syncop( so ); }
static int @@ -1166,10 +1165,10 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) syncprov_info_t *si = on->on_bi.bi_private;
fbase_cookie fc; - syncops *ss, *sprev, *snext; + syncops **pss; Entry *e = NULL; Attribute *a; - int rc; + int rc, gonext; struct berval newdn; int freefdn = 0; BackendDB *b0 = op->o_bd, db; @@ -1229,15 +1228,15 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) }
ldap_pvt_thread_mutex_lock( &si->si_ops_mutex ); - for (ss = si->si_ops, sprev = (syncops *)&si->si_ops; ss; - sprev = ss, ss=snext) + for (pss = &si->si_ops; *pss; pss = gonext ? &(*pss)->s_next : pss) { Operation op2; Opheader oh; syncmatches *sm; int found = 0; + syncops *snext, *ss = *pss;
- snext = ss->s_next; + gonext = 1; if ( ss->s_op->o_abandon ) continue;
@@ -1266,9 +1265,10 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) SlapReply rs = {REP_RESULT}; send_ldap_error( ss->s_op, &rs, LDAP_SYNC_REFRESH_REQUIRED, "search base has changed" ); - sprev->s_next = snext; - syncprov_drop_psearch( ss, 1 ); - ss = sprev; + snext = ss->s_next; + if ( syncprov_drop_psearch( ss, 1 ) ) + *pss = snext; + gonext = 0; continue; }
@@ -1342,7 +1342,11 @@ syncprov_matchops( Operation *op, opcookie *opc, int saveit ) /* Decrement s_inuse, was incremented when called * with saveit == TRUE */ - syncprov_free_syncop( ss ); + snext = ss->s_next; + if ( syncprov_free_syncop( ss ) ) { + *pss = snext; + gonext = 0; + } } } ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
--------------090802040703090609040601--