+static int
+syncprov_new_ctxcsn( opcookie *opc, syncprov_info_t *si, int csn_changed, int numvals, BerVarray vals )
+{
+ unsigned i;
+ int j, sid;
+
+ for ( i=0; i<numvals; i++ ) {
+ sid = slap_parse_csn_sid( &vals[i] );
+ for ( j=0; j<si->si_numcsns; j++ ) {
+ if ( sid < si->si_sids[j] )
+ break;
+ if ( sid == si->si_sids[j] ) {
+ if ( ber_bvcmp( &vals[i], &si->si_ctxcsn[j] ) > 0 ) {
+ ber_bvreplace( &si->si_ctxcsn[j], &vals[i] );
+ csn_changed = 1;
+ }
+ break;
+ }
+ }
+
+ if ( j == si->si_numcsns || sid != si->si_sids[j] ) {
+ slap_insert_csn_sids( (struct sync_cookie *)&si->si_ctxcsn,
+ j, sid, &vals[i] );
+ csn_changed = 1;
+ }
+ }
+ if ( csn_changed )
+ si->si_dirty = 0;
+ ldap_pvt_thread_rdwr_wunlock( &si->si_csn_rwlock );
+
+ if ( csn_changed ) {
+ syncops *ss;
+ ldap_pvt_thread_mutex_lock( &si->si_ops_mutex );
+ for ( ss = si->si_ops; ss; ss = ss->s_next ) {
+ if ( ss->s_op->o_abandon )
+ continue;
+ /* Send the updated csn to all syncrepl consumers,
+ * including the server from which it originated.
+ * The syncrepl consumer and syncprov provider on
+ * the originating server may be configured to store
+ * their csn values in different entries.
+ */
+ syncprov_qresp( opc, ss, LDAP_SYNC_NEW_COOKIE );
+ }
+ ldap_pvt_thread_mutex_unlock( &si->si_ops_mutex );
+ }
+ return csn_changed;
+}
+