Blame SOURCES/0030-Issue-4384-Use-MONOTONIC-clock-for-all-timing-events.patch

be9751
From 6969181628f2c664d5f82c89c15bbc0a2487e21f Mon Sep 17 00:00:00 2001
be9751
From: Mark Reynolds <mreynolds@redhat.com>
be9751
Date: Thu, 19 Nov 2020 15:46:19 -0500
be9751
Subject: [PATCH 1/2] Issue 4384 - Use MONOTONIC clock for all timing events
be9751
 and conditions
be9751
be9751
Bug Description:  All of the server's event handling and replication were
be9751
                  based on REALTIME clocks, which can be influenced by the
be9751
                  system changing.  This could causes massive delays, and
be9751
                  simply cause unexpected behavior.
be9751
be9751
Fix Description:  Move all condition variables to use pthread instead of NSPR
be9751
                  functions.  Also make sure we use MONOTONIC clocks when we
be9751
                  get the current time when checking for timeouts and other
be9751
                  timed events.
be9751
be9751
Relates: https://github.com/389ds/389-ds-base/issues/4384
be9751
be9751
Reviewed by: elkris, firstyear, and tbordaz (Thanks!!!)
be9751
be9751
Apply firstyear's sugestions
be9751
be9751
Apply Firstyear's other suggestions
be9751
be9751
Apply Thierry's suggestions
be9751
---
be9751
 Makefile.am                                   |   2 +-
be9751
 .../tests/suites/plugins/entryusn_test.py     |   3 +
be9751
 ldap/servers/plugins/chainingdb/cb_add.c      |   2 +-
be9751
 ldap/servers/plugins/chainingdb/cb_compare.c  |   2 +-
be9751
 .../plugins/chainingdb/cb_conn_stateless.c    |  16 +-
be9751
 ldap/servers/plugins/chainingdb/cb_delete.c   |   2 +-
be9751
 ldap/servers/plugins/chainingdb/cb_instance.c |   3 +-
be9751
 ldap/servers/plugins/chainingdb/cb_modify.c   |   2 +-
be9751
 ldap/servers/plugins/chainingdb/cb_modrdn.c   |   2 +-
be9751
 ldap/servers/plugins/chainingdb/cb_search.c   |   8 +-
be9751
 ldap/servers/plugins/cos/cos_cache.c          |   4 +-
be9751
 ldap/servers/plugins/dna/dna.c                |   2 +-
be9751
 ldap/servers/plugins/passthru/ptconn.c        |   2 +-
be9751
 ldap/servers/plugins/referint/referint.c      |  85 +++++---
be9751
 ldap/servers/plugins/replication/repl5.h      |   3 +-
be9751
 .../plugins/replication/repl5_backoff.c       |   4 +-
be9751
 .../plugins/replication/repl5_connection.c    |  12 +-
be9751
 .../plugins/replication/repl5_inc_protocol.c  |  91 ++++----
be9751
 .../plugins/replication/repl5_mtnode_ext.c    |   3 +-
be9751
 .../plugins/replication/repl5_prot_private.h  |   6 +-
be9751
 .../plugins/replication/repl5_replica.c       |  10 +-
be9751
 .../replication/repl5_replica_config.c        | 197 +++++++++++-------
be9751
 .../plugins/replication/repl5_tot_protocol.c  |  71 ++++---
be9751
 ldap/servers/plugins/replication/repl_extop.c |   4 +-
be9751
 .../plugins/replication/windows_connection.c  |   2 +-
be9751
 .../replication/windows_inc_protocol.c        |  82 +++++---
be9751
 .../replication/windows_tot_protocol.c        |  24 ++-
be9751
 ldap/servers/plugins/retrocl/retrocl_trim.c   |   2 +-
be9751
 ldap/servers/plugins/roles/roles_cache.c      |   4 +-
be9751
 ldap/servers/plugins/sync/sync.h              |   4 +-
be9751
 ldap/servers/plugins/sync/sync_persist.c      |  54 +++--
be9751
 .../slapd/back-ldbm/db-bdb/bdb_import.c       |  49 ++---
be9751
 .../back-ldbm/db-bdb/bdb_import_threads.c     |  29 +--
be9751
 .../back-ldbm/db-bdb/bdb_instance_config.c    |   8 +-
be9751
 .../slapd/back-ldbm/db-bdb/bdb_layer.c        | 129 +++++++-----
be9751
 .../slapd/back-ldbm/db-bdb/bdb_layer.h        |  10 +-
be9751
 ldap/servers/slapd/back-ldbm/import.h         |   6 +-
be9751
 ldap/servers/slapd/connection.c               |  88 ++++----
be9751
 ldap/servers/slapd/daemon.c                   |  64 ++++--
be9751
 ldap/servers/slapd/eventq.c                   | 132 ++++++++----
be9751
 ldap/servers/slapd/house.c                    |  58 ++++--
be9751
 ldap/servers/slapd/libmakefile                |   2 +-
be9751
 ldap/servers/slapd/psearch.c                  |  63 +++---
be9751
 ldap/servers/slapd/regex.c                    |   2 +-
be9751
 ldap/servers/slapd/slapi-plugin.h             |   7 +
be9751
 .../slapd/{slapi2nspr.c => slapi2runtime.c}   |  87 +++++---
be9751
 ldap/servers/slapd/task.c                     |   4 +-
be9751
 ldap/servers/slapd/time.c                     |  10 +-
be9751
 48 files changed, 877 insertions(+), 579 deletions(-)
be9751
 rename ldap/servers/slapd/{slapi2nspr.c => slapi2runtime.c} (69%)
be9751
be9751
diff --git a/Makefile.am b/Makefile.am
be9751
index 0e5f04f91..f7bf1c44c 100644
be9751
--- a/Makefile.am
be9751
+++ b/Makefile.am
be9751
@@ -1455,7 +1455,7 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \
be9751
 	ldap/servers/slapd/security_wrappers.c \
be9751
 	ldap/servers/slapd/slapd_plhash.c \
be9751
 	ldap/servers/slapd/slapi_counter.c \
be9751
-	ldap/servers/slapd/slapi2nspr.c \
be9751
+	ldap/servers/slapd/slapi2runtime.c \
be9751
 	ldap/servers/slapd/snmp_collator.c \
be9751
 	ldap/servers/slapd/sort.c \
be9751
 	ldap/servers/slapd/ssl.c \
be9751
diff --git a/dirsrvtests/tests/suites/plugins/entryusn_test.py b/dirsrvtests/tests/suites/plugins/entryusn_test.py
be9751
index ad3d7f209..da0538f74 100644
be9751
--- a/dirsrvtests/tests/suites/plugins/entryusn_test.py
be9751
+++ b/dirsrvtests/tests/suites/plugins/entryusn_test.py
be9751
@@ -6,9 +6,11 @@
be9751
 # See LICENSE for details.
be9751
 # --- END COPYRIGHT BLOCK ---
be9751
 #
be9751
+import os
be9751
 import ldap
be9751
 import logging
be9751
 import pytest
be9751
+import time
be9751
 from lib389._constants import DEFAULT_SUFFIX
be9751
 from lib389.config import Config
be9751
 from lib389.plugins import USNPlugin, MemberOfPlugin
be9751
@@ -211,6 +213,7 @@ def test_entryusn_after_repl_delete(topology_m2):
be9751
         user_usn = user_1.get_attr_val_int('entryusn')
be9751
 
be9751
         user_1.delete()
be9751
+        time.sleep(1)  # Gives a little time for tombstone creation to complete
be9751
 
be9751
         ts = tombstones.get(user_rdn)
be9751
         ts_usn = ts.get_attr_val_int('entryusn')
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_add.c b/ldap/servers/plugins/chainingdb/cb_add.c
be9751
index a9f9c0f87..b7ae7267d 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_add.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_add.c
be9751
@@ -130,7 +130,7 @@ chaining_back_add(Slapi_PBlock *pb)
be9751
 
be9751
     /* heart-beat management */
be9751
     if (cb->max_idle_time > 0) {
be9751
-        endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+        endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
     }
be9751
 
be9751
     /* Send LDAP operation to the remote host */
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_compare.c b/ldap/servers/plugins/chainingdb/cb_compare.c
be9751
index 25dfa87b5..8d7fdd06b 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_compare.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_compare.c
be9751
@@ -126,7 +126,7 @@ chaining_back_compare(Slapi_PBlock *pb)
be9751
 
be9751
     /* heart-beat management */
be9751
     if (cb->max_idle_time > 0) {
be9751
-        endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+        endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
     }
be9751
 
be9751
     /*
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_conn_stateless.c b/ldap/servers/plugins/chainingdb/cb_conn_stateless.c
be9751
index 9beb459ef..a2003221e 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_conn_stateless.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_conn_stateless.c
be9751
@@ -453,7 +453,7 @@ cb_get_connection(cb_conn_pool *pool,
be9751
             conn->ld = ld;
be9751
             conn->status = CB_CONNSTATUS_OK;
be9751
             conn->refcount = 0; /* incremented below */
be9751
-            conn->opentime = slapi_current_utc_time();
be9751
+            conn->opentime = slapi_current_rel_time_t();
be9751
             conn->ThreadId = PR_MyThreadId(); /* store the thread id */
be9751
             conn->next = NULL;
