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

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