diff --git a/servers/slapd/syncrepl.c b/servers/slapd/syncrepl.c
index e8ddee979ae93582507bc97db7dc683f324cee4b..161ff46b144c208b1c99da4e27a464710dc4696a 100644
--- a/servers/slapd/syncrepl.c
+++ b/servers/slapd/syncrepl.c
@@ -834,10 +834,17 @@ do_syncrep2(
 					syncCookie.ctxcsn )
 				{
 					rc = syncrepl_updateCookie( si, op, psub, &syncCookie );
-				} else if ( rc == LDAP_NO_SUCH_OBJECT ) {
-					rc = LDAP_SYNC_REFRESH_REQUIRED;
-					si->si_logstate = SYNCLOG_FALLBACK;
-					ldap_abandon_ext( si->si_ld, si->si_msgid, NULL, NULL );
+				} else switch ( rc ) {
+					case LDAP_ALREADY_EXISTS:
+					case LDAP_NO_SUCH_OBJECT:
+					case LDAP_NO_SUCH_ATTRIBUTE:
+					case LDAP_TYPE_OR_VALUE_EXISTS:
+						rc = LDAP_SYNC_REFRESH_REQUIRED;
+						si->si_logstate = SYNCLOG_FALLBACK;
+						ldap_abandon_ext( si->si_ld, si->si_msgid, NULL, NULL );
+						break;
+					default:
+						break;
 				}
 			} else if ( ( rc = syncrepl_message_to_entry( si, op, msg,
 				&modlist, &entry, syncstate ) ) == LDAP_SUCCESS )
@@ -1157,7 +1164,7 @@ do_syncrepl(
 	OperationBuffer opbuf;
 	Operation *op;
 	int rc = LDAP_SUCCESS;
-	int dostop = 0;
+	int dostop = 0, do_setup = 0;
 	ber_socket_t s;
 	int i, defer = 1, fail = 0;
 	Backend *be;
@@ -1167,9 +1174,8 @@ do_syncrepl(
 	if ( si == NULL )
 		return NULL;
 
-	/* Don't wait around if there's a previous session still running */
-	if ( ldap_pvt_thread_mutex_trylock( &si->si_mutex ))
-		return NULL;
+	/* There will never be more than one instance active */
+	ldap_pvt_thread_mutex_lock( &si->si_mutex );
 
 	switch( abs( si->si_type ) ) {
 	case LDAP_SYNC_REFRESH_ONLY:
@@ -1268,8 +1274,9 @@ reload:
 				if ( rc == LDAP_SUCCESS ) {
 					if ( si->si_conn ) {
 						connection_client_enable( si->si_conn );
+						goto success;
 					} else {
-						si->si_conn = connection_client_setup( s, do_syncrepl, arg );
+						do_setup = 1;
 					} 
 				} else if ( si->si_conn ) {
 					dostop = 1;
@@ -1335,6 +1342,11 @@ reload:
 	}
 
 	ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+
+	if ( do_setup )
+		si->si_conn = connection_client_setup( s, do_syncrepl, arg );
+
+success:
 	ldap_pvt_thread_mutex_unlock( &si->si_mutex );
 
 	if ( rc ) {
@@ -3260,6 +3272,7 @@ syncinfo_free( syncinfo_t *sie, int free_all )
 		}
 	
 		/* re-fetch it, in case it was already removed */
+		ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
 		sie->si_re = ldap_pvt_runqueue_find( &slapd_rq, do_syncrepl, sie );
 		if ( sie->si_re ) {
 			if ( ldap_pvt_runqueue_isrunning( &slapd_rq, sie->si_re ) )
@@ -3267,6 +3280,7 @@ syncinfo_free( syncinfo_t *sie, int free_all )
 			ldap_pvt_runqueue_remove( &slapd_rq, sie->si_re );
 		}
 	
+		ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
 	 	ldap_pvt_thread_mutex_destroy( &sie->si_mutex );
 	
 		bindconf_free( &sie->si_bindconf );
@@ -3917,9 +3931,11 @@ add_syncrepl(
 
 			if ( !isMe ) {
 				init_syncrepl( si );
+				ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
 				si->si_re = ldap_pvt_runqueue_insert( &slapd_rq,
 					si->si_interval, do_syncrepl, si, "do_syncrepl",
 					si->si_ridtxt );
+				ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
 				if ( si->si_re )
 					rc = config_sync_shadow( c ) ? -1 : 0;
 				else
@@ -4148,13 +4164,18 @@ syncrepl_config( ConfigArgs *c )
 			for ( sip = &c->be->be_syncinfo, i=0; *sip; i++ ) {
 				si = *sip;
 				if ( c->valx == -1 || i == c->valx ) {
+					int isrunning = 0;
 					*sip = si->si_next;
 					/* If the task is currently active, we have to leave
 					 * it running. It will exit on its own. This will only
 					 * happen when running on the cn=config DB.
 					 */
-					if ( si->si_re &&
-						ldap_pvt_runqueue_isrunning( &slapd_rq, si->si_re ) ) {
+					if ( si->si_re ) {
+						ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex );
+						isrunning = ldap_pvt_runqueue_isrunning( &slapd_rq, si->si_re );
+						ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex );
+					}
+					if ( si->si_re && isrunning ) {
 						si->si_ctype = 0;
 					} else {
 						syncinfo_free( si, 0 );