be9751
             if (secure) {
be9751
@@ -488,7 +488,7 @@ cb_get_connection(cb_conn_pool *pool,
be9751
         }
be9751
 
be9751
         if (!secure)
be9751
-            slapi_wait_condvar(pool->conn.conn_list_cv, NULL);
be9751
+            slapi_wait_condvar_pt(pool->conn.conn_list_cv, pool->conn.conn_list_mutex, NULL);
be9751
 
be9751
         if (cb_debug_on()) {
be9751
             slapi_log_err(SLAPI_LOG_PLUGIN, CB_PLUGIN_SUBSYSTEM,
be9751
@@ -639,7 +639,7 @@ cb_check_for_stale_connections(cb_conn_pool *pool)
be9751
     slapi_lock_mutex(pool->conn.conn_list_mutex);
be9751
 
be9751
     if (connlifetime > 0)
be9751
-        curtime = slapi_current_utc_time();
be9751
+        curtime = slapi_current_rel_time_t();
be9751
 
be9751
     if (pool->secure) {
be9751
         myself = PR_ThreadSelf();
be9751
@@ -860,7 +860,7 @@ cb_ping_farm(cb_backend_instance *cb, cb_outgoing_conn *cnx, time_t end_time)
be9751
     if (cnx && (cnx->status != CB_CONNSTATUS_OK)) /* Known problem */
be9751
         return LDAP_SERVER_DOWN;
be9751
 
be9751
-    now = slapi_current_utc_time();
be9751
+    now = slapi_current_rel_time_t();
be9751
     if (end_time && ((now <= end_time) || (end_time < 0)))
be9751
         return LDAP_SUCCESS;
be9751
 
be9751
@@ -905,7 +905,7 @@ cb_update_failed_conn_cpt(cb_backend_instance *cb)
be9751
         slapi_unlock_mutex(cb->monitor_availability.cpt_lock);
be9751
         if (cb->monitor_availability.cpt >= CB_NUM_CONN_BEFORE_UNAVAILABILITY) {
be9751
             /* we reach the limit of authorized failed connections => we setup the chaining BE state to unavailable */
be9751
-            now = slapi_current_utc_time();
be9751
+            now = slapi_current_rel_time_t();
be9751
             slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
             cb->monitor_availability.unavailableTimeLimit = now + CB_UNAVAILABLE_PERIOD;
be9751
             slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
@@ -938,7 +938,7 @@ cb_check_availability(cb_backend_instance *cb, Slapi_PBlock *pb)
be9751
     time_t now;
be9751
     if (cb->monitor_availability.farmserver_state == FARMSERVER_UNAVAILABLE) {
be9751
         slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
-        now = slapi_current_utc_time();
be9751
+        now = slapi_current_rel_time_t();
be9751
         if (now >= cb->monitor_availability.unavailableTimeLimit) {
be9751
             cb->monitor_availability.unavailableTimeLimit = now + CB_INFINITE_TIME; /* to be sure only one thread can do the test */
be9751
             slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
@@ -951,7 +951,7 @@ cb_check_availability(cb_backend_instance *cb, Slapi_PBlock *pb)
be9751
                       "cb_check_availability - ping the farm server and check if it's still unavailable");
be9751
         if (cb_ping_farm(cb, NULL, 0) != LDAP_SUCCESS) { /* farm still unavailable... Just change the timelimit */
be9751
             slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
-            now = slapi_current_utc_time();
be9751
+            now = slapi_current_rel_time_t();
be9751
             cb->monitor_availability.unavailableTimeLimit = now + CB_UNAVAILABLE_PERIOD;
be9751
             slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
             cb_send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL, "FARM SERVER TEMPORARY UNAVAILABLE", 0, NULL);
be9751
@@ -961,7 +961,7 @@ cb_check_availability(cb_backend_instance *cb, Slapi_PBlock *pb)
be9751
         } else {
be9751
             /* farm is back !*/
be9751
             slapi_lock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
-            now = slapi_current_utc_time();
be9751
+            now = slapi_current_rel_time_t();
be9751
             cb->monitor_availability.unavailableTimeLimit = now; /* the unavailable period is finished */
be9751
             slapi_unlock_mutex(cb->monitor_availability.lock_timeLimit);
be9751
             /* The farmer server state backs to FARMSERVER_AVAILABLE, but this already done in cb_ping_farm, and also the reset of cpt*/
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_delete.c b/ldap/servers/plugins/chainingdb/cb_delete.c
be9751
index e76fb6b95..94f84b55d 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_delete.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_delete.c
be9751
@@ -117,7 +117,7 @@ chaining_back_delete(Slapi_PBlock *pb)
be9751
 
be9751
     /* heart-beat management */
be9751
     if (cb->max_idle_time > 0) {
be9751
-        endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+        endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
     }
be9751
 
be9751
     /*
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
be9751
index cd5abb834..bc1864c1a 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
be9751
@@ -1947,7 +1947,8 @@ cb_instance_add_config_callback(Slapi_PBlock *pb __attribute__((unused)),
be9751
          * we can't call recursively into the DSE to do more adds, they'll
be9751
          * silently fail.  instead, schedule the adds to happen in 1 second.
be9751
          */
be9751
-        inst->eq_ctx = slapi_eq_once(cb_instance_add_monitor_later, (void *)inst, time(NULL) + 1);
be9751
+        inst->eq_ctx = slapi_eq_once(cb_instance_add_monitor_later, (void *)inst,
be9751
+                                     slapi_current_rel_time_t() + 1);
be9751
     }
be9751
 
be9751
     /* Get the list of operational attrs defined in the schema */
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_modify.c b/ldap/servers/plugins/chainingdb/cb_modify.c
be9751
index f81edf4a6..e53da9e40 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_modify.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_modify.c
be9751
@@ -125,7 +125,7 @@ chaining_back_modify(Slapi_PBlock *pb)
be9751
 
be9751
     /* heart-beat management */
be9751
     if (cb->max_idle_time > 0) {
be9751
-        endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+        endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
     }
be9751
 
be9751
     /*
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_modrdn.c b/ldap/servers/plugins/chainingdb/cb_modrdn.c
be9751
index 95a068be7..d648253c7 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_modrdn.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_modrdn.c
be9751
@@ -129,7 +129,7 @@ chaining_back_modrdn(Slapi_PBlock *pb)
be9751
 
be9751
     /* heart-beat management */
be9751
     if (cb->max_idle_time > 0) {
be9751
-        endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+        endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
     }
be9751
 
be9751
     /*
be9751
diff --git a/ldap/servers/plugins/chainingdb/cb_search.c b/ldap/servers/plugins/chainingdb/cb_search.c
be9751
index d47cbc8e4..ffc8f56f8 100644
be9751
--- a/ldap/servers/plugins/chainingdb/cb_search.c
be9751
+++ b/ldap/servers/plugins/chainingdb/cb_search.c
be9751
@@ -236,7 +236,7 @@ chainingdb_build_candidate_list(Slapi_PBlock *pb)
be9751
 
be9751
     /* heart-beat management */
be9751
     if (cb->max_idle_time > 0) {
be9751
-        endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+        endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
     }
be9751
 
be9751
     rc = ldap_search_ext(ld, target, scope, filter, attrs, attrsonly,
be9751
@@ -503,7 +503,7 @@ chainingdb_next_search_entry(Slapi_PBlock *pb)
be9751
 
be9751
     /* heart-beat management */
be9751
     if (cb->max_idle_time > 0) {
be9751
-        endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+        endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
     }
be9751
 
be9751
     while (1) {
be9751
@@ -579,7 +579,7 @@ chainingdb_next_search_entry(Slapi_PBlock *pb)
be9751
 
be9751
             /* heart-beat management */
be9751
             if (cb->max_idle_time > 0) {
be9751
-                endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+                endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
             }
be9751
 
be9751
             /* The server sent one of the entries found by the search */
be9751
@@ -611,7 +611,7 @@ chainingdb_next_search_entry(Slapi_PBlock *pb)
be9751
 
be9751
             /* heart-beat management */
be9751
             if (cb->max_idle_time > 0) {
be9751
-                endtime = slapi_current_utc_time() + cb->max_idle_time;
be9751
+                endtime = slapi_current_rel_time_t() + cb->max_idle_time;
be9751
             }
be9751
 
be9751
             parse_rc = ldap_parse_reference(ctx->ld, res, &referrals, NULL, 1);
be9751
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
be9751
index eb9bd77f9..d404ff901 100644
be9751
--- a/ldap/servers/plugins/cos/cos_cache.c
be9751
+++ b/ldap/servers/plugins/cos/cos_cache.c
be9751
@@ -346,7 +346,7 @@ cos_cache_init(void)
be9751
     if (ret == 0) {
be9751
         slapi_lock_mutex(start_lock);
be9751
         while (!started) {
be9751
-            while (slapi_wait_condvar(start_cond, NULL) == 0)
be9751
+            while (slapi_wait_condvar_pt(start_cond, start_lock, NULL) == 0)
be9751
                 ;
be9751
         }
be9751
         slapi_unlock_mutex(start_lock);
be9751
@@ -401,7 +401,7 @@ cos_cache_wait_on_change(void *arg __attribute__((unused)))
be9751
              * thread notifies our condvar, and so we will not miss any
be9751
              * notifications, including the shutdown notification.
be9751
              */
be9751
-            slapi_wait_condvar(something_changed, NULL);
be9751
+            slapi_wait_condvar_pt(something_changed, change_lock, NULL);
be9751
         } else {
be9751
             /* Something to do...do it below */
be9751
         }
be9751
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
be9751
index 16c625bb0..1cb54580b 100644
be9751
--- a/ldap/servers/plugins/dna/dna.c
be9751
+++ b/ldap/servers/plugins/dna/dna.c
be9751
@@ -907,7 +907,7 @@ dna_load_plugin_config(Slapi_PBlock *pb, int use_eventq)
be9751
          * performing the operation at this point when
be9751
          * starting up  would cause the change to not
be9751
          * get changelogged. */
be9751
-        now = slapi_current_utc_time();
be9751
+        now = slapi_current_rel_time_t();
be9751
         eq_ctx = slapi_eq_once(dna_update_config_event, NULL, now + 30);
be9751
     } else {
be9751
         dna_update_config_event(0, NULL);
be9751
diff --git a/ldap/servers/plugins/passthru/ptconn.c b/ldap/servers/plugins/passthru/ptconn.c
be9751
index 49040f651..637d33843 100644
be9751
--- a/ldap/servers/plugins/passthru/ptconn.c
be9751
+++ b/ldap/servers/plugins/passthru/ptconn.c
be9751
@@ -233,7 +233,7 @@ passthru_get_connection(PassThruServer *srvr, LDAP **ldp)
be9751
         slapi_log_err(SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
be9751
                       "... passthru_get_connection waiting for conn to free up\n");
be9751
 #endif
be9751
-        slapi_wait_condvar(srvr->ptsrvr_connlist_cv, NULL);
be9751
+        slapi_wait_condvar_pt(srvr->ptsrvr_connlist_cv, srvr->ptsrvr_connlist_mutex, NULL);
be9751
 
be9751
 #ifdef PASSTHRU_VERBOSE_LOGGING
be9751
         slapi_log_err(SLAPI_LOG_PLUGIN, PASSTHRU_PLUGIN_SUBSYSTEM,
be9751
diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
be9751
index eb4b089fb..fd5356d72 100644
be9751
--- a/ldap/servers/plugins/referint/referint.c
be9751
+++ b/ldap/servers/plugins/referint/referint.c
be9751
@@ -71,8 +71,9 @@ void referint_get_config(int *delay, char **logfile);
be9751
 /* global thread control stuff */
be9751
 static PRLock *referint_mutex = NULL;
be9751
 static PRThread *referint_tid = NULL;
be9751
-static PRLock *keeprunning_mutex = NULL;
be9751
-static PRCondVar *keeprunning_cv = NULL;
be9751
+static pthread_mutex_t keeprunning_mutex;
be9751
+static pthread_cond_t keeprunning_cv;
be9751
+
be9751
 static int keeprunning = 0;
be9751
 static referint_config *config = NULL;
be9751
 static Slapi_DN *_ConfigAreaDN = NULL;
be9751
@@ -1302,12 +1303,38 @@ referint_postop_start(Slapi_PBlock *pb)
be9751
      *     -1 = integrity off
be9751
      */
be9751
     if (referint_get_delay() > 0) {
be9751
+        pthread_condattr_t condAttr;
be9751
+
be9751
         /* initialize the cv and lock */
be9751
         if (!use_txn && (NULL == referint_mutex)) {
be9751
             referint_mutex = PR_NewLock();
be9751
         }
be9751
-        keeprunning_mutex = PR_NewLock();
be9751
-        keeprunning_cv = PR_NewCondVar(keeprunning_mutex);
be9751
+        if ((rc = pthread_mutex_init(&keeprunning_mutex, NULL)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "referint_postop_start",
be9751
+                          "cannot create new lock.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            exit(1);
be9751
+        }
be9751
+        if ((rc = pthread_condattr_init(&condAttr)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "referint_postop_start",
be9751
+                          "cannot create new condition attribute variable.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            exit(1);
be9751
+        }
be9751
+        if ((rc = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "referint_postop_start",
be9751
+                          "cannot set condition attr clock.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            exit(1);
be9751
+        }
be9751
+        if ((rc = pthread_cond_init(&keeprunning_cv, &condAttr)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "referint_postop_start",
be9751
+                          "cannot create new condition variable.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            exit(1);
be9751
+        }
be9751
+        pthread_condattr_destroy(&condAttr); /* no longer needed */
be9751
+
be9751
         keeprunning = 1;
be9751
 
be9751
         referint_tid = PR_CreateThread(PR_USER_THREAD,
be9751
@@ -1337,13 +1364,11 @@ int
be9751
 referint_postop_close(Slapi_PBlock *pb __attribute__((unused)))
be9751
 {
be9751
     /* signal the thread to exit */
be9751
-    if (NULL != keeprunning_mutex) {
be9751
-        PR_Lock(keeprunning_mutex);
be9751
+    if (referint_get_delay() > 0) {
be9751
+        pthread_mutex_lock(&keeprunning_mutex);
be9751
         keeprunning = 0;
be9751
-        if (NULL != keeprunning_cv) {
be9751
-            PR_NotifyCondVar(keeprunning_cv);
be9751
-        }
be9751
-        PR_Unlock(keeprunning_mutex);
be9751
+        pthread_cond_signal(&keeprunning_cv);
be9751
+        pthread_mutex_unlock(&keeprunning_mutex);
be9751
     }
be9751
 
be9751
     slapi_destroy_rwlock(config_rwlock);
be9751
@@ -1369,6 +1394,7 @@ referint_thread_func(void *arg __attribute__((unused)))
be9751
     char *iter = NULL;
be9751
     Slapi_DN *sdn = NULL;
be9751
     Slapi_DN *tmpsuperior = NULL;
be9751
+    struct timespec current_time = {0};
be9751
     int delay;
be9751
     int no_changes;
be9751
 
be9751
@@ -1383,20 +1409,22 @@ referint_thread_func(void *arg __attribute__((unused)))
be9751
         no_changes = 1;
be9751
         while (no_changes) {
be9751
 
be9751
-            PR_Lock(keeprunning_mutex);
be9751
+            pthread_mutex_lock(&keeprunning_mutex);
be9751
             if (keeprunning == 0) {
be9751
-                PR_Unlock(keeprunning_mutex);
be9751
+                pthread_mutex_unlock(&keeprunning_mutex);
be9751
                 break;
be9751
             }
be9751
-            PR_Unlock(keeprunning_mutex);
be9751
+            pthread_mutex_unlock(&keeprunning_mutex);
be9751
 
be9751
             referint_lock();
be9751
             if ((prfd = PR_Open(logfilename, PR_RDONLY, REFERINT_DEFAULT_FILE_MODE)) == NULL) {
be9751
                 referint_unlock();
be9751
                 /* go back to sleep and wait for this file */
be9751
-                PR_Lock(keeprunning_mutex);
be9751
-                PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
be9751
-                PR_Unlock(keeprunning_mutex);
be9751
+                pthread_mutex_lock(&keeprunning_mutex);
be9751
+                clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+                current_time.tv_sec += delay;
be9751
+                pthread_cond_timedwait(&keeprunning_cv, &keeprunning_mutex, &current_time);
be9751
+                pthread_mutex_unlock(&keeprunning_mutex);
be9751
             } else {
be9751
                 no_changes = 0;
be9751
             }
be9751
@@ -1407,12 +1435,12 @@ referint_thread_func(void *arg __attribute__((unused)))
be9751
          *  loop before trying to do the changes. The server
be9751
          *  will pick them up on next startup as file still exists
be9751
          */
be9751
-        PR_Lock(keeprunning_mutex);
be9751
+        pthread_mutex_lock(&keeprunning_mutex);
be9751
         if (keeprunning == 0) {
be9751
-            PR_Unlock(keeprunning_mutex);
be9751
+            pthread_mutex_unlock(&keeprunning_mutex);
be9751
             break;
be9751
         }
be9751
-        PR_Unlock(keeprunning_mutex);
be9751
+        pthread_mutex_unlock(&keeprunning_mutex);
be9751
 
be9751
         while (GetNextLine(thisline, MAX_LINE, prfd)) {
be9751
             ptoken = ldap_utf8strtok_r(thisline, delimiter, &iter);
be9751
@@ -1459,21 +1487,16 @@ referint_thread_func(void *arg __attribute__((unused)))
be9751
         referint_unlock();
be9751
 
be9751
         /* wait on condition here */
be9751
-        PR_Lock(keeprunning_mutex);
be9751
-        PR_WaitCondVar(keeprunning_cv, PR_SecondsToInterval(delay));
be9751
-        PR_Unlock(keeprunning_mutex);
be9751
+        pthread_mutex_lock(&keeprunning_mutex);
be9751
+        clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+        current_time.tv_sec += delay;
be9751
+        pthread_cond_timedwait(&keeprunning_cv, &keeprunning_mutex, &current_time);
be9751
+        pthread_mutex_unlock(&keeprunning_mutex);
be9751
     }
be9751
 
be9751
     /* cleanup resources allocated in start  */
be9751
-    if (NULL != keeprunning_mutex) {
be9751
-        PR_DestroyLock(keeprunning_mutex);
be9751
-    }
be9751
-    if (NULL != referint_mutex) {
be9751
-        PR_DestroyLock(referint_mutex);
be9751
-    }
be9751
-    if (NULL != keeprunning_cv) {
be9751
-        PR_DestroyCondVar(keeprunning_cv);
be9751
-    }
be9751
+    pthread_mutex_destroy(&keeprunning_mutex);
be9751
+    pthread_cond_destroy(&keeprunning_cv);
be9751
     slapi_ch_free_string(&logfilename);
be9751
 }
be9751
 
be9751
diff --git a/ldap/servers/plugins/replication/repl5.h b/ldap/servers/plugins/replication/repl5.h
be9751
index f1c596a3f..06e747811 100644
be9751
--- a/ldap/servers/plugins/replication/repl5.h
be9751
+++ b/ldap/servers/plugins/replication/repl5.h
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2010 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * Copyright (C) 2009 Hewlett-Packard Development Company, L.P.
be9751
  * All rights reserved.
be9751
  *
be9751
@@ -28,6 +28,7 @@
be9751
 #include "llist.h"
be9751
 #include "repl5_ruv.h"
be9751
 #include "plstr.h"
be9751
+#include <pthread.h>
be9751
 
be9751
 #define START_UPDATE_DELAY                   2 /* 2 second */
be9751
 #define REPLICA_TYPE_WINDOWS                 1
be9751
diff --git a/ldap/servers/plugins/replication/repl5_backoff.c b/ldap/servers/plugins/replication/repl5_backoff.c
be9751
index 40848b96d..40ec75dd7 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_backoff.c
be9751
+++ b/ldap/servers/plugins/replication/repl5_backoff.c
be9751
@@ -110,7 +110,7 @@ backoff_reset(Backoff_Timer *bt, slapi_eq_fn_t callback, void *callback_data)
be9751
         bt->next_interval = bt->initial_interval;
be9751
     }
be9751
     /* Schedule the callback */
be9751
-    bt->last_fire_time = slapi_current_utc_time();
be9751
+    bt->last_fire_time = slapi_current_rel_time_t();
be9751
     return_value = bt->last_fire_time + bt->next_interval;
be9751
     bt->pending_event = slapi_eq_once(bt->callback, bt->callback_arg,
be9751
                                       return_value);
be9751
@@ -177,7 +177,7 @@ backoff_expired(Backoff_Timer *bt, int margin)
be9751
 
be9751
     PR_ASSERT(NULL != bt);
be9751
     PR_Lock(bt->lock);
be9751
-    return_value = (slapi_current_utc_time() >= (bt->last_fire_time + bt->next_interval + margin));
be9751
+    return_value = (slapi_current_rel_time_t() >= (bt->last_fire_time + bt->next_interval + margin));
be9751
     PR_Unlock(bt->lock);
be9751
     return return_value;
be9751
 }
be9751
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
be9751
index cf57c2156..bc9ca424b 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_connection.c
be9751
+++ b/ldap/servers/plugins/replication/repl5_connection.c
be9751
@@ -402,7 +402,7 @@ conn_read_result_ex(Repl_Connection *conn, char **retoidp, struct berval **retda
be9751
         }
be9751
         if (block) {
be9751
             /* Did the connection's timeout expire ? */
be9751
-            time_now = slapi_current_utc_time();
be9751
+            time_now = slapi_current_rel_time_t();
be9751
             if (conn->timeout.tv_sec <= (time_now - start_time)) {
be9751
                 /* We timed out */
be9751
                 rc = 0;
be9751
@@ -676,7 +676,7 @@ conn_is_available(Repl_Connection *conn)
be9751
 {
be9751
     time_t poll_timeout_sec = 1;   /* Polling for 1sec */
be9751
     time_t yield_delay_msec = 100; /* Delay to wait */
be9751
-    time_t start_time = slapi_current_utc_time();
be9751
+    time_t start_time = slapi_current_rel_time_t();
be9751
     time_t time_now;
be9751
     ConnResult return_value = CONN_OPERATION_SUCCESS;
be9751
 
be9751
@@ -686,7 +686,7 @@ conn_is_available(Repl_Connection *conn)
be9751
             /* in case of timeout we return CONN_TIMEOUT only
be9751
              * if the RA.timeout is exceeded
be9751
              */
be9751
-            time_now = slapi_current_utc_time();
be9751
+            time_now = slapi_current_rel_time_t();
be9751
             if (conn->timeout.tv_sec <= (time_now - start_time)) {
be9751
                 break;
be9751
             } else {
be9751
@@ -1010,7 +1010,7 @@ linger_timeout(time_t event_time __attribute__((unused)), void *arg)
be9751
 void
be9751
 conn_start_linger(Repl_Connection *conn)
be9751
 {
be9751
-    time_t now;
be9751
+    time_t now = slapi_current_rel_time_t();
be9751
 
be9751
     PR_ASSERT(NULL != conn);
be9751
     slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
be9751
@@ -1022,7 +1022,7 @@ conn_start_linger(Repl_Connection *conn)
be9751
                       agmt_get_long_name(conn->agmt));
be9751
         return;
be9751
     }
be9751
-    now = slapi_current_utc_time();
be9751
+
be9751
     PR_Lock(conn->lock);
be9751
     if (conn->linger_active) {
be9751
         slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
be9751
@@ -1989,7 +1989,7 @@ repl5_start_debug_timeout(int *setlevel)
be9751
 {
be9751
     Slapi_Eq_Context eqctx = 0;
be9751
     if (s_debug_timeout && s_debug_level) {
be9751
-        time_t now = slapi_current_utc_time();
be9751
+        time_t now = slapi_current_rel_time_t();
be9751
         eqctx = slapi_eq_once(repl5_debug_timeout_callback, setlevel,
be9751
                               s_debug_timeout + now);
be9751
     }
be9751
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c b/ldap/servers/plugins/replication/repl5_inc_protocol.c
be9751
index af5e5897c..4bb384882 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
be9751
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -129,7 +129,7 @@ typedef struct result_data
be9751
  * don't see any updates for a period equal to this interval,
be9751
  * we go ahead and start a replication session, just to be safe
be9751
  */
be9751
-#define MAX_WAIT_BETWEEN_SESSIONS PR_SecondsToInterval(60 * 5) /* 5 minutes */
be9751
+#define MAX_WAIT_BETWEEN_SESSIONS 300 /* 5 minutes */
be9751
 
be9751
 /*
be9751
  * tests if the protocol has been shutdown and we need to quit
be9751
@@ -145,7 +145,7 @@ typedef struct result_data
be9751
 /* Forward declarations */
be9751
 static PRUint32 event_occurred(Private_Repl_Protocol *prp, PRUint32 event);
be9751
 static void reset_events(Private_Repl_Protocol *prp);
be9751
-static void protocol_sleep(Private_Repl_Protocol *prp, PRIntervalTime duration);
be9751
+static void protocol_sleep(Private_Repl_Protocol *prp, int32_t duration);
be9751
 static int send_updates(Private_Repl_Protocol *prp, RUV *ruv, PRUint32 *num_changes_sent);
be9751
 static void repl5_inc_backoff_expired(time_t timer_fire_time, void *arg);
be9751
 static int examine_update_vector(Private_Repl_Protocol *prp, RUV *ruv);
be9751
@@ -253,7 +253,7 @@ repl5_inc_result_threadmain(void *param)
be9751
         char *uniqueid = NULL;
be9751
         char *ldap_error_string = NULL;
be9751
         time_t time_now = 0;
be9751
-        time_t start_time = slapi_current_utc_time();
be9751
+        time_t start_time = slapi_current_rel_time_t();
be9751
         int connection_error = 0;
be9751
         int operation_code = 0;
be9751
         int backoff_time = 1;
be9751
@@ -275,7 +275,7 @@ repl5_inc_result_threadmain(void *param)
be9751
                 /* We need to a) check that the 'real' timeout hasn't expired and
be9751
                  * b) implement a backoff sleep to avoid spinning */
be9751
                 /* Did the connection's timeout expire ? */
be9751
-                time_now = slapi_current_utc_time();
be9751
+                time_now = slapi_current_rel_time_t();
be9751
                 if (conn_get_timeout(conn) <= (time_now - start_time)) {
be9751
                     /* We timed out */
be9751
                     conres = CONN_TIMEOUT;
be9751
@@ -358,7 +358,7 @@ repl5_inc_result_threadmain(void *param)
be9751
         /* Should we stop ? */
be9751
         PR_Lock(rd->lock);
be9751
         if (!finished && yield_session && rd->abort != SESSION_ABORTED && rd->abort_time == 0) {
be9751
-            rd->abort_time = slapi_current_utc_time();
be9751
+            rd->abort_time = slapi_current_rel_time_t();
be9751
             rd->abort = SESSION_ABORTED; /* only set the abort time once */
be9751
             slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "repl5_inc_result_threadmain - "
be9751
                                                             "Abort control detected, setting abort time...(%s)\n",
be9751
@@ -532,13 +532,11 @@ repl5_inc_delete(Private_Repl_Protocol **prpp)
be9751
         (*prpp)->stop(*prpp);
be9751
     }
be9751
     /* Then, delete all resources used by the protocol */
be9751
-    if ((*prpp)->lock) {
be9751
-        PR_DestroyLock((*prpp)->lock);
be9751
-        (*prpp)->lock = NULL;
be9751
+    if (&((*prpp)->lock)) {
be9751
+        pthread_mutex_destroy(&((*prpp)->lock));
be9751
     }
be9751
-    if ((*prpp)->cvar) {
be9751
-        PR_DestroyCondVar((*prpp)->cvar);
be9751
-        (*prpp)->cvar = NULL;
be9751
+    if (&((*prpp)->cvar)) {
be9751
+        pthread_cond_destroy(&(*prpp)->cvar);
be9751
     }
be9751
     slapi_ch_free((void **)&(*prpp)->private);
be9751
     slapi_ch_free((void **)prpp);
be9751
@@ -712,7 +710,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
                 conn_set_agmt_changed(prp->conn);
be9751
             } else if (event_occurred(prp, EVENT_TRIGGERING_CRITERIA_MET)) { /* change available */
be9751
                 /* just ignore it and go to sleep */
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             } else if ((e1 = event_occurred(prp, EVENT_WINDOW_CLOSED)) ||
be9751
                        event_occurred(prp, EVENT_BACKOFF_EXPIRED)) {
be9751
                 /* this events - should not occur - log a warning and go to sleep */
be9751
@@ -720,13 +718,13 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
                               "repl5_inc_run - %s: "
be9751
                               "Event %s should not occur in state %s; going to sleep\n",
be9751
                               agmt_get_long_name(prp->agmt), e1 ? event2name(EVENT_WINDOW_CLOSED) : event2name(EVENT_BACKOFF_EXPIRED), state2name(current_state));
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             } else {
be9751
                 /* wait until window opens or an event occurs */
be9751
                 slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
be9751
                               "repl5_inc_run - %s: Waiting for update window to open\n",
be9751
                               agmt_get_long_name(prp->agmt));
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             }
be9751
             break;
be9751
 
be9751
@@ -850,7 +848,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
                 }
be9751
                 next_state = STATE_BACKOFF;
be9751
                 backoff_reset(prp_priv->backoff, repl5_inc_backoff_expired, (void *)prp);
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
                 use_busy_backoff_timer = PR_FALSE;
be9751
             }
be9751
             break;
be9751
@@ -899,13 +897,13 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
                */
be9751
                 if (STATE_BACKOFF == next_state) {
be9751
                     /* Step the backoff timer */
be9751
-                    now = slapi_current_utc_time();
be9751
+                    now = slapi_current_rel_time_t();
be9751
                     next_fire_time = backoff_step(prp_priv->backoff);
be9751
                     /* And go back to sleep */
be9751
                     slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
be9751
                                   "repl5_inc_run - %s: Replication session backing off for %ld seconds\n",
be9751
                                   agmt_get_long_name(prp->agmt), next_fire_time - now);
be9751
-                    protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                    protocol_sleep(prp, 0);
be9751
                 } else {
be9751
                     /* Destroy the backoff timer, since we won't need it anymore */
be9751
                     backoff_delete(&prp_priv->backoff);
be9751
@@ -923,7 +921,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
                     next_state = STATE_READY_TO_ACQUIRE;
be9751
                 } else {
be9751
                     /* ignore changes and go to sleep */
be9751
-                    protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                    protocol_sleep(prp, 0);
be9751
                 }
be9751
             } else if (event_occurred(prp, EVENT_WINDOW_OPENED)) {
be9751
                 /* this should never happen - log an error and go to sleep */
be9751
@@ -931,7 +929,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
                                                                "Event %s should not occur in state %s; going to sleep\n",
be9751
                               agmt_get_long_name(prp->agmt), event2name(EVENT_WINDOW_OPENED),
be9751
                               state2name(current_state));
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             }
be9751
             break;
be9751
 
be9751
@@ -1178,7 +1176,7 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
                 reset_events(prp);
be9751
             }
be9751
 
be9751
-            protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+            protocol_sleep(prp, 0);
be9751
             break;
be9751
 
be9751
         case STATE_STOP_NORMAL_TERMINATION:
be9751
@@ -1209,20 +1207,28 @@ repl5_inc_run(Private_Repl_Protocol *prp)
be9751
  * Go to sleep until awakened.
be9751
  */
be9751
 static void
be9751
-protocol_sleep(Private_Repl_Protocol *prp, PRIntervalTime duration)
be9751
+protocol_sleep(Private_Repl_Protocol *prp, int32_t duration)
be9751
 {
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     /* we should not go to sleep if there are events available to be processed.
be9751
        Otherwise, we can miss the event that suppose to wake us up */
be9751
-    if (prp->eventbits == 0)
be9751
-        PR_WaitCondVar(prp->cvar, duration);
be9751
-    else {
be9751
+    if (prp->eventbits == 0) {
be9751
+        if (duration > 0) {
be9751
+            struct timespec current_time = {0};
be9751
+            /* get the current monotonic time and add our interval */
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += duration;
be9751
+            pthread_cond_timedwait(&(prp->cvar), &(prp->lock), &current_time);
be9751
+        } else {
be9751
+            pthread_cond_wait(&(prp->cvar), &(prp->lock));
be9751
+        }
be9751
+    } else {
be9751
         slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
be9751
                       "protocol_sleep - %s: Can't go to sleep: event bits - %x\n",
be9751
                       agmt_get_long_name(prp->agmt), prp->eventbits);
be9751
     }
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
 }
be9751
 
be9751
 /*
be9751
@@ -1235,10 +1241,10 @@ static void
be9751
 event_notify(Private_Repl_Protocol *prp, PRUint32 event)
be9751
 {
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     prp->eventbits |= event;
be9751
-    PR_NotifyCondVar(prp->cvar);
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_cond_signal(&(prp->cvar));
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
 }
be9751
 
be9751
 /*
be9751
@@ -1250,10 +1256,10 @@ event_occurred(Private_Repl_Protocol *prp, PRUint32 event)
be9751
 {
be9751
     PRUint32 return_value;
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     return_value = (prp->eventbits & event);
be9751
     prp->eventbits &= ~event; /* Clear event */
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
     return return_value;
be9751
 }
be9751
 
be9751
@@ -1261,9 +1267,9 @@ static void
be9751
 reset_events(Private_Repl_Protocol *prp)
be9751
 {
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     prp->eventbits = 0;
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
 }
be9751
 
be9751
 /*
be9751
@@ -1882,7 +1888,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
be9751
             /* See if the result thread has hit a problem */
be9751
 
be9751
             if (!finished && rd->abort_time) {
be9751
-                time_t current_time = slapi_current_utc_time();
be9751
+                time_t current_time = slapi_current_rel_time_t();
be9751
                 if ((current_time - rd->abort_time) >= release_timeout) {
be9751
                     rd->result = UPDATE_YIELD;
be9751
                     return_value = UPDATE_YIELD;
be9751
@@ -2088,7 +2094,9 @@ Private_Repl_Protocol *
be9751
 Repl_5_Inc_Protocol_new(Repl_Protocol *rp)
be9751
 {
be9751
     repl5_inc_private *rip = NULL;
be9751
-    Private_Repl_Protocol *prp = (Private_Repl_Protocol *)slapi_ch_malloc(sizeof(Private_Repl_Protocol));
be9751
+    pthread_condattr_t cattr; /* the pthread condition attr */
be9751
+    Private_Repl_Protocol *prp = (Private_Repl_Protocol *)slapi_ch_calloc(1, sizeof(Private_Repl_Protocol));
be9751
+
be9751
     prp->delete = repl5_inc_delete;
be9751
     prp->run = repl5_inc_run;
be9751
     prp->stop = repl5_inc_stop;
be9751
@@ -2099,12 +2107,19 @@ Repl_5_Inc_Protocol_new(Repl_Protocol *rp)
be9751
     prp->notify_window_closed = repl5_inc_notify_window_closed;
be9751
     prp->update_now = repl5_inc_update_now;
be9751
     prp->replica = prot_get_replica(rp);
be9751
-    if ((prp->lock = PR_NewLock()) == NULL) {
be9751
+    if (pthread_mutex_init(&(prp->lock), NULL) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    if (pthread_condattr_init(&cattr) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    if (pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC) != 0) {
be9751
         goto loser;
be9751
     }
be9751
-    if ((prp->cvar = PR_NewCondVar(prp->lock)) == NULL) {
be9751
+    if (pthread_cond_init(&(prp->cvar), &cattr) != 0) {
be9751
         goto loser;
be9751
     }
be9751
+    pthread_condattr_destroy(&cattr);
be9751
     prp->stopped = 0;
be9751
     prp->terminate = 0;
be9751
     prp->eventbits = 0;
be9751
diff --git a/ldap/servers/plugins/replication/repl5_mtnode_ext.c b/ldap/servers/plugins/replication/repl5_mtnode_ext.c
be9751
index 08a58613b..82e230958 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_mtnode_ext.c
be9751
+++ b/ldap/servers/plugins/replication/repl5_mtnode_ext.c
be9751
@@ -82,7 +82,8 @@ multimaster_mtnode_construct_replicas()
be9751
                 }
be9751
             }
be9751
             /* Wait a few seconds for everything to startup before resuming any replication tasks */
be9751
-            slapi_eq_once(replica_check_for_tasks, (void *)replica_get_root(r), time(NULL) + 5);
be9751
+            slapi_eq_once(replica_check_for_tasks, (void *)replica_get_root(r),
be9751
+                          slapi_current_rel_time_t() + 5);
be9751
         }
be9751
     }
be9751
 }
be9751
diff --git a/ldap/servers/plugins/replication/repl5_prot_private.h b/ldap/servers/plugins/replication/repl5_prot_private.h
be9751
index 5b2e1b3ca..0673f1978 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_prot_private.h
be9751
+++ b/ldap/servers/plugins/replication/repl5_prot_private.h
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -32,8 +32,6 @@ typedef struct private_repl_protocol
be9751
     void (*notify_window_opened)(struct private_repl_protocol *);
be9751
     void (*notify_window_closed)(struct private_repl_protocol *);
be9751
     void (*update_now)(struct private_repl_protocol *);
be9751
-    PRLock *lock;
be9751
-    PRCondVar *cvar;
be9751
     int stopped;
be9751
     int terminate;
be9751
     PRUint32 eventbits;
be9751
@@ -46,6 +44,8 @@ typedef struct private_repl_protocol
be9751
     int repl50consumer; /* Flag to tell us if this is a 5.0-style consumer we're talking to */
be9751
     int repl71consumer; /* Flag to tell us if this is a 7.1-style consumer we're talking to */
be9751
     int repl90consumer; /* Flag to tell us if this is a 9.0-style consumer we're talking to */
be9751
+    pthread_mutex_t lock;
be9751
+    pthread_cond_t cvar;
be9751
 } Private_Repl_Protocol;
be9751
 
be9751
 extern Private_Repl_Protocol *Repl_5_Inc_Protocol_new(Repl_Protocol *rp);
be9751
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
be9751
index 7e56d6557..c1d376c72 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_replica.c
be9751
+++ b/ldap/servers/plugins/replication/repl5_replica.c
be9751
@@ -232,7 +232,7 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation,
be9751
        In that case the updated would fail but nothing bad would happen. The next
be9751
        scheduled update would save the state */
be9751
     r->repl_eqcxt_rs = slapi_eq_repeat(replica_update_state, r->repl_name,
be9751
-                                       slapi_current_utc_time() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
be9751
+                                       slapi_current_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
be9751
 
be9751
     if (r->tombstone_reap_interval > 0) {
be9751
         /*
be9751
@@ -240,7 +240,7 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation,
be9751
          * This will allow the server to fully start before consuming resources.
be9751
          */
be9751
         r->repl_eqcxt_tr = slapi_eq_repeat(eq_cb_reap_tombstones, r->repl_name,
be9751
-                                           slapi_current_utc_time() + r->tombstone_reap_interval,
be9751
+                                           slapi_current_rel_time_t() + r->tombstone_reap_interval,
be9751
                                            1000 * r->tombstone_reap_interval);
be9751
     }
be9751
 
be9751
@@ -1088,7 +1088,7 @@ replica_is_updatedn(Replica *r, const Slapi_DN *sdn)
be9751
     if (r->groupdn_list) {
be9751
         /* check and rebuild groupdns */
be9751
         if (r->updatedn_group_check_interval > -1) {
be9751
-            time_t now = slapi_current_utc_time();
be9751
+            time_t now = slapi_current_rel_time_t();
be9751
             if (now - r->updatedn_group_last_check > r->updatedn_group_check_interval) {
be9751
                 Slapi_ValueSet *updatedn_groups_copy = NULL;
be9751
                 ReplicaUpdateDNList groupdn_list = replica_updatedn_list_new(NULL);
be9751
@@ -1512,7 +1512,7 @@ replica_set_enabled(Replica *r, PRBool enable)
be9751
         if (r->repl_eqcxt_rs == NULL) /* event is not already registered */
be9751
         {
be9751
             r->repl_eqcxt_rs = slapi_eq_repeat(replica_update_state, r->repl_name,
be9751
-                                               slapi_current_utc_time() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
be9751
+                                               slapi_current_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
be9751
         }
be9751
     } else /* disable */
be9751
     {
be9751
@@ -3637,7 +3637,7 @@ replica_set_tombstone_reap_interval(Replica *r, long interval)
be9751
     r->tombstone_reap_interval = interval;
be9751
     if (interval > 0 && r->repl_eqcxt_tr == NULL) {
be9751
         r->repl_eqcxt_tr = slapi_eq_repeat(eq_cb_reap_tombstones, r->repl_name,
be9751
-                                           slapi_current_utc_time() + r->tombstone_reap_interval,
be9751
+                                           slapi_current_rel_time_t() + r->tombstone_reap_interval,
be9751
                                            1000 * r->tombstone_reap_interval);
be9751
         slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
be9751
                       "replica_set_tombstone_reap_interval - tombstone_reap event (interval=%" PRId64 ") was %s\n",
be9751
diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c
be9751
index d64d4bf45..a969ef82f 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_replica_config.c
be9751
+++ b/ldap/servers/plugins/replication/repl5_replica_config.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -31,14 +31,17 @@
be9751
 #define CLEANALLRUVLEN 11
be9751
 #define REPLICA_RDN "cn=replica"
be9751
 
be9751
+#define CLEANALLRUV_MAX_WAIT 7200 /* 2 hours */
be9751
+#define CLEANALLRUV_SLEEP 5
be9751
+
be9751
 int slapi_log_urp = SLAPI_LOG_REPL;
be9751
 static ReplicaId cleaned_rids[CLEANRID_BUFSIZ] = {0};
be9751
 static ReplicaId pre_cleaned_rids[CLEANRID_BUFSIZ] = {0};
be9751
 static ReplicaId aborted_rids[CLEANRID_BUFSIZ] = {0};
be9751
 static PRLock *rid_lock = NULL;
be9751
 static PRLock *abort_rid_lock = NULL;
be9751
-static PRLock *notify_lock = NULL;
be9751
-static PRCondVar *notify_cvar = NULL;
be9751
+static pthread_mutex_t notify_lock;
be9751
+static pthread_cond_t notify_cvar;
be9751
 static PRLock *task_count_lock = NULL;
be9751
 static int32_t clean_task_count = 0;
be9751
 static int32_t abort_task_count = 0;
be9751
@@ -105,6 +108,9 @@ dont_allow_that(Slapi_PBlock *pb __attribute__((unused)),
be9751
 int
be9751
 replica_config_init()
be9751
 {
be9751
+    int rc = 0;
be9751
+    pthread_condattr_t condAttr;
be9751
+
be9751
     s_configLock = PR_NewLock();
be9751
 
be9751
     if (s_configLock == NULL) {
be9751
@@ -134,18 +140,31 @@ replica_config_init()
be9751
                       PR_GetError());
be9751
         return -1;
be9751
     }
be9751
-    if ((notify_lock = PR_NewLock()) == NULL) {
be9751
-        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
be9751
-                                                       "Failed to create notify lock; NSPR error - %d\n",
be9751
-                      PR_GetError());
be9751
+    if ((rc = pthread_mutex_init(&notify_lock, NULL)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "replica_config_init",
be9751
+                      "Failed to create notify lock: error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         return -1;
be9751
     }
be9751
-    if ((notify_cvar = PR_NewCondVar(notify_lock)) == NULL) {
be9751
-        slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "replica_config_init - "
be9751
-                                                       "Failed to create notify cond var; NSPR error - %d\n",
be9751
-                      PR_GetError());
be9751
+    if ((rc = pthread_condattr_init(&condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "replica_config_init",
be9751
+                      "Failed to create notify new condition attribute variable. error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         return -1;
be9751
     }
be9751
+    if ((rc = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "replica_config_init",
be9751
+                      "Cannot set condition attr clock. error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+        return -1;
be9751
+    }
be9751
+    if ((rc = pthread_cond_init(&notify_cvar, &condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "replica_config_init",
be9751
+                      "Failed to create new condition variable. error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+        return -1;
be9751
+    }
be9751
+    pthread_condattr_destroy(&condAttr);
be9751
 
be9751
     /* config DSE must be initialized before we get here */
be9751
     slapi_config_register_callback(SLAPI_OPERATION_ADD, DSE_FLAG_PREOP, CONFIG_BASE, LDAP_SCOPE_SUBTREE,
be9751
@@ -1674,9 +1693,13 @@ replica_cleanallruv_thread(void *arg)
be9751
          * to startup timing issues, we need to wait before grabbing the replica obj, as
be9751
          * the backends might not be online yet.
be9751
          */
be9751
-        PR_Lock(notify_lock);
be9751
-        PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(10));
be9751
-        PR_Unlock(notify_lock);
be9751
+        struct timespec current_time = {0};
be9751
+        clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+        current_time.tv_sec += 10;
be9751
+
be9751
+        pthread_mutex_lock(&notify_lock);
be9751
+        pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+        pthread_mutex_unlock(&notify_lock);
be9751
         data->replica = replica_get_replica_from_dn(data->sdn);
be9751
         if (data->replica == NULL) {
be9751
             cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Unable to retrieve repl object from dn(%s).", data->sdn);
be9751
@@ -1720,15 +1743,18 @@ replica_cleanallruv_thread(void *arg)
be9751
     ruv_obj = replica_get_ruv(data->replica);
be9751
     ruv = object_get_data(ruv_obj);
be9751
     while (data->maxcsn && !is_task_aborted(data->rid) && !is_cleaned_rid(data->rid) && !slapi_is_shutting_down()) {
be9751
+        struct timespec current_time = {0};
be9751
         if (csn_get_replicaid(data->maxcsn) == 0 ||
be9751
             ruv_covers_csn_cleanallruv(ruv, data->maxcsn) ||
be9751
             strcasecmp(data->force, "yes") == 0) {
be9751
             /* We are caught up, now we can clean the ruv's */
be9751
             break;
be9751
         }
be9751
-        PR_Lock(notify_lock);
be9751
-        PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(5));
be9751
-        PR_Unlock(notify_lock);
be9751
+        clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+        current_time.tv_sec += CLEANALLRUV_SLEEP;
be9751
+        pthread_mutex_lock(&notify_lock);
be9751
+        pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+        pthread_mutex_unlock(&notify_lock);
be9751
     }
be9751
     object_release(ruv_obj);
be9751
     /*
be9751
@@ -1796,18 +1822,20 @@ replica_cleanallruv_thread(void *arg)
be9751
         /*
be9751
          *  need to sleep between passes
be9751
          */
be9751
-        cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Not all replicas have received the "
be9751
-                                                                        "cleanallruv extended op, retrying in %d seconds",
be9751
+        cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
be9751
+                     "Not all replicas have received the cleanallruv extended op, retrying in %d seconds",
be9751
                      interval);
be9751
         if (!slapi_is_shutting_down()) {
be9751
-            PR_Lock(notify_lock);
be9751
-            PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
be9751
-            PR_Unlock(notify_lock);
be9751
+            struct timespec current_time = {0};
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
+            pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+            pthread_mutex_unlock(&notify_lock);
be9751
         }
be9751
-        if (interval < 14400) { /* 4 hour max */
be9751
-            interval = interval * 2;
be9751
-        } else {
be9751
-            interval = 14400;
be9751
+        interval *= 2;
be9751
+        if (interval >= CLEANALLRUV_MAX_WAIT) {
be9751
+            interval = CLEANALLRUV_MAX_WAIT;
be9751
         }
be9751
     }
be9751
     /*
be9751
@@ -1857,18 +1885,19 @@ replica_cleanallruv_thread(void *arg)
be9751
          * Need to sleep between passes unless we are shutting down
be9751
          */
be9751
         if (!slapi_is_shutting_down()) {
be9751
-            cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Replicas have not been cleaned yet, "
be9751
-                                                                            "retrying in %d seconds",
be9751
+            struct timespec current_time = {0};
be9751
+            cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
be9751
+                         "Replicas have not been cleaned yet, retrying in %d seconds",
be9751
                          interval);
be9751
-            PR_Lock(notify_lock);
be9751
-            PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
be9751
-            PR_Unlock(notify_lock);
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
+            pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+            pthread_mutex_unlock(&notify_lock);
be9751
         }
be9751
-
be9751
-        if (interval < 14400) { /* 4 hour max */
be9751
-            interval = interval * 2;
be9751
-        } else {
be9751
-            interval = 14400;
be9751
+        interval *= 2;
be9751
+        if (interval >= CLEANALLRUV_MAX_WAIT) {
be9751
+            interval = CLEANALLRUV_MAX_WAIT;
be9751
         }
be9751
     } /* while */
be9751
 
be9751
@@ -2081,15 +2110,17 @@ check_replicas_are_done_cleaning(cleanruv_data *data)
be9751
                      "Not all replicas finished cleaning, retrying in %d seconds",
be9751
                      interval);
be9751
         if (!slapi_is_shutting_down()) {
be9751
-            PR_Lock(notify_lock);
be9751
-            PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
be9751
-            PR_Unlock(notify_lock);
be9751
+            struct timespec current_time = {0};
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
+            pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
         }
be9751
 
be9751
-        if (interval < 14400) { /* 4 hour max */
be9751
-            interval = interval * 2;
be9751
-        } else {
be9751
-            interval = 14400;
be9751
+        interval *= 2;
be9751
+        if (interval >= CLEANALLRUV_MAX_WAIT) {
be9751
+            interval = CLEANALLRUV_MAX_WAIT;
be9751
         }
be9751
     }
be9751
     slapi_ch_free_string(&filter);
be9751
@@ -2190,14 +2221,16 @@ check_replicas_are_done_aborting(cleanruv_data *data)
be9751
         cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
be9751
                      "Not all replicas finished aborting, retrying in %d seconds", interval);
be9751
         if (!slapi_is_shutting_down()) {
be9751
-            PR_Lock(notify_lock);
be9751
-            PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
be9751
-            PR_Unlock(notify_lock);
be9751
+            struct timespec current_time = {0};
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
+            pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+            pthread_mutex_unlock(&notify_lock);
be9751
         }
be9751
-        if (interval < 14400) { /* 4 hour max */
be9751
-            interval = interval * 2;
be9751
-        } else {
be9751
-            interval = 14400;
be9751
+        interval *= 2;
be9751
+        if (interval >= CLEANALLRUV_MAX_WAIT) {
be9751
+            interval = CLEANALLRUV_MAX_WAIT;
be9751
         }
be9751
     }
be9751
     slapi_ch_free_string(&filter);
be9751
@@ -2248,14 +2281,16 @@ check_agmts_are_caught_up(cleanruv_data *data, char *maxcsn)
be9751
         cleanruv_log(data->task, data->rid, CLEANALLRUV_ID, SLAPI_LOG_NOTICE,
be9751
                      "Not all replicas caught up, retrying in %d seconds", interval);
be9751
         if (!slapi_is_shutting_down()) {
be9751
-            PR_Lock(notify_lock);
be9751
-            PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
be9751
-            PR_Unlock(notify_lock);
be9751
+            struct timespec current_time = {0};
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
+            pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+            pthread_mutex_unlock(&notify_lock);
be9751
         }
be9751
-        if (interval < 14400) { /* 4 hour max */
be9751
-            interval = interval * 2;
be9751
-        } else {
be9751
-            interval = 14400;
be9751
+        interval *= 2;
be9751
+        if (interval >= CLEANALLRUV_MAX_WAIT) {
be9751
+            interval = CLEANALLRUV_MAX_WAIT;
be9751
         }
be9751
     }
be9751
     slapi_ch_free_string(&rid_text);
be9751
@@ -2310,14 +2345,16 @@ check_agmts_are_alive(Replica *replica, ReplicaId rid, Slapi_Task *task)
be9751
                      interval);
be9751
 
be9751
         if (!slapi_is_shutting_down()) {
be9751
-            PR_Lock(notify_lock);
be9751
-            PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
be9751
-            PR_Unlock(notify_lock);
be9751
+            struct timespec current_time = {0};
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
+            pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+            pthread_mutex_unlock(&notify_lock);
be9751
         }
be9751
-        if (interval < 14400) { /* 4 hour max */
be9751
-            interval = interval * 2;
be9751
-        } else {
be9751
-            interval = 14400;
be9751
+        interval *= 2;
be9751
+        if (interval >= CLEANALLRUV_MAX_WAIT) {
be9751
+            interval = CLEANALLRUV_MAX_WAIT;
be9751
         }
be9751
     }
be9751
     if (is_task_aborted(rid)) {
be9751
@@ -3093,16 +3130,18 @@ replica_abort_task_thread(void *arg)
be9751
          *  Need to sleep between passes. unless we are shutting down
be9751
          */
be9751
         if (!slapi_is_shutting_down()) {
be9751
+            struct timespec current_time = {0};
be9751
             cleanruv_log(data->task, data->rid, ABORT_CLEANALLRUV_ID, SLAPI_LOG_NOTICE, "Retrying in %d seconds", interval);
be9751
-            PR_Lock(notify_lock);
be9751
-            PR_WaitCondVar(notify_cvar, PR_SecondsToInterval(interval));
be9751
-            PR_Unlock(notify_lock);
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_mutex_lock(&notify_lock);
be9751
+            pthread_cond_timedwait(&notify_cvar, &notify_lock, &current_time);
be9751
+            pthread_mutex_unlock(&notify_lock);
be9751
         }
be9751
 
be9751
-        if (interval < 14400) { /* 4 hour max */
be9751
-            interval = interval * 2;
be9751
-        } else {
be9751
-            interval = 14400;
be9751
+        interval *= 2;
be9751
+        if (interval >= CLEANALLRUV_MAX_WAIT) {
be9751
+            interval = CLEANALLRUV_MAX_WAIT;
be9751
         }
be9751
     } /* while */
be9751
 
be9751
@@ -3536,10 +3575,10 @@ check_and_set_abort_cleanruv_task_count(void)
be9751
 
be9751
     PR_Lock(task_count_lock);
be9751
     if (abort_task_count > CLEANRIDSIZ) {
be9751
-            rc = -1;
be9751
-        } else {
be9751
-            abort_task_count++;
be9751
-        }
be9751
+        rc = -1;
be9751
+    } else {
be9751
+        abort_task_count++;
be9751
+    }
be9751
     PR_Unlock(task_count_lock);
be9751
 
be9751
     return rc;
be9751
@@ -3551,11 +3590,9 @@ check_and_set_abort_cleanruv_task_count(void)
be9751
 void
be9751
 stop_ruv_cleaning()
be9751
 {
be9751
-    if (notify_lock) {
be9751
-        PR_Lock(notify_lock);
be9751
-        PR_NotifyCondVar(notify_cvar);
be9751
-        PR_Unlock(notify_lock);
be9751
-    }
be9751
+    pthread_mutex_lock(&notify_lock);
be9751
+    pthread_cond_signal(&notify_cvar);
be9751
+    pthread_mutex_unlock(&notify_lock);
be9751
 }
be9751
 
be9751
 /*
be9751
diff --git a/ldap/servers/plugins/replication/repl5_tot_protocol.c b/ldap/servers/plugins/replication/repl5_tot_protocol.c
be9751
index a25839f21..f67263c3e 100644
be9751
--- a/ldap/servers/plugins/replication/repl5_tot_protocol.c
be9751
+++ b/ldap/servers/plugins/replication/repl5_tot_protocol.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -45,7 +45,7 @@ typedef struct callback_data
be9751
     unsigned long num_entries;
be9751
     time_t sleep_on_busy;
be9751
     time_t last_busy;
be9751
-    PRLock *lock;                            /* Lock to protect access to this structure, the message id list and to force memory barriers */
be9751
+    pthread_mutex_t lock;                    /* Lock to protect access to this structure, the message id list and to force memory barriers */
be9751
     PRThread *result_tid;                    /* The async result thread */
be9751
     operation_id_list_item *message_id_list; /* List of IDs for outstanding operations */
be9751
     int abort;                               /* Flag used to tell the sending thread asyncronously that it should abort (because an error came up in a result) */
be9751
@@ -113,7 +113,7 @@ repl5_tot_result_threadmain(void *param)
be9751
     while (!finished) {
be9751
         int message_id = 0;
be9751
         time_t time_now = 0;
be9751
-        time_t start_time = slapi_current_utc_time();
be9751
+        time_t start_time = slapi_current_rel_time_t();
be9751
         int backoff_time = 1;
be9751
 
be9751
         /* Read the next result */
be9751
@@ -130,7 +130,7 @@ repl5_tot_result_threadmain(void *param)
be9751
                 /* We need to a) check that the 'real' timeout hasn't expired and
be9751
                  * b) implement a backoff sleep to avoid spinning */
be9751
                 /* Did the connection's timeout expire ? */
be9751
-                time_now = slapi_current_utc_time();
be9751
+                time_now = slapi_current_rel_time_t();
be9751
                 if (conn_get_timeout(conn) <= (time_now - start_time)) {
be9751
                     /* We timed out */
be9751
                     conres = CONN_TIMEOUT;
be9751
@@ -142,11 +142,11 @@ repl5_tot_result_threadmain(void *param)
be9751
                     backoff_time <<= 1;
be9751
                 }
be9751
                 /* Should we stop ? */
be9751
-                PR_Lock(cb->lock);
be9751
+                pthread_mutex_lock(&(cb->lock));
be9751
                 if (cb->stop_result_thread) {
be9751
                     finished = 1;
be9751
                 }
be9751
-                PR_Unlock(cb->lock);
be9751
+                pthread_mutex_unlock(&(cb->lock));
be9751
             } else {
be9751
                 /* Something other than a timeout, so we exit the loop */
be9751
                 break;
be9751
@@ -164,21 +164,21 @@ repl5_tot_result_threadmain(void *param)
be9751
         /* Was the result itself an error ? */
be9751
         if (0 != conres) {
be9751
             /* If so then we need to take steps to abort the update process */
be9751
-            PR_Lock(cb->lock);
be9751
+            pthread_mutex_lock(&(cb->lock));
be9751
             cb->abort = 1;
be9751
             if (conres == CONN_NOT_CONNECTED) {
be9751
                 cb->rc = LDAP_CONNECT_ERROR;
be9751
             }
be9751
-            PR_Unlock(cb->lock);
be9751
+            pthread_mutex_unlock(&(cb->lock));
be9751
         }
be9751
         /* Should we stop ? */
be9751
-        PR_Lock(cb->lock);
be9751
+        pthread_mutex_lock(&(cb->lock));
be9751
         /* if the connection is not connected, then we cannot read any more
be9751
            results - we are finished */
be9751
         if (cb->stop_result_thread || (conres == CONN_NOT_CONNECTED)) {
be9751
             finished = 1;
be9751
         }
be9751
-        PR_Unlock(cb->lock);
be9751
+        pthread_mutex_unlock(&(cb->lock));
be9751
     }
be9751
 }
be9751
 
be9751
@@ -209,9 +209,9 @@ repl5_tot_destroy_async_result_thread(callback_data *cb_data)
be9751
     int retval = 0;
be9751
     PRThread *tid = cb_data->result_tid;
be9751
     if (tid) {
be9751
-        PR_Lock(cb_data->lock);
be9751
+        pthread_mutex_lock(&(cb_data->lock));
be9751
         cb_data->stop_result_thread = 1;
be9751
-        PR_Unlock(cb_data->lock);
be9751
+        pthread_mutex_unlock(&(cb_data->lock));
be9751
         (void)PR_JoinThread(tid);
be9751
     }
be9751
     return retval;
be9751
@@ -248,7 +248,7 @@ repl5_tot_waitfor_async_results(callback_data *cb_data)
be9751
     /* Keep pulling results off the LDAP connection until we catch up to the last message id stored in the rd */
be9751
     while (!done) {
be9751
         /* Lock the structure to force memory barrier */
be9751
-        PR_Lock(cb_data->lock);
be9751
+        pthread_mutex_lock(&(cb_data->lock));
be9751
         /* Are we caught up ? */
be9751
         slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name,
be9751
                       "repl5_tot_waitfor_async_results - %d %d\n",
be9751
@@ -260,7 +260,7 @@ repl5_tot_waitfor_async_results(callback_data *cb_data)
be9751
         if (cb_data->abort && LOST_CONN_ERR(cb_data->rc)) {
be9751
             done = 1; /* no connection == no more results */
be9751
         }
be9751
-        PR_Unlock(cb_data->lock);
be9751
+        pthread_mutex_unlock(&(cb_data->lock));
be9751
         /* If not then sleep a bit */
be9751
         DS_Sleep(PR_SecondsToInterval(1));
be9751
         loops++;
be9751
@@ -482,9 +482,9 @@ retry:
be9751
         cb_data.rc = 0;
be9751
         cb_data.num_entries = 1UL;
be9751
         cb_data.sleep_on_busy = 0UL;
be9751
-        cb_data.last_busy = slapi_current_utc_time();
be9751
+        cb_data.last_busy = slapi_current_rel_time_t();
be9751
         cb_data.flowcontrol_detection = 0;
be9751
-        cb_data.lock = PR_NewLock();
be9751
+        pthread_mutex_init(&(cb_data.lock), NULL);
be9751
 
be9751
         /* This allows during perform_operation to check the callback data
be9751
          * especially to do flow contol on delta send msgid / recv msgid
be9751
@@ -541,9 +541,9 @@ retry:
be9751
         cb_data.rc = 0;
be9751
         cb_data.num_entries = 0UL;
be9751
         cb_data.sleep_on_busy = 0UL;
be9751
-        cb_data.last_busy = slapi_current_utc_time();
be9751
+        cb_data.last_busy = slapi_current_rel_time_t();
be9751
         cb_data.flowcontrol_detection = 0;
be9751
-        cb_data.lock = PR_NewLock();
be9751
+        pthread_mutex_init(&(cb_data.lock), NULL);
be9751
 
be9751
         /* This allows during perform_operation to check the callback data
be9751
          * especially to do flow contol on delta send msgid / recv msgid
be9751
@@ -633,9 +633,7 @@ done:
be9751
                       type_nsds5ReplicaFlowControlWindow);
be9751
     }
be9751
     conn_set_tot_update_cb(prp->conn, NULL);
be9751
-    if (cb_data.lock) {
be9751
-        PR_DestroyLock(cb_data.lock);
be9751
-    }
be9751
+    pthread_mutex_destroy(&(cb_data.lock));
be9751
     prp->stopped = 1;
be9751
 }
be9751
 
be9751
@@ -700,7 +698,9 @@ Private_Repl_Protocol *
be9751
 Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
be9751
 {
be9751
     repl5_tot_private *rip = NULL;
be9751
-    Private_Repl_Protocol *prp = (Private_Repl_Protocol *)slapi_ch_malloc(sizeof(Private_Repl_Protocol));
be9751
+    pthread_condattr_t cattr;
be9751
+    Private_Repl_Protocol *prp = (Private_Repl_Protocol *)slapi_ch_calloc(1, sizeof(Private_Repl_Protocol));
be9751
+
be9751
     prp->delete = repl5_tot_delete;
be9751
     prp->run = repl5_tot_run;
be9751
     prp->stop = repl5_tot_stop;
be9751
@@ -710,12 +710,19 @@ Repl_5_Tot_Protocol_new(Repl_Protocol *rp)
be9751
     prp->notify_window_opened = repl5_tot_noop;
be9751
     prp->notify_window_closed = repl5_tot_noop;
be9751
     prp->update_now = repl5_tot_noop;
be9751
-    if ((prp->lock = PR_NewLock()) == NULL) {
be9751
+    if (pthread_mutex_init(&(prp->lock), NULL) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    if (pthread_condattr_init(&cattr) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    if (pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC) != 0) {
be9751
         goto loser;
be9751
     }
be9751
-    if ((prp->cvar = PR_NewCondVar(prp->lock)) == NULL) {
be9751
+    if (pthread_cond_init(&(prp->cvar), &cattr) != 0) {
be9751
         goto loser;
be9751
     }
be9751
+    pthread_condattr_destroy(&cattr);
be9751
     prp->stopped = 1;
be9751
     prp->terminate = 0;
be9751
     prp->eventbits = 0;
be9751
@@ -744,13 +751,11 @@ repl5_tot_delete(Private_Repl_Protocol **prpp)
be9751
         (*prpp)->stop(*prpp);
be9751
     }
be9751
     /* Then, delete all resources used by the protocol */
be9751
-    if ((*prpp)->lock) {
be9751
-        PR_DestroyLock((*prpp)->lock);
be9751
-        (*prpp)->lock = NULL;
be9751
+    if (&((*prpp)->lock)) {
be9751
+        pthread_mutex_destroy(&((*prpp)->lock));
be9751
     }
be9751
-    if ((*prpp)->cvar) {
be9751
-        PR_DestroyCondVar((*prpp)->cvar);
be9751
-        (*prpp)->cvar = NULL;
be9751
+    if (&((*prpp)->cvar)) {
be9751
+        pthread_cond_destroy(&(*prpp)->cvar);
be9751
     }
be9751
     slapi_ch_free((void **)&(*prpp)->private);
be9751
     slapi_ch_free((void **)prpp);
be9751
@@ -824,9 +829,9 @@ send_entry(Slapi_Entry *e, void *cb_data)
be9751
 
be9751
     /* see if the result reader thread encountered
be9751
        a fatal error */
be9751
-    PR_Lock(((callback_data *)cb_data)->lock);
be9751
+    pthread_mutex_lock((&((callback_data *)cb_data)->lock));
be9751
     rc = ((callback_data *)cb_data)->abort;
be9751
-    PR_Unlock(((callback_data *)cb_data)->lock);
be9751
+    pthread_mutex_unlock((&((callback_data *)cb_data)->lock));
be9751
     if (rc) {
be9751
         conn_disconnect(prp->conn);
be9751
         ((callback_data *)cb_data)->rc = -1;
be9751
@@ -889,7 +894,7 @@ send_entry(Slapi_Entry *e, void *cb_data)
be9751
         }
be9751
 
be9751
         if (rc == CONN_BUSY) {
be9751
-            time_t now = slapi_current_utc_time();
be9751
+            time_t now = slapi_current_rel_time_t();
be9751
             if ((now - *last_busyp) < (*sleep_on_busyp + 10)) {
be9751
                 *sleep_on_busyp += 5;
be9751
             } else {
be9751
diff --git a/ldap/servers/plugins/replication/repl_extop.c b/ldap/servers/plugins/replication/repl_extop.c
be9751
index af486f730..ef2025dd9 100644
be9751
--- a/ldap/servers/plugins/replication/repl_extop.c
be9751
+++ b/ldap/servers/plugins/replication/repl_extop.c
be9751
@@ -1176,7 +1176,7 @@ multimaster_extop_EndNSDS50ReplicationRequest(Slapi_PBlock *pb)
be9751
                     /* now that the changelog is open and started, we can alos cretae the
be9751
                      * keep alive entry without risk that db and cl will not match
be9751
                      */
be9751
-                    replica_subentry_check(replica_get_root(r), replica_get_rid(r));
be9751
+                    replica_subentry_check((Slapi_DN *)replica_get_root(r), replica_get_rid(r));
be9751
                 }
be9751
 
be9751
                 /* ONREPL code that dealt with new RUV, etc was moved into the code
be9751
@@ -1474,7 +1474,7 @@ multimaster_extop_cleanruv(Slapi_PBlock *pb)
be9751
          *  Launch the cleanruv monitoring thread.  Once all the replicas are cleaned it will release the rid
be9751
          */
be9751
 
be9751
-        cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Launching cleanAllRUV thread...\n");
be9751
+        cleanruv_log(NULL, rid, CLEANALLRUV_ID, SLAPI_LOG_ERR, "Launching cleanAllRUV thread...");
be9751
         data = (cleanruv_data *)slapi_ch_calloc(1, sizeof(cleanruv_data));
be9751
         if (data == NULL) {
be9751
             slapi_log_err(SLAPI_LOG_ERR, repl_plugin_name, "multimaster_extop_cleanruv - CleanAllRUV Task - Failed to allocate "
be9751
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
be9751
index 011b328bf..ce0662544 100644
be9751
--- a/ldap/servers/plugins/replication/windows_connection.c
be9751
+++ b/ldap/servers/plugins/replication/windows_connection.c
be9751
@@ -1121,7 +1121,7 @@ windows_conn_start_linger(Repl_Connection *conn)
be9751
                       agmt_get_long_name(conn->agmt));
be9751
         return;
be9751
     }
be9751
-    now = slapi_current_utc_time();
be9751
+    now = slapi_current_rel_time_t();
be9751
     PR_Lock(conn->lock);
be9751
     if (conn->linger_active) {
be9751
         slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
be9751
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
be9751
index 1c07534e3..3d548e5ed 100644
be9751
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
be9751
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -48,7 +48,7 @@ typedef struct windows_inc_private
be9751
     char *ruv; /* RUV on remote replica (use diff type for this? - ggood */
be9751
     Backoff_Timer *backoff;
be9751
     Repl_Protocol *rp;
be9751
-    PRLock *lock;
be9751
+    pthread_mutex_t *lock;
be9751
     PRUint32 eventbits;
be9751
 } windows_inc_private;
be9751
 
be9751
@@ -96,7 +96,7 @@ typedef struct windows_inc_private
be9751
  * don't see any updates for a period equal to this interval,
be9751
  * we go ahead and start a replication session, just to be safe
be9751
  */
be9751
-#define MAX_WAIT_BETWEEN_SESSIONS PR_SecondsToInterval(60 * 5) /* 5 minutes */
be9751
+#define MAX_WAIT_BETWEEN_SESSIONS 300 /* 5 minutes */
be9751
 /*
be9751
  * tests if the protocol has been shutdown and we need to quit
be9751
  * event_occurred resets the bits in the bit flag, so whoever tests for shutdown
be9751
@@ -108,7 +108,7 @@ typedef struct windows_inc_private
be9751
 /* Forward declarations */
be9751
 static PRUint32 event_occurred(Private_Repl_Protocol *prp, PRUint32 event);
be9751
 static void reset_events(Private_Repl_Protocol *prp);
be9751
-static void protocol_sleep(Private_Repl_Protocol *prp, PRIntervalTime duration);
be9751
+static void protocol_sleep(Private_Repl_Protocol *prp, int32_t duration);
be9751
 static int send_updates(Private_Repl_Protocol *prp, RUV *ruv, PRUint32 *num_changes_sent, int do_send);
be9751
 static void windows_inc_backoff_expired(time_t timer_fire_time, void *arg);
be9751
 static int windows_examine_update_vector(Private_Repl_Protocol *prp, RUV *ruv);
be9751
@@ -143,13 +143,11 @@ windows_inc_delete(Private_Repl_Protocol **prpp)
be9751
         (*prpp)->stopped = 1;
be9751
         (*prpp)->stop(*prpp);
be9751
     }
be9751
-    if ((*prpp)->lock) {
be9751
-        PR_DestroyLock((*prpp)->lock);
be9751
-        (*prpp)->lock = NULL;
be9751
+    if (&((*prpp)->lock)) {
be9751
+        pthread_mutex_destroy(&((*prpp)->lock));
be9751
     }
be9751
-    if ((*prpp)->cvar) {
be9751
-        PR_DestroyCondVar((*prpp)->cvar);
be9751
-        (*prpp)->cvar = NULL;
be9751
+    if (&((*prpp)->cvar)) {
be9751
+        pthread_cond_destroy(&(*prpp)->cvar);
be9751
     }
be9751
     slapi_ch_free((void **)&(*prpp)->private);
be9751
     slapi_ch_free((void **)prpp);
be9751
@@ -360,7 +358,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
             } else if (event_occurred(prp, EVENT_TRIGGERING_CRITERIA_MET)) /* change available */
be9751
             {
be9751
                 /* just ignore it and go to sleep */
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             } else if ((e1 = event_occurred(prp, EVENT_WINDOW_CLOSED)) ||
be9751
                        event_occurred(prp, EVENT_BACKOFF_EXPIRED)) {
be9751
                 /* this events - should not occur - log a warning and go to sleep */
be9751
@@ -370,18 +368,18 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
                               agmt_get_long_name(prp->agmt),
be9751
                               e1 ? event2name(EVENT_WINDOW_CLOSED) : event2name(EVENT_BACKOFF_EXPIRED),
be9751
                               state2name(current_state));
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             } else if (event_occurred(prp, EVENT_RUN_DIRSYNC)) /* periodic_dirsync */
be9751
             {
be9751
                 /* just ignore it and go to sleep */
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             } else {
be9751
                 /* wait until window opens or an event occurs */
be9751
                 slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
be9751
                               "windows_inc_run - %s: "
be9751
                               "Waiting for update window to open\n",
be9751
                               agmt_get_long_name(prp->agmt));
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             }
be9751
             break;
be9751
 
be9751
@@ -536,7 +534,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
                 }
be9751
                 next_state = STATE_BACKOFF;
be9751
                 backoff_reset(prp_priv->backoff, windows_inc_backoff_expired, (void *)prp);
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
                 use_busy_backoff_timer = PR_FALSE;
be9751
             }
be9751
             break;
be9751
@@ -605,7 +603,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
                                   agmt_get_long_name(prp->agmt),
be9751
                                   next_fire_time - now);
be9751
 
be9751
-                    protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                    protocol_sleep(prp, 0);
be9751
                 } else {
be9751
                     /* Destroy the backoff timer, since we won't need it anymore */
be9751
                     backoff_delete(&prp_priv->backoff);
be9751
@@ -624,7 +622,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
                     next_state = STATE_READY_TO_ACQUIRE;
be9751
                 } else {
be9751
                     /* ignore changes and go to sleep */
be9751
-                    protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                    protocol_sleep(prp, 0);
be9751
                 }
be9751
             } else if (event_occurred(prp, EVENT_WINDOW_OPENED)) {
be9751
                 /* this should never happen - log an error and go to sleep */
be9751
@@ -632,7 +630,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
                                                                        "event %s should not occur in state %s; going to sleep\n",
be9751
                               agmt_get_long_name(prp->agmt),
be9751
                               event2name(EVENT_WINDOW_OPENED), state2name(current_state));
be9751
-                protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+                protocol_sleep(prp, 0);
be9751
             }
be9751
             break;
be9751
         case STATE_SENDING_UPDATES:
be9751
@@ -856,7 +854,7 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
                 reset_events(prp);
be9751
             }
be9751
 
be9751
-            protocol_sleep(prp, PR_INTERVAL_NO_TIMEOUT);
be9751
+            protocol_sleep(prp, 0);
be9751
             break;
be9751
 
be9751
         case STATE_STOP_NORMAL_TERMINATION:
be9751
@@ -891,21 +889,29 @@ windows_inc_run(Private_Repl_Protocol *prp)
be9751
  * Go to sleep until awakened.
be9751
  */
be9751
 static void
be9751
-protocol_sleep(Private_Repl_Protocol *prp, PRIntervalTime duration)
be9751
+protocol_sleep(Private_Repl_Protocol *prp, int32_t duration)
be9751
 {
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> protocol_sleep\n");
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     /* we should not go to sleep if there are events available to be processed.
be9751
        Otherwise, we can miss the event that suppose to wake us up */
be9751
-    if (prp->eventbits == 0)
be9751
-        PR_WaitCondVar(prp->cvar, duration);
be9751
-    else {
be9751
+    if (prp->eventbits == 0) {
be9751
+        if (duration > 0) {
be9751
+            struct timespec current_time = {0};
be9751
+            /* get the current monotonic time and add our interval */
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += duration;
be9751
+            pthread_cond_timedwait(&(prp->cvar), &(prp->lock), &current_time);
be9751
+        } else {
be9751
+            pthread_cond_wait(&(prp->cvar), &(prp->lock));
be9751
+        }
be9751
+    } else {
be9751
         slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
be9751
                       "protocol_sleep - %s: Can't go to sleep: event bits - %x\n",
be9751
                       agmt_get_long_name(prp->agmt), prp->eventbits);
be9751
     }
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= protocol_sleep\n");
be9751
 }
be9751
 
be9751
@@ -921,10 +927,10 @@ event_notify(Private_Repl_Protocol *prp, PRUint32 event)
be9751
 {
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> event_notify\n");
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     prp->eventbits |= event;
be9751
-    PR_NotifyCondVar(prp->cvar);
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_cond_signal(&(prp->cvar));
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= event_notify\n");
be9751
 }
be9751
 
be9751
@@ -941,10 +947,10 @@ event_occurred(Private_Repl_Protocol *prp, PRUint32 event)
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> event_occurred\n");
be9751
 
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     return_value = (prp->eventbits & event);
be9751
     prp->eventbits &= ~event; /* Clear event */
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= event_occurred\n");
be9751
     return return_value;
be9751
 }
be9751
@@ -954,9 +960,9 @@ reset_events(Private_Repl_Protocol *prp)
be9751
 {
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> reset_events\n");
be9751
     PR_ASSERT(NULL != prp);
be9751
-    PR_Lock(prp->lock);
be9751
+    pthread_mutex_lock(&(prp->lock));
be9751
     prp->eventbits = 0;
be9751
-    PR_Unlock(prp->lock);
be9751
+    pthread_mutex_unlock(&(prp->lock));
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= reset_events\n");
be9751
 }
be9751
 
be9751
@@ -1416,6 +1422,7 @@ Windows_Inc_Protocol_new(Repl_Protocol *rp)
be9751
 {
be9751
     windows_inc_private *rip = NULL;
be9751
     Private_Repl_Protocol *prp = (Private_Repl_Protocol *)slapi_ch_calloc(1, sizeof(Private_Repl_Protocol));
be9751
+    pthread_condattr_t cattr;
be9751
 
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> Windows_Inc_Protocol_new\n");
be9751
 
be9751
@@ -1429,12 +1436,19 @@ Windows_Inc_Protocol_new(Repl_Protocol *rp)
be9751
     prp->notify_window_closed = windows_inc_notify_window_closed;
be9751
     prp->update_now = windows_inc_update_now;
be9751
     prp->replica = prot_get_replica(rp);
be9751
-    if ((prp->lock = PR_NewLock()) == NULL) {
be9751
+    if (pthread_mutex_init(&(prp->lock), NULL) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    if (pthread_condattr_init(&cattr) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    if (pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC) != 0) {
be9751
         goto loser;
be9751
     }
be9751
-    if ((prp->cvar = PR_NewCondVar(prp->lock)) == NULL) {
be9751
+    if (pthread_cond_init(&(prp->cvar), &cattr) != 0) {
be9751
         goto loser;
be9751
     }
be9751
+    pthread_condattr_destroy(&cattr); /* no longer needed */
be9751
     prp->stopped = 0;
be9751
     prp->terminate = 0;
be9751
     prp->eventbits = 0;
be9751
diff --git a/ldap/servers/plugins/replication/windows_tot_protocol.c b/ldap/servers/plugins/replication/windows_tot_protocol.c
be9751
index da244c166..f67e4dbd2 100644
be9751
--- a/ldap/servers/plugins/replication/windows_tot_protocol.c
be9751
+++ b/ldap/servers/plugins/replication/windows_tot_protocol.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -326,6 +326,7 @@ Windows_Tot_Protocol_new(Repl_Protocol *rp)
be9751
 {
be9751
     windows_tot_private *rip = NULL;
be9751
     Private_Repl_Protocol *prp = (Private_Repl_Protocol *)slapi_ch_calloc(1, sizeof(Private_Repl_Protocol));
be9751
+    pthread_condattr_t cattr;
be9751
 
be9751
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> Windows_Tot_Protocol_new\n");
be9751
 
be9751
@@ -339,12 +340,19 @@ Windows_Tot_Protocol_new(Repl_Protocol *rp)
be9751
     prp->notify_window_closed = windows_tot_noop;
be9751
     prp->replica = prot_get_replica(rp);
be9751
     prp->update_now = windows_tot_noop;
be9751
-    if ((prp->lock = PR_NewLock()) == NULL) {
be9751
+    if (pthread_mutex_init(&(prp->lock), NULL) != 0) {
be9751
         goto loser;
be9751
     }
be9751
-    if ((prp->cvar = PR_NewCondVar(prp->lock)) == NULL) {
be9751
+    if (pthread_condattr_init(&cattr) != 0) {
be9751
         goto loser;
be9751
     }
be9751
+    if (pthread_condattr_setclock(&cattr, CLOCK_MONOTONIC) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    if (pthread_cond_init(&(prp->cvar), &cattr) != 0) {
be9751
+        goto loser;
be9751
+    }
be9751
+    pthread_condattr_destroy(&cattr);
be9751
     prp->stopped = 1;
be9751
     prp->terminate = 0;
be9751
     prp->eventbits = 0;
be9751
@@ -373,13 +381,11 @@ windows_tot_delete(Private_Repl_Protocol **prpp)
be9751
         (*prpp)->stop(*prpp);
be9751
     }
be9751
     /* Then, delete all resources used by the protocol */
be9751
-    if ((*prpp)->lock) {
be9751
-        PR_DestroyLock((*prpp)->lock);
be9751
-        (*prpp)->lock = NULL;
be9751
+    if (&((*prpp)->lock)) {
be9751
+        pthread_mutex_destroy(&((*prpp)->lock));
be9751
     }
be9751
-    if ((*prpp)->cvar) {
be9751
-        PR_DestroyCondVar((*prpp)->cvar);
be9751
-        (*prpp)->cvar = NULL;
be9751
+    if (&((*prpp)->cvar)) {
be9751
+        pthread_cond_destroy(&(*prpp)->cvar);
be9751
     }
be9751
     slapi_ch_free((void **)&(*prpp)->private);
be9751
     slapi_ch_free((void **)prpp);
be9751
diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
be9751
index d031dc3f8..a3e16c4e1 100644
be9751
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
be9751
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
be9751
@@ -241,7 +241,7 @@ trim_changelog(void)
be9751
     int me, lt;
be9751
 
be9751
 
be9751
-    now = slapi_current_utc_time();
be9751
+    now = slapi_current_rel_time_t();
be9751
 
be9751
     PR_Lock(ts.ts_s_trim_mutex);
be9751
     me = ts.ts_c_max_age;
be9751
diff --git a/ldap/servers/plugins/roles/roles_cache.c b/ldap/servers/plugins/roles/roles_cache.c
be9751
index de99ba233..3d076a4cb 100644
be9751
--- a/ldap/servers/plugins/roles/roles_cache.c
be9751
+++ b/ldap/servers/plugins/roles/roles_cache.c
be9751
@@ -343,7 +343,7 @@ roles_cache_create_suffix(Slapi_DN *sdn)
be9751
 
be9751
     slapi_lock_mutex(new_suffix->create_lock);
be9751
     if (new_suffix->is_ready != 1) {
be9751
-        slapi_wait_condvar(new_suffix->suffix_created, NULL);
be9751
+        slapi_wait_condvar_pt(new_suffix->suffix_created, new_suffix->create_lock, NULL);
be9751
     }
be9751
     slapi_unlock_mutex(new_suffix->create_lock);
be9751
 
be9751
@@ -384,7 +384,7 @@ roles_cache_wait_on_change(void *arg)
be9751
             test roles_def->keeprunning before
be9751
             going to sleep.
be9751
         */
be9751
-        slapi_wait_condvar(roles_def->something_changed, NULL);
be9751
+        slapi_wait_condvar_pt(roles_def->something_changed, roles_def->change_lock, NULL);
be9751
 
be9751
         slapi_log_err(SLAPI_LOG_PLUGIN, ROLES_PLUGIN_SUBSYSTEM, "roles_cache_wait_on_change - notified\n");
be9751
 
be9751
diff --git a/ldap/servers/plugins/sync/sync.h b/ldap/servers/plugins/sync/sync.h
be9751
index 51d0da6e0..7241fddbf 100644
be9751
--- a/ldap/servers/plugins/sync/sync.h
be9751
+++ b/ldap/servers/plugins/sync/sync.h
be9751
@@ -201,8 +201,8 @@ typedef struct sync_request_list
be9751
 {
be9751
     Slapi_RWLock *sync_req_rwlock; /* R/W lock struct to serialize access */
be9751
     SyncRequest *sync_req_head;    /* Head of list */
be9751
-    PRLock *sync_req_cvarlock;     /* Lock for cvar */
be9751
-    PRCondVar *sync_req_cvar;      /* ps threads sleep on this */
be9751
+    pthread_mutex_t sync_req_cvarlock;    /* Lock for cvar */
be9751
+    pthread_cond_t sync_req_cvar;         /* ps threads sleep on this */
be9751
     int sync_req_max_persist;
be9751
     int sync_req_cur_persist;
be9751
 } SyncRequestList;
be9751
diff --git a/ldap/servers/plugins/sync/sync_persist.c b/ldap/servers/plugins/sync/sync_persist.c
be9751
index 598c6868d..d13f142b0 100644
be9751
--- a/ldap/servers/plugins/sync/sync_persist.c
be9751
+++ b/ldap/servers/plugins/sync/sync_persist.c
be9751
@@ -463,19 +463,40 @@ int
be9751
 sync_persist_initialize(int argc, char **argv)
be9751
 {
be9751
     if (!SYNC_IS_INITIALIZED()) {
be9751
+        pthread_condattr_t sync_req_condAttr; /* cond var attribute */
be9751
+        int rc = 0;
be9751
+
be9751
         sync_request_list = (SyncRequestList *)slapi_ch_calloc(1, sizeof(SyncRequestList));
be9751
         if ((sync_request_list->sync_req_rwlock = slapi_new_rwlock()) == NULL) {
be9751
             slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM, "sync_persist_initialize - Cannot initialize lock structure(1).\n");
be9751
             return (-1);
be9751
         }
be9751
-        if ((sync_request_list->sync_req_cvarlock = PR_NewLock()) == NULL) {
be9751
-            slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM, "sync_persist_initialize - Cannot initialize lock structure(2).\n");
be9751
+        if (pthread_mutex_init(&(sync_request_list->sync_req_cvarlock), NULL) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "sync_persist_initialize",
be9751
+                          "Failed to create lock: error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            return (-1);
be9751
+        }
be9751
+        if ((rc = pthread_condattr_init(&sync_req_condAttr)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "sync_persist_initialize",
be9751
+                          "Failed to create new condition attribute variable. error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
             return (-1);
be9751
         }
be9751
-        if ((sync_request_list->sync_req_cvar = PR_NewCondVar(sync_request_list->sync_req_cvarlock)) == NULL) {
be9751
-            slapi_log_err(SLAPI_LOG_ERR, SYNC_PLUGIN_SUBSYSTEM, "sync_persist_initialize - Cannot initialize condition variable.\n");
be9751
+        if ((rc = pthread_condattr_setclock(&sync_req_condAttr, CLOCK_MONOTONIC)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "sync_persist_initialize",
be9751
+                          "Cannot set condition attr clock. error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
             return (-1);
be9751
         }
be9751
+        if ((rc = pthread_cond_init(&(sync_request_list->sync_req_cvar), &sync_req_condAttr)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "sync_persist_initialize",
be9751
+                          "Failed to create new condition variable. error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            return (-1);
be9751
+        }
be9751
+        pthread_condattr_destroy(&sync_req_condAttr); /* no longer needed */
be9751
+
be9751
         sync_request_list->sync_req_head = NULL;
be9751
         sync_request_list->sync_req_cur_persist = 0;
be9751
         sync_request_list->sync_req_max_persist = SYNC_MAX_CONCURRENT;
be9751
@@ -617,8 +638,8 @@ sync_persist_terminate_all()
be9751
         }
be9751
 
be9751
         slapi_destroy_rwlock(sync_request_list->sync_req_rwlock);
be9751
-        PR_DestroyLock(sync_request_list->sync_req_cvarlock);
be9751
-        PR_DestroyCondVar(sync_request_list->sync_req_cvar);
be9751
+        pthread_mutex_destroy(&(sync_request_list->sync_req_cvarlock));
be9751
+		pthread_cond_destroy(&(sync_request_list->sync_req_cvar));
be9751
 
be9751
         /* it frees the structures, just in case it remained connected sync_repl client */
be9751
         for (req = sync_request_list->sync_req_head; NULL != req; req = next) {
be9751
@@ -725,9 +746,9 @@ static void
be9751
 sync_request_wakeup_all(void)
be9751
 {
be9751
     if (SYNC_IS_INITIALIZED()) {
be9751
-        PR_Lock(sync_request_list->sync_req_cvarlock);
be9751
-        PR_NotifyAllCondVar(sync_request_list->sync_req_cvar);
be9751
-        PR_Unlock(sync_request_list->sync_req_cvarlock);
be9751
+        pthread_mutex_lock(&(sync_request_list->sync_req_cvarlock));
be9751
+        pthread_cond_broadcast(&(sync_request_list->sync_req_cvar));
be9751
+        pthread_mutex_unlock(&(sync_request_list->sync_req_cvarlock));
be9751
     }
be9751
 }
be9751
 
be9751
@@ -817,7 +838,7 @@ sync_send_results(void *arg)
be9751
         goto done;
be9751
     }
be9751
 
be9751
-    PR_Lock(sync_request_list->sync_req_cvarlock);
be9751
+    pthread_mutex_lock(&(sync_request_list->sync_req_cvarlock));
be9751
 
be9751
     while ((conn_acq_flag == 0) && !req->req_complete && !plugin_closing) {
be9751
         /* Check for an abandoned operation */
be9751
@@ -833,7 +854,12 @@ sync_send_results(void *arg)
be9751
              * connection code. Wake up every second to check if thread
be9751
              * should terminate.
be9751
              */
be9751
-            PR_WaitCondVar(sync_request_list->sync_req_cvar, PR_SecondsToInterval(1));
be9751
+            struct timespec current_time = {0};
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += 1;
be9751
+            pthread_cond_timedwait(&(sync_request_list->sync_req_cvar),
be9751
+                                   &(sync_request_list->sync_req_cvarlock),
be9751
+                                   &current_time);
be9751
         } else {
be9751
             /* dequeue the item */
be9751
             int attrsonly;
be9751
@@ -864,7 +890,7 @@ sync_send_results(void *arg)
be9751
              * Send the result.  Since send_ldap_search_entry can block for
be9751
              * up to 30 minutes, we relinquish all locks before calling it.
be9751
              */
be9751
-            PR_Unlock(sync_request_list->sync_req_cvarlock);
be9751
+            pthread_mutex_unlock(&(sync_request_list->sync_req_cvarlock));
be9751
 
be9751
             /*
be9751
              * The entry is in the right scope and matches the filter
be9751
@@ -910,13 +936,13 @@ sync_send_results(void *arg)
be9751
                 ldap_controls_free(ectrls);
be9751
                 slapi_ch_array_free(noattrs);
be9751
             }
be9751
-            PR_Lock(sync_request_list->sync_req_cvarlock);
be9751
+            pthread_mutex_lock(&(sync_request_list->sync_req_cvarlock));
be9751
 
be9751
             /* Deallocate our wrapper for this entry */
be9751
             sync_node_free(&qnode);
be9751
         }
be9751
     }
be9751
-    PR_Unlock(sync_request_list->sync_req_cvarlock);
be9751
+    pthread_mutex_unlock(&(sync_request_list->sync_req_cvarlock));
be9751
 
be9751
     /* indicate the end of search */
be9751
     sync_release_connection(req->req_pblock, conn, op, conn_acq_flag == 0);
be9751
diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c
be9751
index 1e4830e99..ba783ee59 100644
be9751
--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c
be9751
+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import.c
be9751
@@ -1,5 +1,5 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
- * Copyright (C) 2019 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -1429,21 +1429,22 @@ import_free_job(ImportJob *job)
be9751
          * To avoid freeing fifo queue under bulk_import_queue use
be9751
          * job lock to synchronize
be9751
          */
be9751
-        if (job->wire_lock)
be9751
-            PR_Lock(job->wire_lock);
be9751
+        if (&job->wire_lock) {
be9751
+            pthread_mutex_lock(&job->wire_lock);
be9751
+        }
be9751
 
be9751
         import_fifo_destroy(job);
be9751
 
be9751
-        if (job->wire_lock)
be9751
-            PR_Unlock(job->wire_lock);
be9751
+        if (&job->wire_lock) {
be9751
+            pthread_mutex_unlock(&job->wire_lock);
be9751
+        }
be9751
     }
be9751
 
be9751
-    if (NULL != job->uuid_namespace)
be9751
+    if (NULL != job->uuid_namespace) {
be9751
         slapi_ch_free((void **)&job->uuid_namespace);
be9751
-    if (job->wire_lock)
be9751
-        PR_DestroyLock(job->wire_lock);
be9751
-    if (job->wire_cv)
be9751
-        PR_DestroyCondVar(job->wire_cv);
be9751
+    }
be9751
+    pthread_mutex_destroy(&job->wire_lock);
be9751
+    pthread_cond_destroy(&job->wire_cv);
be9751
     slapi_ch_free((void **)&job->task_status);
be9751
 }
be9751
 
be9751
@@ -1777,7 +1778,7 @@ import_monitor_threads(ImportJob *job, int *status)
be9751
         goto error_abort;
be9751
     }
be9751
 
be9751
-    last_time = slapi_current_utc_time();
be9751
+    last_time = slapi_current_rel_time_t();
be9751
     job->start_time = last_time;
be9751
     import_clear_progress_history(job);
be9751
 
be9751
@@ -1789,7 +1790,7 @@ import_monitor_threads(ImportJob *job, int *status)
be9751
 
be9751
         /* First calculate the time interval since last reported */
be9751
         if (0 == (count % display_interval)) {
be9751
-            time_now = slapi_current_utc_time();
be9751
+            time_now = slapi_current_rel_time_t();
be9751
             time_interval = time_now - last_time;
be9751
             last_time = time_now;
be9751
             /* Now calculate our rate of progress overall for this chunk */
be9751
@@ -2232,7 +2233,7 @@ bdb_import_main(void *arg)
be9751
         opstr = "Reindexing";
be9751
     }
be9751
     PR_ASSERT(inst != NULL);
be9751
-    beginning = slapi_current_utc_time();
be9751
+    beginning = slapi_current_rel_time_t();
be9751
 
be9751
     /* Decide which indexes are needed */
be9751
     if (job->flags & FLAG_INDEX_ATTRS) {
be9751
@@ -2251,9 +2252,9 @@ bdb_import_main(void *arg)
be9751
     ret = import_fifo_init(job);
be9751
     if (ret) {
be9751
         if (!(job->flags & FLAG_USE_FILES)) {
be9751
-            PR_Lock(job->wire_lock);
be9751
-            PR_NotifyCondVar(job->wire_cv);
be9751
-            PR_Unlock(job->wire_lock);
be9751
+            pthread_mutex_lock(&job->wire_lock);
be9751
+            pthread_cond_signal(&job->wire_cv);
be9751
+            pthread_mutex_unlock(&job->wire_lock);
be9751
         }
be9751
         goto error;
be9751
     }
be9751
@@ -2315,9 +2316,9 @@ bdb_import_main(void *arg)
be9751
     } else {
be9751
         /* release the startup lock and let the entries start queueing up
be9751
          * in for import */
be9751
-        PR_Lock(job->wire_lock);
be9751
-        PR_NotifyCondVar(job->wire_cv);
be9751
-        PR_Unlock(job->wire_lock);
be9751
+        pthread_mutex_lock(&job->wire_lock);
be9751
+        pthread_cond_signal(&job->wire_cv);
be9751
+        pthread_mutex_unlock(&job->wire_lock);
be9751
     }
be9751
 
be9751
     /* Run as many passes as we need to complete the job or die honourably in
be9751
@@ -2499,7 +2500,7 @@ error:
be9751
             import_log_notice(job, SLAPI_LOG_WARNING, "bdb_import_main", "Failed to close database");
be9751
         }
be9751
     }
be9751
-    end = slapi_current_utc_time();
be9751
+    end = slapi_current_rel_time_t();
be9751
     if (verbose && (0 == ret)) {
be9751
         int seconds_to_import = end - beginning;
be9751
         size_t entries_processed = job->lead_ID - (job->starting_ID - 1);
be9751
@@ -3393,7 +3394,7 @@ import_mega_merge(ImportJob *job)
be9751
                           passes, (long unsigned int)job->number_indexers);
be9751
     }
be9751
 
be9751
-    beginning = slapi_current_utc_time();
be9751
+    beginning = slapi_current_rel_time_t();
be9751
     /* Iterate over the files */
be9751
     for (current_worker = job->worker_list;
be9751
          (ret == 0) && (current_worker != NULL);
be9751
@@ -3405,9 +3406,9 @@ import_mega_merge(ImportJob *job)
be9751
             time_t file_end = 0;
be9751
             int key_count = 0;
be9751
 
be9751
-            file_beginning = slapi_current_utc_time();
be9751
+            file_beginning = slapi_current_rel_time_t();
be9751
             ret = import_merge_one_file(current_worker, passes, &key_count);
be9751
-            file_end = slapi_current_utc_time();
be9751
+            file_end = slapi_current_rel_time_t();
be9751
             if (key_count == 0) {
be9751
                 import_log_notice(job, SLAPI_LOG_INFO, "import_mega_merge", "No files to merge for \"%s\".",
be9751
                                   current_worker->index_info->name);
be9751
@@ -3426,7 +3427,7 @@ import_mega_merge(ImportJob *job)
be9751
         }
be9751
     }
be9751
 
be9751
-    end = slapi_current_utc_time();
be9751
+    end = slapi_current_rel_time_t();
be9751
     if (0 == ret) {
be9751
         int seconds_to_merge = end - beginning;
be9751
         import_log_notice(job, SLAPI_LOG_INFO, "import_mega_merge", "Merging completed in %d seconds.",
be9751
diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import_threads.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import_threads.c
be9751
index 5c7d9c8f7..905a84e74 100644
be9751
--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import_threads.c
be9751
+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_import_threads.c
be9751
@@ -1,5 +1,5 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
- * Copyright (C) 2019 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -3151,8 +3151,9 @@ bulk_import_start(Slapi_PBlock *pb)
be9751
                                      (1024 * 1024);
be9751
     }
be9751
     import_subcount_stuff_init(job->mothers);
be9751
-    job->wire_lock = PR_NewLock();
be9751
-    job->wire_cv = PR_NewCondVar(job->wire_lock);
be9751
+
be9751
+    pthread_mutex_init(&job->wire_lock, NULL);
be9751
+    pthread_cond_init(&job->wire_cv, NULL);
be9751
 
be9751
     /* COPIED from ldif2ldbm.c : */
be9751
 
be9751
@@ -3175,7 +3176,7 @@ bulk_import_start(Slapi_PBlock *pb)
be9751
 
be9751
     /* END OF COPIED SECTION */
be9751
 
be9751
-    PR_Lock(job->wire_lock);
be9751
+    pthread_mutex_lock(&job->wire_lock);
be9751
     vlv_init(job->inst);
be9751
 
be9751
     /* create thread for import_main, so we can return */
be9751
@@ -3188,7 +3189,7 @@ bulk_import_start(Slapi_PBlock *pb)
be9751
         slapi_log_err(SLAPI_LOG_ERR, "bulk_import_start",
be9751
                       "Unable to spawn import thread, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
                       prerr, slapd_pr_strerror(prerr));
be9751
-        PR_Unlock(job->wire_lock);
be9751
+        pthread_mutex_unlock(&job->wire_lock);
be9751
         ret = -2;
be9751
         goto fail;
be9751
     }
be9751
@@ -3204,8 +3205,8 @@ bulk_import_start(Slapi_PBlock *pb)
be9751
     /* (don't want to send the success code back to the LDAP client until
be9751
      * we're ready for the adds to start rolling in)
be9751
      */
be9751
-    PR_WaitCondVar(job->wire_cv, PR_INTERVAL_NO_TIMEOUT);
be9751
-    PR_Unlock(job->wire_lock);
be9751
+    pthread_cond_wait(&job->wire_cv, &job->wire_lock);
be9751
+    pthread_mutex_unlock(&job->wire_lock);
be9751
 
be9751
     return 0;
be9751
 
be9751
@@ -3243,13 +3244,13 @@ bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
be9751
         return -1;
be9751
     }
be9751
 
be9751
-    PR_Lock(job->wire_lock);
be9751
+    pthread_mutex_lock(&job->wire_lock);
be9751
     /* Let's do this inside the lock !*/
be9751
     id = job->lead_ID + 1;
be9751
     /* generate uniqueid if necessary */
be9751
     if (import_generate_uniqueid(job, entry) != UID_SUCCESS) {
be9751
         import_abort_all(job, 1);
be9751
-        PR_Unlock(job->wire_lock);
be9751
+        pthread_mutex_unlock(&job->wire_lock);
be9751
         return -1;
be9751
     }
be9751
 
be9751
@@ -3258,7 +3259,7 @@ bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
be9751
     if ((ep == NULL) || (ep->ep_entry == NULL)) {
be9751
         import_abort_all(job, 1);
be9751
         backentry_free(&ep); /* release the backend wrapper, here */
be9751
-        PR_Unlock(job->wire_lock);
be9751
+        pthread_mutex_unlock(&job->wire_lock);
be9751
         return -1;
be9751
     }
be9751
 
be9751
@@ -3304,7 +3305,7 @@ bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
be9751
         if (job->flags & FLAG_ABORT) {
be9751
             backentry_clear_entry(ep); /* entry is released in the frontend on failure*/
be9751
             backentry_free(&ep);       /* release the backend wrapper, here */
be9751
-            PR_Unlock(job->wire_lock);
be9751
+            pthread_mutex_unlock(&job->wire_lock);
be9751
             return -2;
be9751
         }
be9751
 
be9751
@@ -3342,7 +3343,7 @@ bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
be9751
                     /* entry is released in the frontend on failure*/
be9751
                     backentry_clear_entry(ep);
be9751
                     backentry_free(&ep); /* release the backend wrapper */
be9751
-                    PR_Unlock(job->wire_lock);
be9751
+                    pthread_mutex_unlock(&job->wire_lock);
be9751
                     return -1;
be9751
                 }
be9751
                 sepp = PL_strchr(sepp + 1, ',');
be9751
@@ -3368,7 +3369,7 @@ bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
be9751
                           (long unsigned int)newesize, (long unsigned int)job->fifo.bsize);
be9751
         backentry_clear_entry(ep); /* entry is released in the frontend on failure*/
be9751
         backentry_free(&ep);       /* release the backend wrapper, here */
be9751
-        PR_Unlock(job->wire_lock);
be9751
+        pthread_mutex_unlock(&job->wire_lock);
be9751
         return -1;
be9751
     }
be9751
     /* Now check if fifo has enough space for the new entry */
be9751
@@ -3394,7 +3395,7 @@ bulk_import_queue(ImportJob *job, Slapi_Entry *entry)
be9751
         job->trailing_ID = id - job->fifo.size;
be9751
     }
be9751
 
be9751
-    PR_Unlock(job->wire_lock);
be9751
+    pthread_mutex_unlock(&job->wire_lock);
be9751
     return 0;
be9751
 }
be9751
 
be9751
diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_instance_config.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_instance_config.c
be9751
index 0ac3694b6..5d6010f46 100644
be9751
--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_instance_config.c
be9751
+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_instance_config.c
be9751
@@ -1,5 +1,5 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
- * Copyright (C) 2019 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -270,10 +270,8 @@ bdb_instance_cleanup(struct ldbm_instance *inst)
be9751
             slapi_ch_free_string(&inst_dirp);
be9751
     }
be9751
     slapi_destroy_rwlock(inst_env->bdb_env_lock);
be9751
-    PR_DestroyCondVar(inst_env->bdb_thread_count_cv);
be9751
-    inst_env->bdb_thread_count_cv = NULL;
be9751
-    PR_DestroyLock(inst_env->bdb_thread_count_lock);
be9751
-    inst_env->bdb_thread_count_lock = NULL;
be9751
+    pthread_mutex_destroy(&(inst_env->bdb_thread_count_lock));
be9751
+    pthread_cond_destroy(&(inst_env->bdb_thread_count_cv));
be9751
     slapi_ch_free((void **)&inst->inst_db);
be9751
     /* 
be9751
     slapi_destroy_rwlock(((bdb_db_env *)inst->inst_db)->bdb_env_lock);
be9751
diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c
be9751
index 464f89f4d..6cccad8e6 100644
be9751
--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c
be9751
+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.c
be9751
@@ -1,5 +1,5 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
- * Copyright (C) 2019 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -52,16 +52,16 @@
be9751
    return.
be9751
 */
be9751
 #define INCR_THREAD_COUNT(pEnv)       \
be9751
-    PR_Lock(pEnv->bdb_thread_count_lock); \
be9751
+    pthread_mutex_lock(&pEnv->bdb_thread_count_lock); \
be9751
     ++pEnv->bdb_thread_count;     \
be9751
-    PR_Unlock(pEnv->bdb_thread_count_lock)
be9751
+    pthread_mutex_unlock(&pEnv->bdb_thread_count_lock)
be9751
 
be9751
 #define DECR_THREAD_COUNT(pEnv)                  \
be9751
-    PR_Lock(pEnv->bdb_thread_count_lock);            \
be9751
+    pthread_mutex_lock(&pEnv->bdb_thread_count_lock);            \
be9751
     if (--pEnv->bdb_thread_count == 0) {     \
be9751
-        PR_NotifyCondVar(pEnv->bdb_thread_count_cv); \
be9751
+        pthread_cond_broadcast(&pEnv->bdb_thread_count_cv); \
be9751
     }                                            \
be9751
-    PR_Unlock(pEnv->bdb_thread_count_lock)
be9751
+    pthread_mutex_unlock(&pEnv->bdb_thread_count_lock)
be9751
 
be9751
 #define NEWDIR_MODE 0755
be9751
 #define DB_REGION_PREFIX "__db."
be9751
@@ -91,9 +91,12 @@ static int trans_batch_txn_max_sleep = 50;
be9751
 static PRBool log_flush_thread = PR_FALSE;
be9751
 static int txn_in_progress_count = 0;
be9751
 static int *txn_log_flush_pending = NULL;
be9751
-static PRLock *sync_txn_log_flush = NULL;
be9751
-static PRCondVar *sync_txn_log_flush_done = NULL;
be9751
-static PRCondVar *sync_txn_log_do_flush = NULL;
be9751
+
be9751
+static pthread_mutex_t sync_txn_log_flush;
be9751
+static pthread_cond_t sync_txn_log_flush_done;
be9751
+static pthread_cond_t sync_txn_log_do_flush;
be9751
+
be9751
+
be9751
 static int bdb_db_remove_ex(bdb_db_env *env, char const path[], char const dbName[], PRBool use_lock);
be9751
 static int bdb_restore_file_check(struct ldbminfo *li);
be9751
 
be9751
@@ -181,12 +184,12 @@ bdb_set_batch_transactions(void *arg __attribute__((unused)), void *value, char
be9751
         } else {
be9751
             if (val == 0) {
be9751
                 if (log_flush_thread) {
be9751
-                    PR_Lock(sync_txn_log_flush);
be9751
+                    pthread_mutex_lock(&sync_txn_log_flush);
be9751
                 }
be9751
                 trans_batch_limit = FLUSH_REMOTEOFF;
be9751
                 if (log_flush_thread) {
be9751
                     log_flush_thread = PR_FALSE;
be9751
-                    PR_Unlock(sync_txn_log_flush);
be9751
+                    pthread_mutex_unlock(&sync_txn_log_flush);
be9751
                 }
be9751
             } else if (val > 0) {
be9751
                 if (trans_batch_limit == FLUSH_REMOTEOFF) {
be9751
@@ -217,12 +220,12 @@ bdb_set_batch_txn_min_sleep(void *arg __attribute__((unused)), void *value, char
be9751
         } else {
be9751
             if (val == 0) {
be9751
                 if (log_flush_thread) {
be9751
-                    PR_Lock(sync_txn_log_flush);
be9751
+                    pthread_mutex_lock(&sync_txn_log_flush);
be9751
                 }
be9751
                 trans_batch_txn_min_sleep = FLUSH_REMOTEOFF;
be9751
                 if (log_flush_thread) {
be9751
                     log_flush_thread = PR_FALSE;
be9751
-                    PR_Unlock(sync_txn_log_flush);
be9751
+                    pthread_mutex_unlock(&sync_txn_log_flush);
be9751
                 }
be9751
             } else if (val > 0) {
be9751
                 if (trans_batch_txn_min_sleep == FLUSH_REMOTEOFF || !log_flush_thread) {
be9751
@@ -249,12 +252,12 @@ bdb_set_batch_txn_max_sleep(void *arg __attribute__((unused)), void *value, char
be9751
         } else {
be9751
             if (val == 0) {
be9751
                 if (log_flush_thread) {
be9751
-                    PR_Lock(sync_txn_log_flush);
be9751
+                    pthread_mutex_lock(&sync_txn_log_flush);
be9751
                 }
be9751
                 trans_batch_txn_max_sleep = FLUSH_REMOTEOFF;
be9751
                 if (log_flush_thread) {
be9751
                     log_flush_thread = PR_FALSE;
be9751
-                    PR_Unlock(sync_txn_log_flush);
be9751
+                    pthread_mutex_unlock(&sync_txn_log_flush);
be9751
                 }
be9751
             } else if (val > 0) {
be9751
                 if (trans_batch_txn_max_sleep == FLUSH_REMOTEOFF || !log_flush_thread) {
be9751
@@ -725,10 +728,9 @@ bdb_free_env(void **arg)
be9751
         slapi_destroy_rwlock((*env)->bdb_env_lock);
be9751
         (*env)->bdb_env_lock = NULL;
be9751
     }
be9751
-    PR_DestroyCondVar((*env)->bdb_thread_count_cv);
be9751
-    (*env)->bdb_thread_count_cv = NULL;
be9751
-    PR_DestroyLock((*env)->bdb_thread_count_lock);
be9751
-    (*env)->bdb_thread_count_lock = NULL;
be9751
+    pthread_mutex_destroy(&((*env)->bdb_thread_count_lock));
be9751
+    pthread_cond_destroy(&((*env)->bdb_thread_count_cv));
be9751
+
be9751
     slapi_ch_free((void **)env);
be9751
     return;
be9751
 }
be9751
@@ -746,11 +748,15 @@ bdb_make_env(bdb_db_env **env, struct ldbminfo *li)
be9751
     int ret;
be9751
     Object *inst_obj;
be9751
     ldbm_instance *inst = NULL;
be9751
+    pthread_condattr_t condAttr;
be9751
 
be9751
     pEnv = (bdb_db_env *)slapi_ch_calloc(1, sizeof(bdb_db_env));
be9751
 
be9751
-    pEnv->bdb_thread_count_lock = PR_NewLock();
be9751
-    pEnv->bdb_thread_count_cv = PR_NewCondVar(pEnv->bdb_thread_count_lock);
be9751
+    pthread_mutex_init(&pEnv->bdb_thread_count_lock, NULL);
be9751
+    pthread_condattr_init(&condAttr);
be9751
+    pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);
be9751
+    pthread_cond_init(&pEnv->bdb_thread_count_cv, &condAttr);
be9751
+    pthread_condattr_destroy(&condAttr); /* no longer needed */
be9751
 
be9751
     if ((ret = db_env_create(&pEnv->bdb_DB_ENV, 0)) != 0) {
be9751
         slapi_log_err(SLAPI_LOG_ERR,
be9751
@@ -2013,9 +2019,9 @@ bdb_pre_close(struct ldbminfo *li)
be9751
         return;
be9751
 
be9751
     /* first, see if there are any housekeeping threads running */
be9751
-    PR_Lock(pEnv->bdb_thread_count_lock);
be9751
+    pthread_mutex_lock(&pEnv->bdb_thread_count_lock);
be9751
     threadcount = pEnv->bdb_thread_count;
be9751
-    PR_Unlock(pEnv->bdb_thread_count_lock);
be9751
+    pthread_mutex_unlock(&pEnv->bdb_thread_count_lock);
be9751
 
be9751
     if (threadcount) {
be9751
         PRIntervalTime cvwaittime = PR_MillisecondsToInterval(DBLAYER_SLEEP_INTERVAL * 100);
be9751
@@ -2023,7 +2029,7 @@ bdb_pre_close(struct ldbminfo *li)
be9751
         /* Print handy-dandy log message */
be9751
         slapi_log_err(SLAPI_LOG_INFO, "bdb_pre_close", "Waiting for %d database threads to stop\n",
be9751
                       threadcount);
be9751
-        PR_Lock(pEnv->bdb_thread_count_lock);
be9751
+        pthread_mutex_lock(&pEnv->bdb_thread_count_lock);
be9751
         /* Tell them to stop - we wait until the last possible moment to invoke
be9751
            this.  If we do this much sooner than this, we could find ourselves
be9751
            in a situation where the threads see the stop_threads and exit before
be9751
@@ -2034,6 +2040,7 @@ bdb_pre_close(struct ldbminfo *li)
be9751
         conf->bdb_stop_threads = 1;
be9751
         /* Wait for them to exit */
be9751
         while (pEnv->bdb_thread_count > 0) {
be9751
+            struct timespec current_time = {0};
be9751
             PRIntervalTime before = PR_IntervalNow();
be9751
             /* There are 3 ways to wake up from this WaitCondVar:
be9751
                1) The last database thread exits and calls NotifyCondVar - thread_count
be9751
@@ -2041,7 +2048,9 @@ bdb_pre_close(struct ldbminfo *li)
be9751
                2) Timeout - in this case, thread_count will be > 0 - bad
be9751
                3) A bad error occurs - bad - will be reported as a timeout
be9751
             */
be9751
-            PR_WaitCondVar(pEnv->bdb_thread_count_cv, cvwaittime);
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += DBLAYER_SLEEP_INTERVAL / 10; /* cvwaittime but in seconds */
be9751
+            pthread_cond_timedwait(&pEnv->bdb_thread_count_cv, &pEnv->bdb_thread_count_lock, &current_time);
be9751
             if (pEnv->bdb_thread_count > 0) {
be9751
                 /* still at least 1 thread running - see if this is a timeout */
be9751
                 if ((PR_IntervalNow() - before) >= cvwaittime) {
be9751
@@ -2052,7 +2061,7 @@ bdb_pre_close(struct ldbminfo *li)
be9751
                 /* else just a spurious interrupt */
be9751
             }
be9751
         }
be9751
-        PR_Unlock(pEnv->bdb_thread_count_lock);
be9751
+        pthread_mutex_unlock(&pEnv->bdb_thread_count_lock);
be9751
         if (timedout) {
be9751
             slapi_log_err(SLAPI_LOG_ERR,
be9751
                           "bdb_pre_close", "Timeout after [%d] milliseconds; leave %d database thread(s)...\n",
be9751
@@ -2645,12 +2654,12 @@ bdb_txn_begin(struct ldbminfo *li, back_txnid parent_txn, back_txn *txn, PRBool
be9751
                and new parent for any nested transactions created */
be9751
             if (use_lock && log_flush_thread) {
be9751
                 int txn_id = new_txn.back_txn_txn->id(new_txn.back_txn_txn);
be9751
-                PR_Lock(sync_txn_log_flush);
be9751
+                pthread_mutex_lock(&sync_txn_log_flush);
be9751
                 txn_in_progress_count++;
be9751
                 slapi_log_err(SLAPI_LOG_BACKLDBM, "dblayer_txn_begin_ext",
be9751
                               "Batchcount: %d, txn_in_progress: %d, curr_txn: %x\n",
be9751
                               trans_batch_count, txn_in_progress_count, txn_id);
be9751
-                PR_Unlock(sync_txn_log_flush);
be9751
+                pthread_mutex_unlock(&sync_txn_log_flush);
be9751
             }
be9751
             dblayer_push_pvt_txn(&new_txn);
be9751
             if (txn) {
be9751
@@ -2717,11 +2726,11 @@ bdb_txn_commit(struct ldbminfo *li, back_txn *txn, PRBool use_lock)
be9751
         if ((conf->bdb_durable_transactions) && use_lock) {
be9751
             if (trans_batch_limit > 0 && log_flush_thread) {
be9751
                 /* let log_flush thread do the flushing */
be9751
-                PR_Lock(sync_txn_log_flush);
be9751
+                pthread_mutex_lock(&sync_txn_log_flush);
be9751
                 txn_batch_slot = trans_batch_count++;
be9751
                 txn_log_flush_pending[txn_batch_slot] = txn_id;
be9751
-                slapi_log_err(SLAPI_LOG_BACKLDBM, "dblayer_txn_commit_ext", "(before notify): batchcount: %d, "
be9751
-                                                                            "txn_in_progress: %d, curr_txn: %x\n",
be9751
+                slapi_log_err(SLAPI_LOG_BACKLDBM, "dblayer_txn_commit_ext",
be9751
+                              "(before notify): batchcount: %d, txn_in_progress: %d, curr_txn: %x\n",
be9751
                               trans_batch_count,
be9751
                               txn_in_progress_count, txn_id);
be9751
                 /*
be9751
@@ -2731,8 +2740,9 @@ bdb_txn_commit(struct ldbminfo *li, back_txn *txn, PRBool use_lock)
be9751
                  * - there is no other outstanding txn
be9751
                  */
be9751
                 if (trans_batch_count > trans_batch_limit ||
be9751
-                    trans_batch_count == txn_in_progress_count) {
be9751
-                    PR_NotifyCondVar(sync_txn_log_do_flush);
be9751
+                    trans_batch_count == txn_in_progress_count)
be9751
+                {
be9751
+                    pthread_cond_signal(&sync_txn_log_do_flush);
be9751
                 }
be9751
                 /*
be9751
                  * We need to wait until the txn has been flushed before continuing
be9751
@@ -2740,14 +2750,14 @@ bdb_txn_commit(struct ldbminfo *li, back_txn *txn, PRBool use_lock)
be9751
                  * PR_WaitCondvar releases and reaquires the lock
be9751
                  */
be9751
                 while (txn_log_flush_pending[txn_batch_slot] == txn_id) {
be9751
-                    PR_WaitCondVar(sync_txn_log_flush_done, PR_INTERVAL_NO_TIMEOUT);
be9751
+                    pthread_cond_wait(&sync_txn_log_flush_done, &sync_txn_log_flush);
be9751
                 }
be9751
                 txn_in_progress_count--;
be9751
-                slapi_log_err(SLAPI_LOG_BACKLDBM, "dblayer_txn_commit_ext", "(before unlock): batchcount: %d, "
be9751
-                                                                            "txn_in_progress: %d, curr_txn %x\n",
be9751
+                slapi_log_err(SLAPI_LOG_BACKLDBM, "dblayer_txn_commit_ext",
be9751
+                              "(before unlock): batchcount: %d, txn_in_progress: %d, curr_txn %x\n",
be9751
                               trans_batch_count,
be9751
                               txn_in_progress_count, txn_id);
be9751
-                PR_Unlock(sync_txn_log_flush);
be9751
+                pthread_mutex_unlock(&sync_txn_log_flush);
be9751
             } else if (trans_batch_limit == FLUSH_REMOTEOFF) { /* user remotely turned batching off */
be9751
                 LOG_FLUSH(pEnv->bdb_DB_ENV, 0);
be9751
             }
be9751
@@ -2799,9 +2809,9 @@ bdb_txn_abort(struct ldbminfo *li, back_txn *txn, PRBool use_lock)
be9751
         int txn_id = db_txn->id(db_txn);
be9751
         bdb_db_env *pEnv = (bdb_db_env *)priv->dblayer_env;
be9751
         if (use_lock && log_flush_thread) {
be9751
-            PR_Lock(sync_txn_log_flush);
be9751
+            pthread_mutex_lock(&sync_txn_log_flush);
be9751
             txn_in_progress_count--;
be9751
-            PR_Unlock(sync_txn_log_flush);
be9751
+            pthread_mutex_unlock(&sync_txn_log_flush);
be9751
             slapi_log_err(SLAPI_LOG_BACKLDBM, "dblayer_txn_abort_ext",
be9751
                           "Batchcount: %d, txn_in_progress: %d, curr_txn: %x\n",
be9751
                           trans_batch_count, txn_in_progress_count, txn_id);
be9751
@@ -3420,11 +3430,18 @@ bdb_start_log_flush_thread(struct ldbminfo *li)
be9751
     int max_threads = config_get_threadnumber();
be9751
 
be9751
     if ((BDB_CONFIG(li)->bdb_durable_transactions) &&
be9751
-        (BDB_CONFIG(li)->bdb_enable_transactions) && (trans_batch_limit > 0)) {
be9751
+        (BDB_CONFIG(li)->bdb_enable_transactions) && (trans_batch_limit > 0))
be9751
+    {
be9751
         /* initialize the synchronization objects for the log_flush and worker threads */
be9751
-        sync_txn_log_flush = PR_NewLock();
be9751
-        sync_txn_log_flush_done = PR_NewCondVar(sync_txn_log_flush);
be9751
-        sync_txn_log_do_flush = PR_NewCondVar(sync_txn_log_flush);
be9751
+        pthread_condattr_t condAttr;
be9751
+
be9751
+        pthread_mutex_init(&sync_txn_log_flush, NULL);
be9751
+        pthread_condattr_init(&condAttr);
be9751
+        pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);
be9751
+        pthread_cond_init(&sync_txn_log_do_flush, &condAttr);
be9751
+        pthread_cond_init(&sync_txn_log_flush_done, NULL);
be9751
+        pthread_condattr_destroy(&condAttr); /* no longer needed */
be9751
+
be9751
         txn_log_flush_pending = (int *)slapi_ch_malloc(max_threads * sizeof(int));
be9751
         log_flush_thread = PR_TRUE;
be9751
         if (NULL == PR_CreateThread(PR_USER_THREAD,
be9751
@@ -3451,7 +3468,7 @@ bdb_start_log_flush_thread(struct ldbminfo *li)
be9751
 static int
be9751
 log_flush_threadmain(void *param)
be9751
 {
be9751
-    PRIntervalTime interval_wait, interval_flush, interval_def;
be9751
+    PRIntervalTime interval_flush, interval_def;
be9751
     PRIntervalTime last_flush = 0;
be9751
     int i;
be9751
     int do_flush = 0;
be9751
@@ -3464,7 +3481,6 @@ log_flush_threadmain(void *param)
be9751
     INCR_THREAD_COUNT(pEnv);
be9751
 
be9751
     interval_flush = PR_MillisecondsToInterval(trans_batch_txn_min_sleep);
be9751
-    interval_wait = PR_MillisecondsToInterval(trans_batch_txn_max_sleep);
be9751
     interval_def = PR_MillisecondsToInterval(300); /*used while no txn or txn batching */
be9751
     /* LK this is only needed if online change of
be9751
      * of txn config is supported ???
be9751
@@ -3473,10 +3489,10 @@ log_flush_threadmain(void *param)
be9751
         if (BDB_CONFIG(li)->bdb_enable_transactions) {
be9751
             if (trans_batch_limit > 0) {
be9751
                 /* synchronize flushing thread with workers */
be9751
-                PR_Lock(sync_txn_log_flush);
be9751
+                pthread_mutex_lock(&sync_txn_log_flush);
be9751
                 if (!log_flush_thread) {
be9751
                     /* batch transactions was disabled while waiting for the lock */
be9751
-                    PR_Unlock(sync_txn_log_flush);
be9751
+                    pthread_mutex_unlock(&sync_txn_log_flush);
be9751
                     break;
be9751
                 }
be9751
                 slapi_log_err(SLAPI_LOG_BACKLDBM, "log_flush_threadmain", "(in loop): batchcount: %d, "
be9751
@@ -3502,20 +3518,31 @@ log_flush_threadmain(void *param)
be9751
                     slapi_log_err(SLAPI_LOG_BACKLDBM, "log_flush_threadmain", "(before notify): batchcount: %d, "
be9751
                                                                               "txn_in_progress: %d\n",
be9751
                                   trans_batch_count, txn_in_progress_count);
be9751
-                    PR_NotifyAllCondVar(sync_txn_log_flush_done);
be9751
+                    pthread_cond_broadcast(&sync_txn_log_flush_done);
be9751
                 }
be9751
                 /* wait until flushing conditions are met */
be9751
                 while ((trans_batch_count == 0) ||
be9751
-                       (trans_batch_count < trans_batch_limit && trans_batch_count < txn_in_progress_count)) {
be9751
+                       (trans_batch_count < trans_batch_limit && trans_batch_count < txn_in_progress_count))
be9751
+                {
be9751
+                    struct timespec current_time = {0};
be9751
+                    /* convert milliseconds to nano seconds */
be9751
+                    int32_t nano_sec_sleep = trans_batch_txn_max_sleep * 1000000;
be9751
                     if (BDB_CONFIG(li)->bdb_stop_threads)
be9751
                         break;
be9751
                     if (PR_IntervalNow() - last_flush > interval_flush) {
be9751
                         do_flush = 1;
be9751
                         break;
be9751
                     }
be9751
-                    PR_WaitCondVar(sync_txn_log_do_flush, interval_wait);
be9751
+                    clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+                    if (current_time.tv_nsec + nano_sec_sleep > 1000000000) {
be9751
+                        /* nano sec will overflow, just bump the seconds */
be9751
+                        current_time.tv_sec++;
be9751
+                    } else {
be9751
+                        current_time.tv_nsec += nano_sec_sleep;
be9751
+                    }
be9751
+                    pthread_cond_timedwait(&sync_txn_log_do_flush, &sync_txn_log_flush, &current_time);
be9751
                 }
be9751
-                PR_Unlock(sync_txn_log_flush);
be9751
+                pthread_mutex_unlock(&sync_txn_log_flush);
be9751
                 slapi_log_err(SLAPI_LOG_BACKLDBM, "log_flush_threadmain", "(wakeup): batchcount: %d, "
be9751
                                                                           "txn_in_progress: %d\n",
be9751
                               trans_batch_count, txn_in_progress_count);
be9751
diff --git a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h
be9751
index bf00d2e9a..6bb04d21a 100644
be9751
--- a/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h
be9751
+++ b/ldap/servers/slapd/back-ldbm/db-bdb/bdb_layer.h
be9751
@@ -1,5 +1,5 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
- * Copyright (C) 2019 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -18,10 +18,10 @@ typedef struct bdb_db_env
be9751
     Slapi_RWLock *bdb_env_lock;
be9751
     int bdb_openflags;
be9751
     int bdb_priv_flags;
be9751
-    PRLock *bdb_thread_count_lock;      /* lock for thread_count_cv */
be9751
-    PRCondVar *bdb_thread_count_cv;     /* condition variable for housekeeping thread shutdown */
be9751
-    PRInt32 bdb_thread_count;           /* Tells us how many threads are running,
be9751
-                                         * used to figure out when they're all stopped */
be9751
+    pthread_mutex_t bdb_thread_count_lock; /* lock for thread_count_cv */
be9751
+    pthread_cond_t bdb_thread_count_cv;    /* condition variable for housekeeping thread shutdown */
be9751
+    PRInt32 bdb_thread_count;              /* Tells us how many threads are running,
be9751
+                                            * used to figure out when they're all stopped */
be9751
 } bdb_db_env;
be9751
 
be9751
 /* structure which holds our stuff */
be9751
diff --git a/ldap/servers/slapd/back-ldbm/import.h b/ldap/servers/slapd/back-ldbm/import.h
be9751
index db77a602b..bfa74ed49 100644
be9751
--- a/ldap/servers/slapd/back-ldbm/import.h
be9751
+++ b/ldap/servers/slapd/back-ldbm/import.h
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -130,8 +130,8 @@ typedef struct
be9751
     char **exclude_subtrees;            /* list of subtrees to NOT import */
be9751
     Fifo fifo;                          /* entry fifo for indexing */
be9751
     char *task_status;                  /* transient state info for the end-user */
be9751
-    PRLock *wire_lock;                  /* lock for serializing wire imports */
be9751
-    PRCondVar *wire_cv;                 /* ... and ordering the startup */
be9751
+    pthread_mutex_t wire_lock;          /* lock for serializing wire imports */
be9751
+    pthread_cond_t wire_cv;             /* ... and ordering the startup */
be9751
     PRThread *main_thread;              /* for FRI: import_main() thread id */
be9751
     int encrypt;
be9751
     Slapi_Value *usn_value; /* entryusn for import */
be9751
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
be9751
index 88b7dc3be..1883fe711 100644
be9751
--- a/ldap/servers/slapd/connection.c
be9751
+++ b/ldap/servers/slapd/connection.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -64,8 +64,10 @@ struct Slapi_work_q
be9751
 
be9751
 static struct Slapi_work_q *head_work_q = NULL; /* global work queue head */
be9751
 static struct Slapi_work_q *tail_work_q = NULL; /* global work queue tail */
be9751
-static PRLock *work_q_lock = NULL;              /* protects head_conn_q and tail_conn_q */
be9751
-static PRCondVar *work_q_cv;                    /* used by operation threads to wait for work - when there is a conn in the queue waiting to be processed */
be9751
+static pthread_mutex_t work_q_lock;             /* protects head_conn_q and tail_conn_q */
be9751
+static pthread_cond_t work_q_cv;                /* used by operation threads to wait for work -
be9751
+                                                 * when there is a conn in the queue waiting
be9751
+                                                 * to be processed */
be9751
 static PRInt32 work_q_size;                     /* size of conn_q */
be9751
 static PRInt32 work_q_size_max;                 /* high water mark of work_q_size */
be9751
 #define WORK_Q_EMPTY (work_q_size == 0)
be9751
@@ -409,7 +411,7 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib
be9751
 
be9751
     /* initialize the remaining connection fields */
be9751
     conn->c_ldapversion = LDAP_VERSION3;
be9751
-    conn->c_starttime = slapi_current_utc_time();
be9751
+    conn->c_starttime = slapi_current_rel_time_t();
be9751
     conn->c_idlesince = conn->c_starttime;
be9751
     conn->c_flags = is_SSL ? CONN_FLAG_SSL : 0;
be9751
     conn->c_authtype = slapi_ch_strdup(SLAPD_AUTH_NONE);
be9751
@@ -424,32 +426,40 @@ connection_reset(Connection *conn, int ns, PRNetAddr *from, int fromLen __attrib
be9751
 void
be9751
 init_op_threads()
be9751
 {
be9751
-    int i;
be9751
-    PRErrorCode errorCode;
be9751
-    int max_threads = config_get_threadnumber();
be9751
-    /* Initialize the locks and cv */
be9751
+    pthread_condattr_t condAttr;
be9751
+    int32_t max_threads = config_get_threadnumber();
be9751
+    int32_t rc;
be9751
 
be9751
-    if ((work_q_lock = PR_NewLock()) == NULL) {
be9751
-        errorCode = PR_GetError();
be9751
-        slapi_log_err(SLAPI_LOG_ERR,
be9751
-                      "init_op_threads", "PR_NewLock failed for work_q_lock, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
-                      errorCode, slapd_pr_strerror(errorCode));
be9751
+    /* Initialize the locks and cv */
be9751
+    if ((rc = pthread_mutex_init(&work_q_lock, NULL)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "init_op_threads",
be9751
+                      "Cannot create new lock.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         exit(-1);
be9751
     }
be9751
-
be9751
-    if ((work_q_cv = PR_NewCondVar(work_q_lock)) == NULL) {
be9751
-        errorCode = PR_GetError();
be9751
-        slapi_log_err(SLAPI_LOG_ERR, "init_op_threads", "PR_NewCondVar failed for work_q_cv, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
-                      errorCode, slapd_pr_strerror(errorCode));
be9751
+    if ((rc = pthread_condattr_init(&condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "init_op_threads",
be9751
+                      "Cannot create new condition attribute variable.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+        exit(-1);
be9751
+    } else if ((rc = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "init_op_threads",
be9751
+                      "Cannot set condition attr clock.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+        exit(-1);
be9751
+    } else if ((rc = pthread_cond_init(&work_q_cv, &condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "init_op_threads",
be9751
+                      "Cannot create new condition variable.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         exit(-1);
be9751
     }
be9751
+    pthread_condattr_destroy(&condAttr); /* no longer needed */
be9751
 
be9751
     work_q_stack = PR_CreateStack("connection_work_q");
be9751
-
be9751
     op_stack = PR_CreateStack("connection_operation");
be9751
 
be9751
     /* start the operation threads */
be9751
-    for (i = 0; i < max_threads; i++) {
be9751
+    for (size_t i = 0; i < max_threads; i++) {
be9751
         PR_SetConcurrency(4);
be9751
         if (PR_CreateThread(PR_USER_THREAD,
be9751
                             (VFP)(void *)connection_threadmain, NULL,
be9751
@@ -457,7 +467,8 @@ init_op_threads()
be9751
                             PR_UNJOINABLE_THREAD,
be9751
                             SLAPD_DEFAULT_THREAD_STACKSIZE) == NULL) {
be9751
             int prerr = PR_GetError();
be9751
-            slapi_log_err(SLAPI_LOG_ERR, "init_op_threads", "PR_CreateThread failed, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "init_op_threads",
be9751
+                          "PR_CreateThread failed, " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
                           prerr, slapd_pr_strerror(prerr));
be9751
         } else {
be9751
             g_incr_active_threadcnt();
be9751
@@ -949,16 +960,23 @@ connection_make_new_pb(Slapi_PBlock *pb, Connection *conn)
be9751
 }
be9751
 
be9751
 int
be9751
-connection_wait_for_new_work(Slapi_PBlock *pb, PRIntervalTime interval)
be9751
+connection_wait_for_new_work(Slapi_PBlock *pb, int32_t interval)
be9751
 {
be9751
     int ret = CONN_FOUND_WORK_TO_DO;
be9751
     work_q_item *wqitem = NULL;
be9751
     struct Slapi_op_stack *op_stack_obj = NULL;
be9751
 
be9751
-    PR_Lock(work_q_lock);
be9751
+    pthread_mutex_lock(&work_q_lock);
be9751
 
be9751
     while (!op_shutdown && WORK_Q_EMPTY) {
be9751
-        PR_WaitCondVar(work_q_cv, interval);
be9751
+        if (interval == 0 ) {
be9751
+            pthread_cond_wait(&work_q_cv, &work_q_lock);
be9751
+        } else {
be9751
+            struct timespec current_time = {0};
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += interval;
be9751
+            pthread_cond_timedwait(&work_q_cv, &work_q_lock, &current_time);
be9751
+        }
be9751
     }
be9751
 
be9751
     if (op_shutdown) {
be9751
@@ -975,7 +993,7 @@ connection_wait_for_new_work(Slapi_PBlock *pb, PRIntervalTime interval)
be9751
         slapi_pblock_set(pb, SLAPI_OPERATION, op_stack_obj->op);
be9751
     }
be9751
 
be9751
-    PR_Unlock(work_q_lock);
be9751
+    pthread_mutex_unlock(&work_q_lock);
be9751
     return ret;
be9751
 }
be9751
 
be9751
@@ -1353,7 +1371,7 @@ connection_check_activity_level(Connection *conn)
be9751
     /* store current count in the previous count slot */
be9751
     conn->c_private->previous_op_count = current_count;
be9751
     /* update the last checked time */
be9751
-    conn->c_private->previous_count_check_time = slapi_current_utc_time();
be9751
+    conn->c_private->previous_count_check_time = slapi_current_rel_time_t();
be9751
     pthread_mutex_unlock(&(conn->c_mutex));
be9751
     slapi_log_err(SLAPI_LOG_CONNS, "connection_check_activity_level", "conn %" PRIu64 " activity level = %d\n", conn->c_connid, delta_count);
be9751
 }
be9751
@@ -1463,7 +1481,7 @@ connection_threadmain()
be9751
 {
be9751
     Slapi_PBlock *pb = slapi_pblock_new();
be9751
     /* wait forever for new pb until one is available or shutdown */
be9751
-    PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT; /* PR_SecondsToInterval(10); */
be9751
+    int32_t interval = 0; /* used be  10 seconds */
be9751
     Connection *conn = NULL;
be9751
     Operation *op;
be9751
     ber_tag_t tag = 0;
be9751
@@ -1503,7 +1521,7 @@ connection_threadmain()
be9751
 
be9751
             switch (ret) {
be9751
             case CONN_NOWORK:
be9751
-                PR_ASSERT(interval != PR_INTERVAL_NO_TIMEOUT); /* this should never happen with PR_INTERVAL_NO_TIMEOUT */
be9751
+                PR_ASSERT(interval != 0); /* this should never happen */
be9751
                 continue;
be9751
             case CONN_SHUTDOWN:
be9751
                 slapi_log_err(SLAPI_LOG_TRACE, "connection_threadmain",
be9751
@@ -1610,7 +1628,7 @@ connection_threadmain()
be9751
                           conn->c_opsinitiated, conn->c_refcnt, conn->c_flags);
be9751
         }
be9751
 
be9751
-        curtime = slapi_current_utc_time();
be9751
+        curtime = slapi_current_rel_time_t();
be9751
 #define DB_PERF_TURBO 1
be9751
 #if defined(DB_PERF_TURBO)
be9751
         /* If it's been a while since we last did it ... */
be9751
@@ -1914,7 +1932,7 @@ add_work_q(work_q_item *wqitem, struct Slapi_op_stack *op_stack_obj)
be9751
     new_work_q->op_stack_obj = op_stack_obj;
be9751
     new_work_q->next_work_item = NULL;
be9751
 
be9751
-    PR_Lock(work_q_lock);
be9751
+    pthread_mutex_lock(&work_q_lock);
be9751
     if (tail_work_q == NULL) {
be9751
         tail_work_q = new_work_q;
be9751
         head_work_q = new_work_q;
be9751
@@ -1926,8 +1944,8 @@ add_work_q(work_q_item *wqitem, struct Slapi_op_stack *op_stack_obj)
be9751
     if (work_q_size > work_q_size_max) {
be9751
         work_q_size_max = work_q_size;
be9751
     }
be9751
-    PR_NotifyCondVar(work_q_cv); /* notify waiters in connection_wait_for_new_work */
be9751
-    PR_Unlock(work_q_lock);
be9751
+    pthread_cond_signal(&work_q_cv); /* notify waiters in connection_wait_for_new_work */
be9751
+    pthread_mutex_unlock(&work_q_lock);
be9751
 }
be9751
 
be9751
 /* get_work_q(): will get a work_q_item from the beginning of the work queue, return NULL if
be9751
@@ -1975,9 +1993,9 @@ op_thread_cleanup()
be9751
                   op_stack_size, work_q_size_max, work_q_stack_size_max);
be9751
 
be9751
     PR_AtomicIncrement(&op_shutdown);
be9751
-    PR_Lock(work_q_lock);
be9751
-    PR_NotifyAllCondVar(work_q_cv); /* tell any thread waiting in connection_wait_for_new_work to shutdown */
be9751
-    PR_Unlock(work_q_lock);
be9751
+    pthread_mutex_lock(&work_q_lock);
be9751
+    pthread_cond_broadcast(&work_q_cv); /* tell any thread waiting in connection_wait_for_new_work to shutdown */
be9751
+    pthread_mutex_unlock(&work_q_lock);
be9751
 }
be9751
 
be9751
 /* do this after all worker threads have terminated */
be9751
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
be9751
index bfd965263..0071ed86a 100644
be9751
--- a/ldap/servers/slapd/daemon.c
be9751
+++ b/ldap/servers/slapd/daemon.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -81,8 +81,9 @@ static int readsignalpipe = SLAPD_INVALID_SOCKET;
be9751
 #define FDS_SIGNAL_PIPE 0
be9751
 
be9751
 static PRThread *disk_thread_p = NULL;
be9751
-static PRCondVar *diskmon_cvar = NULL;
be9751
-static PRLock *diskmon_mutex = NULL;
be9751
+static pthread_cond_t diskmon_cvar;
be9751
+static pthread_mutex_t diskmon_mutex;
be9751
+
be9751
 void disk_monitoring_stop(void);
be9751
 
be9751
 typedef struct listener_info
be9751
@@ -441,9 +442,13 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
be9751
 
be9751
     while (!g_get_shutdown()) {
be9751
         if (!first_pass) {
be9751
-            PR_Lock(diskmon_mutex);
be9751
-            PR_WaitCondVar(diskmon_cvar, PR_SecondsToInterval(10));
be9751
-            PR_Unlock(diskmon_mutex);
be9751
+            struct timespec current_time = {0};
be9751
+
be9751
+            pthread_mutex_lock(&diskmon_mutex);
be9751
+            clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+            current_time.tv_sec += 10;
be9751
+            pthread_cond_timedwait(&diskmon_cvar, &diskmon_mutex, &current_time);
be9751
+            pthread_mutex_unlock(&diskmon_mutex);
be9751
             /*
be9751
              *  We need to subtract from disk_space to account for the
be9751
              *  logging we just did, it doesn't hurt if we subtract a
be9751
@@ -622,7 +627,7 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
be9751
                     "Disk space on (%s) is too far below the threshold(%" PRIu64 " bytes).  "
be9751
                     "Waiting %d minutes for disk space to be cleaned up before shutting slapd down...\n",
be9751
                     dirstr, threshold, (grace_period / 60));
be9751
-            start = slapi_current_utc_time();
be9751
+            start = slapi_current_rel_time_t();
be9751
             now = start;
be9751
             while ((now - start) < grace_period) {
be9751
                 if (g_get_shutdown()) {
be9751
@@ -685,7 +690,7 @@ disk_monitoring_thread(void *nothing __attribute__((unused)))
be9751
                     immediate_shutdown = 1;
be9751
                     goto cleanup;
be9751
                 }
be9751
-                now = slapi_current_utc_time();
be9751
+                now = slapi_current_rel_time_t();
be9751
             }
be9751
 
be9751
             if (ok_now) {
be9751
@@ -1005,21 +1010,34 @@ slapd_daemon(daemon_ports_t *ports)
be9751
      *  and the monitoring thread.
be9751
      */
be9751
     if (config_get_disk_monitoring()) {
be9751
-        if ((diskmon_mutex = PR_NewLock()) == NULL) {
be9751
+        pthread_condattr_t condAttr;
be9751
+        int rc = 0;
be9751
+
be9751
+        if ((rc = pthread_mutex_init(&diskmon_mutex, NULL)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "slapd_daemon", "cannot create new lock.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            g_set_shutdown(SLAPI_SHUTDOWN_EXIT);
be9751
+        }
be9751
+        if ((rc = pthread_condattr_init(&condAttr)) != 0) {
be9751
             slapi_log_err(SLAPI_LOG_ERR, "slapd_daemon",
be9751
-                          "Cannot create new lock for disk space monitoring. " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
-                          PR_GetError(), slapd_pr_strerror(PR_GetError()));
be9751
+                          "cannot create new condition attribute variable.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
             g_set_shutdown(SLAPI_SHUTDOWN_EXIT);
be9751
         }
be9751
-        if (diskmon_mutex) {
be9751
-            if ((diskmon_cvar = PR_NewCondVar(diskmon_mutex)) == NULL) {
be9751
-                slapi_log_err(SLAPI_LOG_EMERG, "slapd_daemon",
be9751
-                              "Cannot create new condition variable for disk space monitoring. " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
-                              PR_GetError(), slapd_pr_strerror(PR_GetError()));
be9751
-                g_set_shutdown(SLAPI_SHUTDOWN_EXIT);
be9751
-            }
be9751
+        if ((rc = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "slapd_daemon",
be9751
+                          "cannot set condition attr clock.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            g_set_shutdown(SLAPI_SHUTDOWN_EXIT);
be9751
+        }
be9751
+        if ((rc = pthread_cond_init(&diskmon_cvar, &condAttr)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "slapd_daemon",
be9751
+                          "cannot create new condition variable.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            g_set_shutdown(SLAPI_SHUTDOWN_EXIT);
be9751
         }
be9751
-        if (diskmon_mutex && diskmon_cvar) {
be9751
+        pthread_condattr_destroy(&condAttr);
be9751
+        if (rc == 0) {
be9751
             disk_thread_p = PR_CreateThread(PR_SYSTEM_THREAD,
be9751
                                             (VFP)(void *)disk_monitoring_thread, NULL,
be9751
                                             PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
be9751
@@ -1508,7 +1526,7 @@ static void
be9751
 handle_pr_read_ready(Connection_Table *ct, PRIntn num_poll __attribute__((unused)))
be9751
 {
be9751
     Connection *c;
be9751
-    time_t curtime = slapi_current_utc_time();
be9751
+    time_t curtime = slapi_current_rel_time_t();
be9751
 
be9751
 #if LDAP_ERROR_LOGGING
be9751
     if (slapd_ldap_debug & LDAP_DEBUG_CONNS) {
be9751
@@ -2884,8 +2902,8 @@ void
be9751
 disk_monitoring_stop(void)
be9751
 {
be9751
     if (disk_thread_p) {
be9751
-        PR_Lock(diskmon_mutex);
be9751
-        PR_NotifyCondVar(diskmon_cvar);
be9751
-        PR_Unlock(diskmon_mutex);
be9751
+        pthread_mutex_lock(&diskmon_mutex);
be9751
+        pthread_cond_signal(&diskmon_cvar);
be9751
+        pthread_mutex_unlock(&diskmon_mutex);
be9751
     }
be9751
 }
be9751
diff --git a/ldap/servers/slapd/eventq.c b/ldap/servers/slapd/eventq.c
be9751
index a491acd0a..e1900724f 100644
be9751
--- a/ldap/servers/slapd/eventq.c
be9751
+++ b/ldap/servers/slapd/eventq.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -52,8 +52,8 @@ typedef struct _slapi_eq_context
be9751
  */
be9751
 typedef struct _event_queue
be9751
 {
be9751
-    PRLock *eq_lock;
be9751
-    PRCondVar *eq_cv;
be9751
+    pthread_mutex_t eq_lock;
be9751
+    pthread_cond_t eq_cv;
be9751
     slapi_eq_context *eq_queue;
be9751
 } event_queue;
be9751
 
be9751
@@ -74,8 +74,8 @@ static PRThread *eq_loop_tid = NULL;
be9751
 static int eq_running = 0;
be9751
 static int eq_stopped = 0;
be9751
 static int eq_initialized = 0;
be9751
-PRLock *ss_lock = NULL;
be9751
-PRCondVar *ss_cv = NULL;
be9751
+static pthread_mutex_t ss_lock;
be9751
+static pthread_cond_t ss_cv;
be9751
 PRCallOnceType init_once = {0};
be9751
 
be9751
 /* Forward declarations */
be9751
@@ -170,7 +170,7 @@ slapi_eq_cancel(Slapi_Eq_Context ctx)
be9751
 
be9751
     PR_ASSERT(eq_initialized);
be9751
     if (!eq_stopped) {
be9751
-        PR_Lock(eq->eq_lock);
be9751
+        pthread_mutex_lock(&(eq->eq_lock));
be9751
         p = &(eq->eq_queue);
be9751
         while (!found && *p != NULL) {
be9751
             if ((*p)->ec_id == ctx) {
be9751
@@ -182,7 +182,7 @@ slapi_eq_cancel(Slapi_Eq_Context ctx)
be9751
                 p = &((*p)->ec_next);
be9751
             }
be9751
         }
be9751
-        PR_Unlock(eq->eq_lock);
be9751
+        pthread_mutex_unlock(&(eq->eq_lock));
be9751
     }
be9751
     slapi_log_err(SLAPI_LOG_HOUSE, NULL,
be9751
                   "cancellation of event id %p requested: %s\n",
be9751
@@ -223,7 +223,7 @@ eq_enqueue(slapi_eq_context *newec)
be9751
     slapi_eq_context **p;
be9751
 
be9751
     PR_ASSERT(NULL != newec);
be9751
-    PR_Lock(eq->eq_lock);
be9751
+    pthread_mutex_lock(&(eq->eq_lock));
be9751
     /* Insert <newec> in order (sorted by start time) in the list */
be9751
     for (p = &(eq->eq_queue); *p != NULL; p = &((*p)->ec_next)) {
be9751
         if ((*p)->ec_when > newec->ec_when) {
be9751
@@ -236,8 +236,8 @@ eq_enqueue(slapi_eq_context *newec)
be9751
         newec->ec_next = NULL;
be9751
     }
be9751
     *p = newec;
be9751
-    PR_NotifyCondVar(eq->eq_cv); /* wake up scheduler thread */
be9751
-    PR_Unlock(eq->eq_lock);
be9751
+    pthread_cond_signal(&(eq->eq_cv)); /* wake up scheduler thread */
be9751
+    pthread_mutex_unlock(&(eq->eq_lock));
be9751
 }
be9751
 
be9751
 
be9751
@@ -251,12 +251,12 @@ eq_dequeue(time_t now)
be9751
 {
be9751
     slapi_eq_context *retptr = NULL;
be9751
 
be9751
-    PR_Lock(eq->eq_lock);
be9751
+    pthread_mutex_lock(&(eq->eq_lock));
be9751
     if (NULL != eq->eq_queue && eq->eq_queue->ec_when <= now) {
be9751
         retptr = eq->eq_queue;
be9751
         eq->eq_queue = retptr->ec_next;
be9751
     }
be9751
-    PR_Unlock(eq->eq_lock);
be9751
+    pthread_mutex_unlock(&(eq->eq_lock));
be9751
     return retptr;
be9751
 }
be9751
 
be9751
@@ -271,7 +271,7 @@ static void
be9751
 eq_call_all(void)
be9751
 {
be9751
     slapi_eq_context *p;
be9751
-    time_t curtime = slapi_current_utc_time();
be9751
+    time_t curtime = slapi_current_rel_time_t();
be9751
 
be9751
     while ((p = eq_dequeue(curtime)) != NULL) {
be9751
         /* Call the scheduled function */
be9751
@@ -299,34 +299,35 @@ static void
be9751
 eq_loop(void *arg __attribute__((unused)))
be9751
 {
be9751
     while (eq_running) {
be9751
-        time_t curtime = slapi_current_utc_time();
be9751
-        PRIntervalTime timeout;
be9751
+        time_t curtime = slapi_current_rel_time_t();
be9751
         int until;
be9751
-        PR_Lock(eq->eq_lock);
be9751
+
be9751
+        pthread_mutex_lock(&(eq->eq_lock));
be9751
         while (!((NULL != eq->eq_queue) && (eq->eq_queue->ec_when <= curtime))) {
be9751
             if (!eq_running) {
be9751
-                PR_Unlock(eq->eq_lock);
be9751
+                pthread_mutex_unlock(&(eq->eq_lock));
be9751
                 goto bye;
be9751
             }
be9751
             /* Compute new timeout */
be9751
             if (NULL != eq->eq_queue) {
be9751
+                struct timespec current_time = slapi_current_rel_time_hr();
be9751
                 until = eq->eq_queue->ec_when - curtime;
be9751
-                timeout = PR_SecondsToInterval(until);
be9751
+                current_time.tv_sec += until;
be9751
+                pthread_cond_timedwait(&eq->eq_cv, &eq->eq_lock, &current_time);
be9751
             } else {
be9751
-                timeout = PR_INTERVAL_NO_TIMEOUT;
be9751
+                pthread_cond_wait(&eq->eq_cv, &eq->eq_lock);
be9751
             }
be9751
-            PR_WaitCondVar(eq->eq_cv, timeout);
be9751
-            curtime = slapi_current_utc_time();
be9751
+            curtime = slapi_current_rel_time_t();
be9751
         }
be9751
         /* There is some work to do */
be9751
-        PR_Unlock(eq->eq_lock);
be9751
+        pthread_mutex_unlock(&(eq->eq_lock));
be9751
         eq_call_all();
be9751
     }
be9751
 bye:
be9751
     eq_stopped = 1;
be9751
-    PR_Lock(ss_lock);
be9751
-    PR_NotifyAllCondVar(ss_cv);
be9751
-    PR_Unlock(ss_lock);
be9751
+    pthread_mutex_lock(&ss_lock);
be9751
+    pthread_cond_broadcast(&ss_cv);
be9751
+    pthread_mutex_unlock(&ss_lock);
be9751
 }
be9751
 
be9751
 
be9751
@@ -336,23 +337,50 @@ bye:
be9751
 static PRStatus
be9751
 eq_create(void)
be9751
 {
be9751
-    PR_ASSERT(NULL == eq->eq_lock);
be9751
-    if ((eq->eq_lock = PR_NewLock()) == NULL) {
be9751
-        slapi_log_err(SLAPI_LOG_ERR, "eq_create", "PR_NewLock failed\n");
be9751
+    pthread_condattr_t condAttr;
be9751
+    int rc = 0;
be9751
+
be9751
+    /* Init the eventq mutex and cond var */
be9751
+    if (pthread_mutex_init(&eq->eq_lock, NULL) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create",
be9751
+                      "Failed to create lock: error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         exit(1);
be9751
     }
be9751
-    if ((eq->eq_cv = PR_NewCondVar(eq->eq_lock)) == NULL) {
be9751
-        slapi_log_err(SLAPI_LOG_ERR, "eq_create", "PR_NewCondVar failed\n");
be9751
+    if ((rc = pthread_condattr_init(&condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create",
be9751
+                      "Failed to create new condition attribute variable. error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         exit(1);
be9751
     }
be9751
-    if ((ss_lock = PR_NewLock()) == NULL) {
be9751
-        slapi_log_err(SLAPI_LOG_ERR, "eq_create", "PR_NewLock failed\n");
be9751
+    if ((rc = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create",
be9751
+                      "Cannot set condition attr clock. error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         exit(1);
be9751
     }
be9751
-    if ((ss_cv = PR_NewCondVar(ss_lock)) == NULL) {
be9751
-        slapi_log_err(SLAPI_LOG_ERR, "eq_create", "PR_NewCondVar failed\n");
be9751
+    if ((rc = pthread_cond_init(&eq->eq_cv, &condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create",
be9751
+                      "Failed to create new condition variable. error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
         exit(1);
be9751
     }
be9751
+
be9751
+    /* Init the "ss" mutex and condition var */
be9751
+    if (pthread_mutex_init(&ss_lock, NULL) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create",
be9751
+                      "Failed to create ss lock: error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+        exit(1);
be9751
+    }
be9751
+    if ((rc = pthread_cond_init(&ss_cv, &condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create",
be9751
+                      "Failed to create new ss condition variable. error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+        exit(1);
be9751
+    }
be9751
+    pthread_condattr_destroy(&condAttr); /* no longer needed */
be9751
+
be9751
     eq->eq_queue = NULL;
be9751
     eq_initialized = 1;
be9751
     return PR_SUCCESS;
be9751
@@ -411,7 +439,7 @@ eq_stop()
be9751
 {
be9751
     slapi_eq_context *p, *q;
be9751
 
be9751
-    if (NULL == eq || NULL == eq->eq_lock) { /* never started */
be9751
+    if (NULL == eq) { /* never started */
be9751
         eq_stopped = 1;
be9751
         return;
be9751
     }
be9751
@@ -423,12 +451,24 @@ eq_stop()
be9751
      * it acknowledges by setting eq_stopped.
be9751
      */
be9751
     while (!eq_stopped) {
be9751
-        PR_Lock(eq->eq_lock);
be9751
-        PR_NotifyAllCondVar(eq->eq_cv);
be9751
-        PR_Unlock(eq->eq_lock);
be9751
-        PR_Lock(ss_lock);
be9751
-        PR_WaitCondVar(ss_cv, PR_MillisecondsToInterval(100));
be9751
-        PR_Unlock(ss_lock);
be9751
+        struct timespec current_time = {0};
be9751
+
be9751
+        pthread_mutex_lock(&(eq->eq_lock));
be9751
+        pthread_cond_broadcast(&(eq->eq_cv));
be9751
+        pthread_mutex_unlock(&(eq->eq_lock));
be9751
+
be9751
+        pthread_mutex_lock(&ss_lock);
be9751
+        clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+        if (current_time.tv_nsec + 100000000 > 1000000000) {
be9751
+            /* nanoseconds will overflow, adjust the seconds and nanoseconds */
be9751
+            current_time.tv_sec++;
be9751
+            /* Add the remainder to nanoseconds */
be9751
+            current_time.tv_nsec = (current_time.tv_nsec + 100000000) - 1000000000;
be9751
+        } else {
be9751
+            current_time.tv_nsec += 100000000; /* 100 ms */
be9751
+        }
be9751
+        pthread_cond_timedwait(&ss_cv, &ss_lock, &current_time);
be9751
+        pthread_mutex_unlock(&ss_lock);
be9751
     }
be9751
     (void)PR_JoinThread(eq_loop_tid);
be9751
     /*
be9751
@@ -438,7 +478,7 @@ eq_stop()
be9751
      * The downside is that the event queue can't be stopped and restarted
be9751
      * easily.
be9751
      */
be9751
-    PR_Lock(eq->eq_lock);
be9751
+    pthread_mutex_lock(&(eq->eq_lock));
be9751
     p = eq->eq_queue;
be9751
     while (p != NULL) {
be9751
         q = p->ec_next;
be9751
@@ -449,7 +489,7 @@ eq_stop()
be9751
          */
be9751
         p = q;
be9751
     }
be9751
-    PR_Unlock(eq->eq_lock);
be9751
+    pthread_mutex_unlock(&(eq->eq_lock));
be9751
     slapi_log_err(SLAPI_LOG_HOUSE, NULL, "event queue services have shut down\n");
be9751
 }
be9751
 
be9751
@@ -463,17 +503,17 @@ slapi_eq_get_arg(Slapi_Eq_Context ctx)
be9751
 
be9751
     PR_ASSERT(eq_initialized);
be9751
     if (eq && !eq_stopped) {
be9751
-        PR_Lock(eq->eq_lock);
be9751
+        pthread_mutex_lock(&(eq->eq_lock));
be9751
         p = &(eq->eq_queue);
be9751
         while (p && *p != NULL) {
be9751
             if ((*p)->ec_id == ctx) {
be9751
-                PR_Unlock(eq->eq_lock);
be9751
+                pthread_mutex_unlock(&(eq->eq_lock));
be9751
                 return (*p)->ec_arg;
be9751
             } else {
be9751
                 p = &((*p)->ec_next);
be9751
             }
be9751
         }
be9751
-        PR_Unlock(eq->eq_lock);
be9751
+        pthread_mutex_unlock(&(eq->eq_lock));
be9751
     }
be9751
     return NULL;
be9751
 }
be9751
diff --git a/ldap/servers/slapd/house.c b/ldap/servers/slapd/house.c
be9751
index ff139a4a5..ac1d94f26 100644
be9751
--- a/ldap/servers/slapd/house.c
be9751
+++ b/ldap/servers/slapd/house.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -23,17 +23,15 @@
be9751
 #define SLAPD_HOUSEKEEPING_INTERVAL 30 /* seconds */
be9751
 
be9751
 static PRThread *housekeeping_tid = NULL;
be9751
-static PRLock *housekeeping_mutex = NULL;
be9751
-static PRCondVar *housekeeping_cvar = NULL;
be9751
+static pthread_mutex_t housekeeping_mutex;
be9751
+static pthread_cond_t housekeeping_cvar;
be9751
 
be9751
 
be9751
 static void
be9751
 housecleaning(void *cur_time __attribute__((unused)))
be9751
 {
be9751
-    int interval;
be9751
-
be9751
-    interval = PR_SecondsToInterval(SLAPD_HOUSEKEEPING_INTERVAL);
be9751
     while (!g_get_shutdown()) {
be9751
+        struct timespec current_time = {0};
be9751
         /*
be9751
          * Looks simple, but could potentially take a long time.
be9751
          */
be9751
@@ -42,9 +40,15 @@ housecleaning(void *cur_time __attribute__((unused)))
be9751
         if (g_get_shutdown()) {
be9751
             break;
be9751
         }
be9751
-        PR_Lock(housekeeping_mutex);
be9751
-        PR_WaitCondVar(housekeeping_cvar, interval);
be9751
-        PR_Unlock(housekeeping_mutex);
be9751
+
be9751
+        /* get the current monotonic time and add our interval */
be9751
+        clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+        current_time.tv_sec += SLAPD_HOUSEKEEPING_INTERVAL;
be9751
+
be9751
+        /* Now we wait... */
be9751
+        pthread_mutex_lock(&housekeeping_mutex);
be9751
+        pthread_cond_timedwait(&housekeeping_cvar, &housekeeping_mutex, &current_time);
be9751
+        pthread_mutex_unlock(&housekeeping_mutex);
be9751
     }
be9751
 }
be9751
 
be9751
@@ -52,20 +56,31 @@ PRThread *
be9751
 housekeeping_start(time_t cur_time, void *arg __attribute__((unused)))
be9751
 {
be9751
     static time_t thread_start_time;
be9751
+    pthread_condattr_t condAttr;
be9751
+    int rc = 0;
be9751
 
be9751
     if (housekeeping_tid) {
be9751
         return housekeeping_tid;
be9751
     }
be9751
 
be9751
-    if ((housekeeping_mutex = PR_NewLock()) == NULL) {
be9751
+    if ((rc = pthread_mutex_init(&housekeeping_mutex, NULL)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "housekeeping_start",
be9751
+                      "housekeeping cannot create new lock.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+    } else if ((rc = pthread_condattr_init(&condAttr)) != 0) {
be9751
         slapi_log_err(SLAPI_LOG_ERR, "housekeeping_start",
be9751
-                      "housekeeping cannot create new lock. " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
-                      PR_GetError(), slapd_pr_strerror(PR_GetError()));
be9751
-    } else if ((housekeeping_cvar = PR_NewCondVar(housekeeping_mutex)) == NULL) {
be9751
+                      "housekeeping cannot create new condition attribute variable.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+    } else if ((rc = pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC)) != 0) {
be9751
         slapi_log_err(SLAPI_LOG_ERR, "housekeeping_start",
be9751
-                      "housekeeping cannot create new condition variable. " SLAPI_COMPONENT_NAME_NSPR " error %d (%s)\n",
be9751
-                      PR_GetError(), slapd_pr_strerror(PR_GetError()));
be9751
+                      "housekeeping cannot set condition attr clock.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
+    } else if ((rc = pthread_cond_init(&housekeeping_cvar, &condAttr)) != 0) {
be9751
+        slapi_log_err(SLAPI_LOG_ERR, "housekeeping_start",
be9751
+                      "housekeeping cannot create new condition variable.  error %d (%s)\n",
be9751
+                      rc, strerror(rc));
be9751
     } else {
be9751
+        pthread_condattr_destroy(&condAttr); /* no longer needed */
be9751
         thread_start_time = cur_time;
be9751
         if ((housekeeping_tid = PR_CreateThread(PR_USER_THREAD,
be9751
                                                 (VFP)housecleaning, (void *)&thread_start_time,
be9751
@@ -84,9 +99,16 @@ void
be9751
 housekeeping_stop()
be9751
 {
be9751
     if (housekeeping_tid) {
be9751
-        PR_Lock(housekeeping_mutex);
be9751
-        PR_NotifyCondVar(housekeeping_cvar);
be9751
-        PR_Unlock(housekeeping_mutex);
be9751
+        /* Notify the thread */
be9751
+        pthread_mutex_lock(&housekeeping_mutex);
be9751
+        pthread_cond_signal(&housekeeping_cvar);
be9751
+        pthread_mutex_unlock(&housekeeping_mutex);
be9751
+
be9751
+        /* Wait for the thread to finish */
be9751
         (void)PR_JoinThread(housekeeping_tid);
be9751
+
be9751
+        /* Clean it all up */
be9751
+        pthread_mutex_destroy(&housekeeping_mutex);
be9751
+        pthread_cond_destroy(&housekeeping_cvar);
be9751
     }
be9751
 }
be9751
diff --git a/ldap/servers/slapd/libmakefile b/ldap/servers/slapd/libmakefile
be9751
index b3ecabc29..3559c0104 100644
be9751
--- a/ldap/servers/slapd/libmakefile
be9751
+++ b/ldap/servers/slapd/libmakefile
be9751
@@ -46,7 +46,7 @@ LIBSLAPD_OBJS=plugin_role.o getfilelist.o libglobs.o log.o ch_malloc.o entry.o p
be9751
 	filter.o filtercmp.o filterentry.o operation.o schemaparse.o pw.o \
be9751
 	backend.o defbackend.o ava.o charray.o regex.o \
be9751
 	str2filter.o dynalib.o plugin.o plugin_syntax.o plugin_mr.o \
be9751
-	slapi2nspr.o rwlock.o control.o plugin_internal_op.o \
be9751
+	slapi2runtime.o rwlock.o control.o plugin_internal_op.o \
be9751
 	result.o pw_retry.o agtmmap.o referral.o snmp_collator.o util.o \
be9751
 	dse.o errormap.o computed.o match.o fileio.o \
be9751
 	generation.o localhost.o ssl.o factory.o auditlog.o \
be9751
diff --git a/ldap/servers/slapd/psearch.c b/ldap/servers/slapd/psearch.c
be9751
index 6820a5d75..c60e6a8ed 100644
be9751
--- a/ldap/servers/slapd/psearch.c
be9751
+++ b/ldap/servers/slapd/psearch.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -59,10 +59,10 @@ typedef struct _psearch
be9751
  */
be9751
 typedef struct _psearch_list
be9751
 {
be9751
-    Slapi_RWLock *pl_rwlock; /* R/W lock struct to serialize access */
be9751
-    PSearch *pl_head;        /* Head of list */
be9751
-    PRLock *pl_cvarlock;     /* Lock for cvar */
be9751
-    PRCondVar *pl_cvar;      /* ps threads sleep on this */
be9751
+    Slapi_RWLock *pl_rwlock;     /* R/W lock struct to serialize access */
be9751
+    PSearch *pl_head;            /* Head of list */
be9751
+    pthread_mutex_t pl_cvarlock; /* Lock for cvar */
be9751
+    pthread_cond_t pl_cvar;      /* ps threads sleep on this */
be9751
 } PSearch_List;
be9751
 
be9751
 /*
be9751
@@ -101,21 +101,26 @@ void
be9751
 ps_init_psearch_system()
be9751
 {
be9751
     if (!PS_IS_INITIALIZED()) {
be9751
+        int32_t rc = 0;
be9751
+
be9751
         psearch_list = (PSearch_List *)slapi_ch_calloc(1, sizeof(PSearch_List));
be9751
         if ((psearch_list->pl_rwlock = slapi_new_rwlock()) == NULL) {
be9751
             slapi_log_err(SLAPI_LOG_ERR, "ps_init_psearch_system", "Cannot initialize lock structure.  "
be9751
                                                                    "The server is terminating.\n");
be9751
             exit(-1);
be9751
         }
be9751
-        if ((psearch_list->pl_cvarlock = PR_NewLock()) == NULL) {
be9751
-            slapi_log_err(SLAPI_LOG_ERR, "ps_init_psearch_system", "Cannot create new lock.  "
be9751
-                                                                   "The server is terminating.\n");
be9751
-            exit(-1);
be9751
+
be9751
+        if ((rc = pthread_mutex_init(&(psearch_list->pl_cvarlock), NULL)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "ps_init_psearch_system",
be9751
+                          "Cannot create new lock.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            exit(1);
be9751
         }
be9751
-        if ((psearch_list->pl_cvar = PR_NewCondVar(psearch_list->pl_cvarlock)) == NULL) {
be9751
-            slapi_log_err(SLAPI_LOG_ERR, "ps_init_psearch_system", "Cannot create new condition variable.  "
be9751
-                                                                   "The server is terminating.\n");
be9751
-            exit(-1);
be9751
+        if ((rc = pthread_cond_init(&(psearch_list->pl_cvar), NULL)) != 0) {
be9751
+            slapi_log_err(SLAPI_LOG_ERR, "housekeeping_start",
be9751
+                          "housekeeping cannot create new condition variable.  error %d (%s)\n",
be9751
+                          rc, strerror(rc));
be9751
+            exit(1);
be9751
         }
be9751
         psearch_list->pl_head = NULL;
be9751
     }
be9751
@@ -288,7 +293,7 @@ ps_send_results(void *arg)
be9751
                       pb_conn->c_connid, pb_op ? pb_op->o_opid : -1);
be9751
     }
be9751
 
be9751
-    PR_Lock(psearch_list->pl_cvarlock);
be9751
+    pthread_mutex_lock(&(psearch_list->pl_cvarlock));
be9751
 
be9751
     while ((conn_acq_flag == 0) && slapi_atomic_load_64(&(ps->ps_complete), __ATOMIC_ACQUIRE) == 0) {
be9751
         /* Check for an abandoned operation */
be9751
@@ -300,7 +305,7 @@ ps_send_results(void *arg)
be9751
         }
be9751
         if (NULL == ps->ps_eq_head) {
be9751
             /* Nothing to do */
be9751
-            PR_WaitCondVar(psearch_list->pl_cvar, PR_INTERVAL_NO_TIMEOUT);
be9751
+            pthread_cond_wait(&(psearch_list->pl_cvar), &(psearch_list->pl_cvarlock));
be9751
         } else {
be9751
             /* dequeue the item */
be9751
             int attrsonly;
be9751
@@ -330,17 +335,17 @@ ps_send_results(void *arg)
be9751
             }
be9751
 
be9751
             /*
be9751
-         * Send the result.  Since send_ldap_search_entry can block for
be9751
-         * up to 30 minutes, we relinquish all locks before calling it.
be9751
-         */
be9751
-            PR_Unlock(psearch_list->pl_cvarlock);
be9751
+             * Send the result.  Since send_ldap_search_entry can block for
be9751
+             * up to 30 minutes, we relinquish all locks before calling it.
be9751
+             */
be9751
+            pthread_mutex_unlock(&(psearch_list->pl_cvarlock));
be9751
 
be9751
             /*
be9751
-         * The entry is in the right scope and matches the filter
be9751
-         * but we need to redo the filter test here to check access
be9751
-         * controls. See the comments at the slapi_filter_test()
be9751
-         * call in ps_service_persistent_searches().
be9751
-        */
be9751
+             * The entry is in the right scope and matches the filter
be9751
+             * but we need to redo the filter test here to check access
be9751
+             * controls. See the comments at the slapi_filter_test()
be9751
+             * call in ps_service_persistent_searches().
be9751
+            */
be9751
             slapi_pblock_get(ps->ps_pblock, SLAPI_SEARCH_FILTER, &f);
be9751
 
be9751
             /* See if the entry meets the filter and ACL criteria */
be9751
@@ -358,13 +363,13 @@ ps_send_results(void *arg)
be9751
                 }
be9751
             }
be9751
 
be9751
-            PR_Lock(psearch_list->pl_cvarlock);
be9751
+            pthread_mutex_lock(&(psearch_list->pl_cvarlock));
be9751
 
be9751
             /* Deallocate our wrapper for this entry */
be9751
             pe_ch_free(&peq;;
be9751
         }
be9751
     }
be9751
-    PR_Unlock(psearch_list->pl_cvarlock);
be9751
+    pthread_mutex_unlock(&(psearch_list->pl_cvarlock));
be9751
     ps_remove(ps);
be9751
 
be9751
     /* indicate the end of search */
be9751
@@ -474,9 +479,9 @@ void
be9751
 ps_wakeup_all()
be9751
 {
be9751
     if (PS_IS_INITIALIZED()) {
be9751
-        PR_Lock(psearch_list->pl_cvarlock);
be9751
-        PR_NotifyAllCondVar(psearch_list->pl_cvar);
be9751
-        PR_Unlock(psearch_list->pl_cvarlock);
be9751
+        pthread_mutex_lock(&(psearch_list->pl_cvarlock));
be9751
+        pthread_cond_broadcast(&(psearch_list->pl_cvar));
be9751
+        pthread_mutex_unlock(&(psearch_list->pl_cvarlock));
be9751
     }
be9751
 }
be9751
 
be9751
diff --git a/ldap/servers/slapd/regex.c b/ldap/servers/slapd/regex.c
be9751
index 97249a4c5..a17c354fd 100644
be9751
--- a/ldap/servers/slapd/regex.c
be9751
+++ b/ldap/servers/slapd/regex.c
be9751
@@ -72,7 +72,7 @@ int
be9751
 slapi_re_exec(Slapi_Regex *re_handle, const char *subject, time_t time_up)
be9751
 {
be9751
     int rc;
be9751
-    time_t curtime = slapi_current_utc_time();
be9751
+    time_t curtime = slapi_current_rel_time_t();
be9751
 
be9751
     if (NULL == re_handle || NULL == re_handle->re_pcre || NULL == subject) {
be9751
         return LDAP_PARAM_ERROR;
be9751
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
be9751
index f9ac8b46c..55ded5eb8 100644
be9751
--- a/ldap/servers/slapd/slapi-plugin.h
be9751
+++ b/ldap/servers/slapd/slapi-plugin.h
be9751
@@ -6086,6 +6086,7 @@ Slapi_CondVar *slapi_new_condvar(Slapi_Mutex *mutex);
be9751
 void slapi_destroy_condvar(Slapi_CondVar *cvar);
be9751
 int slapi_wait_condvar(Slapi_CondVar *cvar, struct timeval *timeout);
be9751
 int slapi_notify_condvar(Slapi_CondVar *cvar, int notify_all);
be9751
+int slapi_wait_condvar_pt(Slapi_CondVar *cvar, Slapi_Mutex *mutex, struct timeval *timeout);
be9751
 
be9751
 /**
be9751
  * Creates a new read/write lock
be9751
@@ -6777,6 +6778,12 @@ struct timespec slapi_current_time_hr(void);
be9751
  * \return timespec of the current monotonic time.
be9751
  */
be9751
 struct timespec slapi_current_rel_time_hr(void);
be9751
+/**
be9751
+ * Returns the current system time as a hr clock
be9751
+ *
be9751
+ * \return time_t of the current monotonic time.
be9751
+ */
be9751
+time_t slapi_current_rel_time_t(void);
be9751
 /**
be9751
  * Returns the current system time as a hr clock in UTC timezone.
be9751
  * This clock adjusts with ntp steps, and should NOT be
be9751
diff --git a/ldap/servers/slapd/slapi2nspr.c b/ldap/servers/slapd/slapi2runtime.c
be9751
similarity index 69%
be9751
rename from ldap/servers/slapd/slapi2nspr.c
be9751
rename to ldap/servers/slapd/slapi2runtime.c
be9751
index 232d1599e..85dc4c9a8 100644
be9751
--- a/ldap/servers/slapd/slapi2nspr.c
be9751
+++ b/ldap/servers/slapd/slapi2runtime.c
be9751
@@ -1,6 +1,6 @@
be9751
 /** BEGIN COPYRIGHT BLOCK
be9751
  * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
be9751
- * Copyright (C) 2005 Red Hat, Inc.
be9751
+ * Copyright (C) 2020 Red Hat, Inc.
be9751
  * All rights reserved.
be9751
  *
be9751
  * License: GPL (version 3 or any later version).
be9751
@@ -14,6 +14,8 @@
be9751
 /*
be9751
  * slapi2nspr.c - expose a subset of the NSPR20/21 API to SLAPI plugin writers
be9751
  *
be9751
+ * Also include slapi2pthread functions
be9751
+ *
be9751
  */
be9751
 
be9751
 #include "slap.h"
be9751
@@ -44,47 +46,50 @@
be9751
 Slapi_Mutex *
be9751
 slapi_new_mutex(void)
be9751
 {
be9751
-    return ((Slapi_Mutex *)PR_NewLock());
be9751
+    pthread_mutex_t *new_mutex = (pthread_mutex_t *)slapi_ch_calloc(1, sizeof(pthread_mutex_t));
be9751
+    pthread_mutex_init(new_mutex, NULL);
be9751
+    return ((Slapi_Mutex *)new_mutex);
be9751
 }
be9751
 
be9751
-
be9751
 /*
be9751
  * Function: slapi_destroy_mutex
be9751
- * Description: behaves just like PR_DestroyLock().
be9751
+ * Description: behaves just like pthread_mutex_destroy().
be9751
  */
be9751
 void
be9751
 slapi_destroy_mutex(Slapi_Mutex *mutex)
be9751
 {
be9751
     if (mutex != NULL) {
be9751
-        PR_DestroyLock((PRLock *)mutex);
be9751
+        pthread_mutex_destroy((pthread_mutex_t *)mutex);
be9751
+        slapi_ch_free((void **)&mutex);
be9751
     }
be9751
 }
be9751
 
be9751
 
be9751
 /*
be9751
  * Function: slapi_lock_mutex
be9751
- * Description: behaves just like PR_Lock().
be9751
+ * Description: behaves just like pthread_mutex_lock().
be9751
  */
be9751
-void
be9751
+inline void __attribute__((always_inline))
be9751
 slapi_lock_mutex(Slapi_Mutex *mutex)
be9751
 {
be9751
     if (mutex != NULL) {
be9751
-        PR_Lock((PRLock *)mutex);
be9751
+        pthread_mutex_lock((pthread_mutex_t *)mutex);
be9751
     }
be9751
 }
be9751
 
be9751
 
be9751
 /*
be9751
  * Function: slapi_unlock_mutex
be9751
- * Description: behaves just like PR_Unlock().
be9751
+ * Description: behaves just like pthread_mutex_unlock().
be9751
  * Returns:
be9751
  *    non-zero if mutex was successfully unlocked.
be9751
  *    0 if mutex is NULL or is not locked by the calling thread.
be9751
  */
be9751
-int
be9751
+inline int __attribute__((always_inline))
be9751
 slapi_unlock_mutex(Slapi_Mutex *mutex)
be9751
 {
be9751
-    if (mutex == NULL || PR_Unlock((PRLock *)mutex) == PR_FAILURE) {
be9751
+    PR_ASSERT(mutex != NULL);
be9751
+    if (mutex == NULL || pthread_mutex_unlock((pthread_mutex_t *)mutex) != 0) {
be9751
         return (0);
be9751
     } else {
be9751
         return (1);
be9751
@@ -98,13 +103,18 @@ slapi_unlock_mutex(Slapi_Mutex *mutex)
be9751
  * Returns: pointer to a new condition variable (NULL if one can't be created).
be9751
  */
be9751
 Slapi_CondVar *
be9751
-slapi_new_condvar(Slapi_Mutex *mutex)
be9751
+slapi_new_condvar(Slapi_Mutex *mutex __attribute__((unused)))
be9751
 {
be9751
-    if (mutex == NULL) {
be9751
-        return (NULL);
be9751
-    }
be9751
+    pthread_cond_t *new_cv = (pthread_cond_t *)slapi_ch_calloc(1, sizeof(pthread_cond_t));
be9751
+    pthread_condattr_t condAttr;
be9751
+
be9751
+    pthread_condattr_init(&condAttr);
be9751
+    pthread_condattr_setclock(&condAttr, CLOCK_MONOTONIC);
be9751
+    pthread_cond_init(new_cv, &condAttr);
be9751
+    /* Done with the cond attr, it's safe to destroy it */
be9751
+    pthread_condattr_destroy(&condAttr);
be9751
 
be9751
-    return ((Slapi_CondVar *)PR_NewCondVar((PRLock *)mutex));
be9751
+    return (Slapi_CondVar *)new_cv;
be9751
 }
be9751
 
be9751
 
be9751
@@ -116,7 +126,8 @@ void
be9751
 slapi_destroy_condvar(Slapi_CondVar *cvar)
be9751
 {
be9751
     if (cvar != NULL) {
be9751
-        PR_DestroyCondVar((PRCondVar *)cvar);
be9751
+        pthread_cond_destroy((pthread_cond_t *)cvar);
be9751
+        slapi_ch_free((void **)&cvar);
be9751
     }
be9751
 }
be9751
 
be9751
@@ -134,23 +145,35 @@ slapi_destroy_condvar(Slapi_CondVar *cvar)
be9751
 int
be9751
 slapi_wait_condvar(Slapi_CondVar *cvar, struct timeval *timeout)
be9751
 {
be9751
-    PRIntervalTime prit;
be9751
+    /* deprecated in favor of slapi_wait_condvar_pt() which requires that the
be9751
+     * mutex be passed in */
be9751
+    return (0);
be9751
+}
be9751
+
be9751
+int
be9751
+slapi_wait_condvar_pt(Slapi_CondVar *cvar, Slapi_Mutex *mutex, struct timeval *timeout)
be9751
+{
be9751
+    int32_t rc = 1;
be9751
 
be9751
     if (cvar == NULL) {
be9751
-        return (0);
be9751
+        return 0;
be9751
     }
be9751
 
be9751
     if (timeout == NULL) {
be9751
-        prit = PR_INTERVAL_NO_TIMEOUT;
be9751
+        rc = pthread_cond_wait((pthread_cond_t *)cvar, (pthread_mutex_t *)mutex);
be9751
     } else {
be9751
-        prit = PR_SecondsToInterval(timeout->tv_sec) + PR_MicrosecondsToInterval(timeout->tv_usec);
be9751
+        struct timespec current_time = {0};
be9751
+        clock_gettime(CLOCK_MONOTONIC, &current_time);
be9751
+        current_time.tv_sec += (timeout->tv_sec + PR_MicrosecondsToInterval(timeout->tv_usec));
be9751
+        rc = pthread_cond_timedwait((pthread_cond_t *)cvar, (pthread_mutex_t *)mutex, &current_time);
be9751
     }
be9751
 
be9751
-    if (PR_WaitCondVar((PRCondVar *)cvar, prit) != PR_SUCCESS) {
be9751
-        return (0);
be9751
+    if (rc != 0) {
be9751
+        /* something went wrong */
be9751
+        return 0;
be9751
     }
be9751
 
be9751
-    return (1);
be9751
+    return 1;  /* success */
be9751
 }
be9751
 
be9751
 
be9751
@@ -166,19 +189,19 @@ slapi_wait_condvar(Slapi_CondVar *cvar, struct timeval *timeout)
be9751
 int
be9751
 slapi_notify_condvar(Slapi_CondVar *cvar, int notify_all)
be9751
 {
be9751
-    PRStatus prrc;
be9751
+    int32_t rc;
be9751
 
be9751
     if (cvar == NULL) {
be9751
-        return (0);
be9751
+        return 0;
be9751
     }
be9751
 
be9751
     if (notify_all) {
be9751
-        prrc = PR_NotifyAllCondVar((PRCondVar *)cvar);
be9751
+        rc = pthread_cond_broadcast((pthread_cond_t *)cvar);
be9751
     } else {
be9751
-        prrc = PR_NotifyCondVar((PRCondVar *)cvar);
be9751
+        rc = pthread_cond_signal((pthread_cond_t *)cvar);
be9751
     }
be9751
 
be9751
-    return (prrc == PR_SUCCESS ? 1 : 0);
be9751
+    return (rc == 0 ? 1 : 0);
be9751
 }
be9751
 
be9751
 Slapi_RWLock *
be9751
@@ -236,7 +259,7 @@ slapi_destroy_rwlock(Slapi_RWLock *rwlock)
be9751
     }
be9751
 }
be9751
 
be9751
-int
be9751
+inline int __attribute__((always_inline))
be9751
 slapi_rwlock_rdlock(Slapi_RWLock *rwlock)
be9751
 {
be9751
     int ret = 0;
be9751
@@ -252,7 +275,7 @@ slapi_rwlock_rdlock(Slapi_RWLock *rwlock)
be9751
     return ret;
be9751
 }
be9751
 
be9751
-int
be9751
+inline int __attribute__((always_inline))
be9751
 slapi_rwlock_wrlock(Slapi_RWLock *rwlock)
be9751
 {
be9751
     int ret = 0;
be9751
@@ -268,7 +291,7 @@ slapi_rwlock_wrlock(Slapi_RWLock *rwlock)
be9751
     return ret;
be9751
 }
be9751
 
be9751
-int
be9751
+inline int __attribute__((always_inline))
be9751
 slapi_rwlock_unlock(Slapi_RWLock *rwlock)
be9751
 {
be9751
     int ret = 0;
be9751
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
be9751
index 806077a16..26f281cba 100644
be9751
--- a/ldap/servers/slapd/task.c
be9751
+++ b/ldap/servers/slapd/task.c
be9751
@@ -380,16 +380,14 @@ slapi_task_status_changed(Slapi_Task *task)
be9751
         Slapi_PBlock *pb = slapi_pblock_new();
be9751
         Slapi_Entry *e;
be9751
         int ttl;
be9751
-        time_t expire;
be9751
 
be9751
         if ((e = get_internal_entry(pb, task->task_dn))) {
be9751
             ttl = atoi(slapi_fetch_attr(e, "ttl", DEFAULT_TTL));
be9751
             if (ttl > (24*3600))
be9751
                 ttl = (24*3600); /* be reasonable, allow to check task status not longer than one day  */
be9751
-            expire = time(NULL) + ttl;
be9751
             task->task_flags |= SLAPI_TASK_DESTROYING;
be9751
             /* queue an event to destroy the state info */
be9751
-            slapi_eq_once(destroy_task, (void *)task, expire);
be9751
+            slapi_eq_once(destroy_task, (void *)task, slapi_current_rel_time_t() + ttl);
be9751
         }
be9751
         slapi_free_search_results_internal(pb);
be9751
         slapi_pblock_destroy(pb);
be9751
diff --git a/ldap/servers/slapd/time.c b/ldap/servers/slapd/time.c
be9751
index 545538404..0406c3689 100644
be9751
--- a/ldap/servers/slapd/time.c
be9751
+++ b/ldap/servers/slapd/time.c
be9751
@@ -107,6 +107,14 @@ slapi_current_rel_time_hr(void)
be9751
     return now;
be9751
 }
be9751
 
be9751
+time_t
be9751
+slapi_current_rel_time_t(void)
be9751
+{
be9751
+    struct timespec now = {0};
be9751
+    clock_gettime(CLOCK_MONOTONIC, &now;;
be9751
+    return now.tv_sec;
be9751
+}
be9751
+
be9751
 struct timespec
be9751
 slapi_current_utc_time_hr(void)
be9751
 {
be9751
@@ -292,7 +300,7 @@ slapi_timer_result
be9751
 slapi_timespec_expire_check(struct timespec *expire)
be9751
 {
be9751
     /*
be9751
-     * Check this first, as it makes no timeout virutally free.
be9751
+     * Check this first, as it makes no timeout virtually free.
be9751
      */
be9751
     if (expire->tv_sec == 0 && expire->tv_nsec == 0) {
be9751
         return TIMER_CONTINUE;
be9751
-- 
be9751
2.26.2
be9751