andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone

Blame SOURCES/0031-Issue-4384-Separate-eventq-into-REALTIME-and-MONOTON.patch

3280a9
From 69af412d42acccac660037e1f4026a6a6717634c Mon Sep 17 00:00:00 2001
3280a9
From: Mark Reynolds <mreynolds@redhat.com>
3280a9
Date: Thu, 17 Dec 2020 15:25:42 -0500
3280a9
Subject: [PATCH 2/2] Issue 4384 - Separate eventq into REALTIME and MONOTONIC
3280a9
3280a9
Description:  The recent changes to the eventq "when" time changed
3280a9
              internally from REALTIME to MONOTONIC, and this broke
3280a9
              the API.  Create a new API for MONOTONIC clocks, and
3280a9
              keep the original API intact for REALTIME clocks.
3280a9
3280a9
Relates:  https://github.com/389ds/389-ds-base/issues/4384
3280a9
3280a9
Reviewed by: firstyear(Thanks!)
3280a9
---
3280a9
 Makefile.am                                   |   1 +
3280a9
 docs/slapi.doxy.in                            |   1 -
3280a9
 ldap/servers/plugins/chainingdb/cb_instance.c |   6 +-
3280a9
 ldap/servers/plugins/dna/dna.c                |   4 +-
3280a9
 .../plugins/replication/repl5_backoff.c       |  12 +-
3280a9
 .../plugins/replication/repl5_connection.c    |  10 +-
3280a9
 .../plugins/replication/repl5_mtnode_ext.c    |   4 +-
3280a9
 .../plugins/replication/repl5_replica.c       |  24 +-
3280a9
 .../plugins/replication/repl5_schedule.c      |   4 +-
3280a9
 .../plugins/replication/windows_connection.c  |  12 +-
3280a9
 .../replication/windows_inc_protocol.c        |   7 +-
3280a9
 ldap/servers/plugins/retrocl/retrocl_trim.c   |  10 +-
3280a9
 ldap/servers/slapd/daemon.c                   |   3 +-
3280a9
 ldap/servers/slapd/eventq-deprecated.c        | 483 ++++++++++++++++++
3280a9
 ldap/servers/slapd/eventq.c                   | 236 ++++-----
3280a9
 ldap/servers/slapd/main.c                     |  18 +-
3280a9
 ldap/servers/slapd/proto-slap.h               |   6 +-
3280a9
 ldap/servers/slapd/slapi-plugin.h             |  62 ++-
3280a9
 ldap/servers/slapd/slapi2runtime.c            |  23 +-
3280a9
 ldap/servers/slapd/snmp_collator.c            |   7 +-
3280a9
 ldap/servers/slapd/task.c                     |   2 +-
3280a9
 ldap/servers/slapd/uuid.c                     |   3 +-
3280a9
 22 files changed, 750 insertions(+), 188 deletions(-)
3280a9
 create mode 100644 ldap/servers/slapd/eventq-deprecated.c
3280a9
3280a9
diff --git a/Makefile.am b/Makefile.am
3280a9
index f7bf1c44c..ece1ad41a 100644
3280a9
--- a/Makefile.am
3280a9
+++ b/Makefile.am
3280a9
@@ -1408,6 +1408,7 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \
3280a9
 	ldap/servers/slapd/entrywsi.c \
3280a9
 	ldap/servers/slapd/errormap.c \
3280a9
 	ldap/servers/slapd/eventq.c \
3280a9
+	ldap/servers/slapd/eventq-deprecated.c \
3280a9
 	ldap/servers/slapd/factory.c \
3280a9
 	ldap/servers/slapd/features.c \
3280a9
 	ldap/servers/slapd/fileio.c \
3280a9
diff --git a/docs/slapi.doxy.in b/docs/slapi.doxy.in
3280a9
index b1e4810ab..1cafc50ce 100644
3280a9
--- a/docs/slapi.doxy.in
3280a9
+++ b/docs/slapi.doxy.in
3280a9
@@ -759,7 +759,6 @@ WARN_LOGFILE           =
3280a9
 # Note: If this tag is empty the current directory is searched.
3280a9
 
3280a9
 INPUT                  = src/libsds/include/sds.h \
3280a9
-                         docs/job-safety.md \
3280a9
                          # ldap/servers/slapd/slapi-plugin.h \
3280a9
 
3280a9
 # This tag can be used to specify the character encoding of the source files
3280a9
diff --git a/ldap/servers/plugins/chainingdb/cb_instance.c b/ldap/servers/plugins/chainingdb/cb_instance.c
3280a9
index bc1864c1a..7fd85deb0 100644
3280a9
--- a/ldap/servers/plugins/chainingdb/cb_instance.c
3280a9
+++ b/ldap/servers/plugins/chainingdb/cb_instance.c
3280a9
@@ -217,7 +217,7 @@ cb_instance_free(cb_backend_instance *inst)
3280a9
         slapi_rwlock_wrlock(inst->rwl_config_lock);
3280a9
 
3280a9
         if (inst->eq_ctx != NULL) {
3280a9
-            slapi_eq_cancel(inst->eq_ctx);
3280a9
+            slapi_eq_cancel_rel(inst->eq_ctx);
3280a9
             inst->eq_ctx = NULL;
3280a9
         }
3280a9
 
3280a9
@@ -1947,8 +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,
3280a9
-                                     slapi_current_rel_time_t() + 1);
3280a9
+        inst->eq_ctx = slapi_eq_once_rel(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/dna/dna.c b/ldap/servers/plugins/dna/dna.c
3280a9
index 1cb54580b..b46edfcbb 100644
3280a9
--- a/ldap/servers/plugins/dna/dna.c
3280a9
+++ b/ldap/servers/plugins/dna/dna.c
3280a9
@@ -688,7 +688,7 @@ dna_close(Slapi_PBlock *pb __attribute__((unused)))
3280a9
     slapi_log_err(SLAPI_LOG_TRACE, DNA_PLUGIN_SUBSYSTEM,
3280a9
                   "--> dna_close\n");
3280a9
 
3280a9
-    slapi_eq_cancel(eq_ctx);
3280a9
+    slapi_eq_cancel_rel(eq_ctx);
3280a9
     dna_delete_config(NULL);
3280a9
     slapi_ch_free((void **)&dna_global_config);
3280a9
     slapi_destroy_rwlock(g_dna_cache_lock);
3280a9
@@ -908,7 +908,7 @@ dna_load_plugin_config(Slapi_PBlock *pb, int use_eventq)
3280a9
          * starting up  would cause the change to not
3280a9
          * get changelogged. */
3280a9
         now = slapi_current_rel_time_t();
3280a9
-        eq_ctx = slapi_eq_once(dna_update_config_event, NULL, now + 30);
3280a9
+        eq_ctx = slapi_eq_once_rel(dna_update_config_event, NULL, now + 30);
3280a9
     } else {
3280a9
         dna_update_config_event(0, NULL);
3280a9
     }
3280a9
diff --git a/ldap/servers/plugins/replication/repl5_backoff.c b/ldap/servers/plugins/replication/repl5_backoff.c
3280a9
index 40ec75dd7..8c851beb2 100644
3280a9
--- a/ldap/servers/plugins/replication/repl5_backoff.c
3280a9
+++ b/ldap/servers/plugins/replication/repl5_backoff.c
3280a9
@@ -99,7 +99,7 @@ backoff_reset(Backoff_Timer *bt, slapi_eq_fn_t callback, void *callback_data)
3280a9
     bt->callback_arg = callback_data;
3280a9
     /* Cancel any pending events in the event queue */
3280a9
     if (NULL != bt->pending_event) {
3280a9
-        slapi_eq_cancel(bt->pending_event);
3280a9
+        slapi_eq_cancel_rel(bt->pending_event);
3280a9
         bt->pending_event = NULL;
3280a9
     }
3280a9
     /* Compute the first fire time */
3280a9
@@ -112,8 +112,8 @@ backoff_reset(Backoff_Timer *bt, slapi_eq_fn_t callback, void *callback_data)
3280a9
     /* Schedule the callback */
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
+    bt->pending_event = slapi_eq_once_rel(bt->callback, bt->callback_arg,
3280a9
+                                          return_value);
3280a9
     PR_Unlock(bt->lock);
3280a9
     return return_value;
3280a9
 }
3280a9
@@ -159,8 +159,8 @@ backoff_step(Backoff_Timer *bt)
3280a9
         /* Schedule the callback, if any */
3280a9
         bt->last_fire_time += previous_interval;
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
+        bt->pending_event = slapi_eq_once_rel(bt->callback, bt->callback_arg,
3280a9
+                                              return_value);
3280a9
     }
3280a9
     PR_Unlock(bt->lock);
3280a9
     return return_value;
3280a9
@@ -196,7 +196,7 @@ backoff_delete(Backoff_Timer **btp)
3280a9
     PR_Lock(bt->lock);
3280a9
     /* Cancel any pending events in the event queue */
3280a9
     if (NULL != bt->pending_event) {
3280a9
-        slapi_eq_cancel(bt->pending_event);
3280a9
+        slapi_eq_cancel_rel(bt->pending_event);
3280a9
     }
3280a9
     PR_Unlock(bt->lock);
3280a9
     PR_DestroyLock(bt->lock);
3280a9
diff --git a/ldap/servers/plugins/replication/repl5_connection.c b/ldap/servers/plugins/replication/repl5_connection.c
3280a9
index bc9ca424b..2dd74f9e7 100644
3280a9
--- a/ldap/servers/plugins/replication/repl5_connection.c
3280a9
+++ b/ldap/servers/plugins/replication/repl5_connection.c
3280a9
@@ -272,7 +272,7 @@ conn_delete(Repl_Connection *conn)
3280a9
     PR_ASSERT(NULL != conn);
3280a9
     PR_Lock(conn->lock);
3280a9
     if (conn->linger_active) {
3280a9
-        if (slapi_eq_cancel(conn->linger_event) == 1) {
3280a9
+        if (slapi_eq_cancel_rel(conn->linger_event) == 1) {
3280a9
             /* Event was found and cancelled. Destroy the connection object. */
3280a9
             destroy_it = PR_TRUE;
3280a9
         } else {
3280a9
@@ -961,7 +961,7 @@ conn_cancel_linger(Repl_Connection *conn)
3280a9
                       "conn_cancel_linger - %s - Canceling linger on the connection\n",
3280a9
                       agmt_get_long_name(conn->agmt));
3280a9
         conn->linger_active = PR_FALSE;
3280a9
-        if (slapi_eq_cancel(conn->linger_event) == 1) {
3280a9
+        if (slapi_eq_cancel_rel(conn->linger_event) == 1) {
3280a9
             conn->refcnt--;
3280a9
         }
3280a9
         conn->linger_event = NULL;
3280a9
@@ -1030,7 +1030,7 @@ conn_start_linger(Repl_Connection *conn)
3280a9
                       agmt_get_long_name(conn->agmt));
3280a9
     } else {
3280a9
         conn->linger_active = PR_TRUE;
3280a9
-        conn->linger_event = slapi_eq_once(linger_timeout, conn, now + conn->linger_time);
3280a9
+        conn->linger_event = slapi_eq_once_rel(linger_timeout, conn, now + conn->linger_time);
3280a9
         conn->status = STATUS_LINGERING;
3280a9
     }
3280a9
     PR_Unlock(conn->lock);
3280a9
@@ -1990,7 +1990,7 @@ repl5_start_debug_timeout(int *setlevel)
3280a9
     Slapi_Eq_Context eqctx = 0;
3280a9
     if (s_debug_timeout && s_debug_level) {
3280a9
         time_t now = slapi_current_rel_time_t();
3280a9
-        eqctx = slapi_eq_once(repl5_debug_timeout_callback, setlevel,
3280a9
+        eqctx = slapi_eq_once_rel(repl5_debug_timeout_callback, setlevel,
3280a9
                               s_debug_timeout + now);
3280a9
     }
3280a9
     return eqctx;
3280a9
@@ -2002,7 +2002,7 @@ repl5_stop_debug_timeout(Slapi_Eq_Context eqctx, int *setlevel)
3280a9
     char buf[20];
3280a9
 
3280a9
     if (eqctx && !*setlevel) {
3280a9
-        (void)slapi_eq_cancel(eqctx);
3280a9
+        (void)slapi_eq_cancel_rel(eqctx);
3280a9
     }
3280a9
 
3280a9
     if (s_debug_timeout && s_debug_level && *setlevel) {
3280a9
diff --git a/ldap/servers/plugins/replication/repl5_mtnode_ext.c b/ldap/servers/plugins/replication/repl5_mtnode_ext.c
3280a9
index 82e230958..2967a47f8 100644
3280a9
--- a/ldap/servers/plugins/replication/repl5_mtnode_ext.c
3280a9
+++ b/ldap/servers/plugins/replication/repl5_mtnode_ext.c
3280a9
@@ -82,8 +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),
3280a9
-                          slapi_current_rel_time_t() + 5);
3280a9
+            slapi_eq_once_rel(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_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
3280a9
index c1d376c72..7102e0606 100644
3280a9
--- a/ldap/servers/plugins/replication/repl5_replica.c
3280a9
+++ b/ldap/servers/plugins/replication/repl5_replica.c
3280a9
@@ -231,17 +231,17 @@ replica_new_from_entry(Slapi_Entry *e, char *errortext, PRBool is_add_operation,
3280a9
     /* ONREPL - the state update can occur before the entry is added to the DIT.
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_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
3280a9
+    r->repl_eqcxt_rs = slapi_eq_repeat_rel(replica_update_state, r->repl_name,
3280a9
+                                           slapi_current_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
3280a9
 
3280a9
     if (r->tombstone_reap_interval > 0) {
3280a9
         /*
3280a9
          * Reap Tombstone should be started some time after the plugin started.
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_rel_time_t() + r->tombstone_reap_interval,
3280a9
-                                           1000 * r->tombstone_reap_interval);
3280a9
+        r->repl_eqcxt_tr = slapi_eq_repeat_rel(eq_cb_reap_tombstones, r->repl_name,
3280a9
+                                               slapi_current_rel_time_t() + r->tombstone_reap_interval,
3280a9
+                                               1000 * r->tombstone_reap_interval);
3280a9
     }
3280a9
 
3280a9
 done:
3280a9
@@ -303,12 +303,12 @@ replica_destroy(void **arg)
3280a9
      */
3280a9
 
3280a9
     if (r->repl_eqcxt_rs) {
3280a9
-        slapi_eq_cancel(r->repl_eqcxt_rs);
3280a9
+        slapi_eq_cancel_rel(r->repl_eqcxt_rs);
3280a9
         r->repl_eqcxt_rs = NULL;
3280a9
     }
3280a9
 
3280a9
     if (r->repl_eqcxt_tr) {
3280a9
-        slapi_eq_cancel(r->repl_eqcxt_tr);
3280a9
+        slapi_eq_cancel_rel(r->repl_eqcxt_tr);
3280a9
         r->repl_eqcxt_tr = NULL;
3280a9
     }
3280a9
 
3280a9
@@ -1511,14 +1511,14 @@ replica_set_enabled(Replica *r, PRBool enable)
3280a9
     if (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_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
3280a9
+            r->repl_eqcxt_rs = slapi_eq_repeat_rel(replica_update_state, r->repl_name,
3280a9
+                                                   slapi_current_rel_time_t() + START_UPDATE_DELAY, RUV_SAVE_INTERVAL);
3280a9
         }
3280a9
     } else /* disable */
3280a9
     {
3280a9
         if (r->repl_eqcxt_rs) /* event is still registerd */
3280a9
         {
3280a9
-            slapi_eq_cancel(r->repl_eqcxt_rs);
3280a9
+            slapi_eq_cancel_rel(r->repl_eqcxt_rs);
3280a9
             r->repl_eqcxt_rs = NULL;
3280a9
         }
3280a9
     }
3280a9
@@ -3628,7 +3628,7 @@ replica_set_tombstone_reap_interval(Replica *r, long interval)
3280a9
     if (interval > 0 && r->repl_eqcxt_tr && r->tombstone_reap_interval != interval) {
3280a9
         int found;
3280a9
 
3280a9
-        found = slapi_eq_cancel(r->repl_eqcxt_tr);
3280a9
+        found = slapi_eq_cancel_rel(r->repl_eqcxt_tr);
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
                       r->tombstone_reap_interval, (found ? "cancelled" : "not found"));
3280a9
@@ -3636,7 +3636,7 @@ replica_set_tombstone_reap_interval(Replica *r, long interval)
3280a9
     }
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
+        r->repl_eqcxt_tr = slapi_eq_repeat_rel(eq_cb_reap_tombstones, r->repl_name,
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
diff --git a/ldap/servers/plugins/replication/repl5_schedule.c b/ldap/servers/plugins/replication/repl5_schedule.c
3280a9
index 9539f4031..ca42df561 100644
3280a9
--- a/ldap/servers/plugins/replication/repl5_schedule.c
3280a9
+++ b/ldap/servers/plugins/replication/repl5_schedule.c
3280a9
@@ -550,7 +550,7 @@ schedule_window_state_change_event(Schedule *sch)
3280a9
         wakeup_time = PRTime2time_t(tm);
3280a9
 
3280a9
         /* schedule the event */
3280a9
-        sch->pending_event = slapi_eq_once(window_state_changed, sch, wakeup_time);
3280a9
+        sch->pending_event = slapi_eq_once_rel(window_state_changed, sch, wakeup_time);
3280a9
 
3280a9
         timestr = get_timestring(&wakeup_time);
3280a9
         slapi_log_err(SLAPI_LOG_REPL, repl_plugin_name, "%s: Update window will %s at %s\n",
3280a9
@@ -593,7 +593,7 @@ static void
3280a9
 unschedule_window_state_change_event(Schedule *sch)
3280a9
 {
3280a9
     if (sch->pending_event) {
3280a9
-        slapi_eq_cancel(sch->pending_event);
3280a9
+        slapi_eq_cancel_rel(sch->pending_event);
3280a9
         sch->pending_event = NULL;
3280a9
     }
3280a9
 }
3280a9
diff --git a/ldap/servers/plugins/replication/windows_connection.c b/ldap/servers/plugins/replication/windows_connection.c
3280a9
index ce0662544..5eca5fad1 100644
3280a9
--- a/ldap/servers/plugins/replication/windows_connection.c
3280a9
+++ b/ldap/servers/plugins/replication/windows_connection.c
3280a9
@@ -204,7 +204,7 @@ windows_conn_delete(Repl_Connection *conn)
3280a9
     PR_ASSERT(NULL != conn);
3280a9
     PR_Lock(conn->lock);
3280a9
     if (conn->linger_active) {
3280a9
-        if (slapi_eq_cancel(conn->linger_event) == 1) {
3280a9
+        if (slapi_eq_cancel_rel(conn->linger_event) == 1) {
3280a9
             /* Event was found and cancelled. Destroy the connection object. */
3280a9
             PR_Unlock(conn->lock);
3280a9
             destroy_it = PR_TRUE;
3280a9
@@ -1052,7 +1052,7 @@ windows_conn_cancel_linger(Repl_Connection *conn)
3280a9
                       "windows_conn_cancel_linger - %s: Cancelling linger on the connection\n",
3280a9
                       agmt_get_long_name(conn->agmt));
3280a9
         conn->linger_active = PR_FALSE;
3280a9
-        if (slapi_eq_cancel(conn->linger_event) == 1) {
3280a9
+        if (slapi_eq_cancel_rel(conn->linger_event) == 1) {
3280a9
             conn->refcnt--;
3280a9
         }
3280a9
         conn->linger_event = NULL;
3280a9
@@ -1129,7 +1129,7 @@ windows_conn_start_linger(Repl_Connection *conn)
3280a9
                       agmt_get_long_name(conn->agmt));
3280a9
     } else {
3280a9
         conn->linger_active = PR_TRUE;
3280a9
-        conn->linger_event = slapi_eq_once(linger_timeout, conn, now + conn->linger_time);
3280a9
+        conn->linger_event = slapi_eq_once_rel(linger_timeout, conn, now + conn->linger_time);
3280a9
         conn->status = STATUS_LINGERING;
3280a9
     }
3280a9
     PR_Unlock(conn->lock);
3280a9
@@ -1822,8 +1822,8 @@ repl5_start_debug_timeout(int *setlevel)
3280a9
 
3280a9
     if (s_debug_timeout && s_debug_level) {
3280a9
         time_t now = time(NULL);
3280a9
-        eqctx = slapi_eq_once(repl5_debug_timeout_callback, setlevel,
3280a9
-                              s_debug_timeout + now);
3280a9
+        eqctx = slapi_eq_once_rel(repl5_debug_timeout_callback, setlevel,
3280a9
+                                  s_debug_timeout + now);
3280a9
     }
3280a9
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "<= repl5_start_debug_timeout\n");
3280a9
     return eqctx;
3280a9
@@ -1837,7 +1837,7 @@ repl5_stop_debug_timeout(Slapi_Eq_Context eqctx, int *setlevel)
3280a9
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> repl5_stop_debug_timeout\n");
3280a9
 
3280a9
     if (eqctx && !*setlevel) {
3280a9
-        (void)slapi_eq_cancel(eqctx);
3280a9
+        (void)slapi_eq_cancel_rel(eqctx);
3280a9
     }
3280a9
 
3280a9
     if (s_debug_timeout && s_debug_level && *setlevel) {
3280a9
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
3280a9
index 3d548e5ed..c07a8180a 100644
3280a9
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
3280a9
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
3280a9
@@ -132,7 +132,7 @@ windows_inc_delete(Private_Repl_Protocol **prpp)
3280a9
     slapi_log_err(SLAPI_LOG_TRACE, windows_repl_plugin_name, "=> windows_inc_delete\n");
3280a9
     /* First, stop the protocol if it isn't already stopped */
3280a9
     /* Then, delete all resources used by the protocol */
3280a9
-    rc = slapi_eq_cancel(dirsync);
3280a9
+    rc = slapi_eq_cancel_rel(dirsync);
3280a9
     slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
3280a9
                   "windows_inc_delete - dirsync: %p, rval: %d\n", dirsync, rc);
3280a9
     /* if backoff is set, delete it (from EQ, as well) */
3280a9
@@ -324,12 +324,13 @@ windows_inc_run(Private_Repl_Protocol *prp)
3280a9
             if (interval != current_interval) {
3280a9
                 current_interval = interval;
3280a9
                 if (dirsync) {
3280a9
-                    int rc = slapi_eq_cancel(dirsync);
3280a9
+                    int rc = slapi_eq_cancel_rel(dirsync);
3280a9
                     slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
3280a9
                                   "windows_inc_run - Cancelled dirsync: %p, rval: %d\n",
3280a9
                                   dirsync, rc);
3280a9
                 }
3280a9
-                dirsync = slapi_eq_repeat(periodic_dirsync, (void *)prp, (time_t)0, interval);
3280a9
+                dirsync = slapi_eq_repeat_rel(periodic_dirsync, (void *)prp,
3280a9
+                                              slapi_current_rel_time_t(), interval);
3280a9
                 slapi_log_err(SLAPI_LOG_REPL, windows_repl_plugin_name,
3280a9
                               "windows_inc_run - New dirsync: %p\n", dirsync);
3280a9
             }
3280a9
diff --git a/ldap/servers/plugins/retrocl/retrocl_trim.c b/ldap/servers/plugins/retrocl/retrocl_trim.c
3280a9
index a3e16c4e1..12a395210 100644
3280a9
--- a/ldap/servers/plugins/retrocl/retrocl_trim.c
3280a9
+++ b/ldap/servers/plugins/retrocl/retrocl_trim.c
3280a9
@@ -460,10 +460,10 @@ retrocl_init_trimming(void)
3280a9
     ts.ts_s_initialized = 1;
3280a9
     retrocl_trimming = 1;
3280a9
 
3280a9
-    retrocl_trim_ctx = slapi_eq_repeat(retrocl_housekeeping,
3280a9
-                                       NULL, (time_t)0,
3280a9
-                                       /* in milliseconds */
3280a9
-                                       trim_interval * 1000);
3280a9
+    retrocl_trim_ctx = slapi_eq_repeat_rel(retrocl_housekeeping,
3280a9
+                                           NULL, (time_t)0,
3280a9
+                                           /* in milliseconds */
3280a9
+                                           trim_interval * 1000);
3280a9
 }
3280a9
 
3280a9
 /*
3280a9
@@ -487,7 +487,7 @@ retrocl_stop_trimming(void)
3280a9
          */
3280a9
         retrocl_trimming = 0;
3280a9
         if (retrocl_trim_ctx) {
3280a9
-            slapi_eq_cancel(retrocl_trim_ctx);
3280a9
+            slapi_eq_cancel_rel(retrocl_trim_ctx);
3280a9
             retrocl_trim_ctx = NULL;
3280a9
         }
3280a9
         PR_DestroyLock(ts.ts_s_trim_mutex);
3280a9
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
3280a9
index 0071ed86a..7681e88ea 100644
3280a9
--- a/ldap/servers/slapd/daemon.c
3280a9
+++ b/ldap/servers/slapd/daemon.c
3280a9
@@ -1240,7 +1240,8 @@ slapd_daemon(daemon_ports_t *ports)
3280a9
     slapi_log_err(SLAPI_LOG_TRACE, "slapd_daemon",
3280a9
                   "slapd shutting down - waiting for backends to close down\n");
3280a9
 
3280a9
-    eq_stop();
3280a9
+    eq_stop(); /* deprecated */
3280a9
+    eq_stop_rel();
3280a9
     if (!in_referral_mode) {
3280a9
         task_shutdown();
3280a9
         uniqueIDGenCleanup();
3280a9
diff --git a/ldap/servers/slapd/eventq-deprecated.c b/ldap/servers/slapd/eventq-deprecated.c
3280a9
new file mode 100644
3280a9
index 000000000..71a7bf8f5
3280a9
--- /dev/null
3280a9
+++ b/ldap/servers/slapd/eventq-deprecated.c
3280a9
@@ -0,0 +1,483 @@
3280a9
+/** BEGIN COPYRIGHT BLOCK
3280a9
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
3280a9
+ * Copyright (C) 2020 Red Hat, Inc.
3280a9
+ * All rights reserved.
3280a9
+ *
3280a9
+ * License: GPL (version 3 or any later version).
3280a9
+ * See LICENSE for details.
3280a9
+ * END COPYRIGHT BLOCK **/
3280a9
+
3280a9
+#ifdef HAVE_CONFIG_H
3280a9
+#include <config.h>
3280a9
+#endif
3280a9
+
3280a9
+
3280a9
+/* ********************************************************
3280a9
+eventq-deprecated.c - Event queue/scheduling system.
3280a9
+
3280a9
+There are 3 publicly-accessible entry points:
3280a9
+
3280a9
+slapi_eq_once(): cause an event to happen exactly once
3280a9
+slapi_eq_repeat(): cause an event to happen repeatedly
3280a9
+slapi_eq_cancel(): cancel a pending event
3280a9
+
3280a9
+There is also an initialization point which must be
3280a9
+called by the server to initialize the event queue system:
3280a9
+eq_start(), and an entry point used to shut down the system:
3280a9
+eq_stop().
3280a9
+
3280a9
+These functions are now deprecated in favor of the functions
3280a9
+in eventq.c which use MONOTONIC clocks instead of REALTIME
3280a9
+clocks.
3280a9
+*********************************************************** */
3280a9
+
3280a9
+#include "slap.h"
3280a9
+#include "prlock.h"
3280a9
+#include "prcvar.h"
3280a9
+#include "prinit.h"
3280a9
+
3280a9
+/*
3280a9
+ * Private definition of slapi_eq_context. Only this
3280a9
+ * module (eventq.c) should know about the layout of
3280a9
+ * this structure.
3280a9
+ */
3280a9
+typedef struct _slapi_eq_context
3280a9
+{
3280a9
+    time_t ec_when;
3280a9
+    time_t ec_interval;
3280a9
+    slapi_eq_fn_t ec_fn;
3280a9
+    void *ec_arg;
3280a9
+    Slapi_Eq_Context ec_id;
3280a9
+    struct _slapi_eq_context *ec_next;
3280a9
+} slapi_eq_context;
3280a9
+
3280a9
+/*
3280a9
+ * Definition of the event queue.
3280a9
+ */
3280a9
+typedef struct _event_queue
3280a9
+{
3280a9
+    PRLock *eq_lock;
3280a9
+    PRCondVar *eq_cv;
3280a9
+    slapi_eq_context *eq_queue;
3280a9
+} event_queue;
3280a9
+
3280a9
+/*
3280a9
+ * The event queue itself.
3280a9
+ */
3280a9
+static event_queue eqs = {0};
3280a9
+static event_queue *eq = &eqs;
3280a9
+
3280a9
+/*
3280a9
+ * Thread ID of the main thread loop
3280a9
+ */
3280a9
+static PRThread *eq_loop_tid = NULL;
3280a9
+
3280a9
+/*
3280a9
+ * Flags used to control startup/shutdown of the event queue
3280a9
+ */
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
+PRCallOnceType init_once = {0};
3280a9
+
3280a9
+/* Forward declarations */
3280a9
+static slapi_eq_context *eq_new(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval);
3280a9
+static void eq_enqueue(slapi_eq_context *newec);
3280a9
+static slapi_eq_context *eq_dequeue(time_t now);
3280a9
+static PRStatus eq_create(void);
3280a9
+
3280a9
+
3280a9
+/* ******************************************************** */
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * slapi_eq_once: cause an event to happen exactly once.
3280a9
+ *
3280a9
+ * Arguments:
3280a9
+ *  fn: the function to call
3280a9
+ *  arg: an argument to pass to the called function
3280a9
+ *  when: the time that the function should be called
3280a9
+ * Returns:
3280a9
+ *  slapi_eq_context - a handle to an opaque object which
3280a9
+ *  the caller can use to refer to this particular scheduled
3280a9
+ *  event.
3280a9
+ */
3280a9
+Slapi_Eq_Context
3280a9
+slapi_eq_once(slapi_eq_fn_t fn, void *arg, time_t when)
3280a9
+{
3280a9
+    slapi_eq_context *tmp;
3280a9
+    PR_ASSERT(eq_initialized);
3280a9
+    if (!eq_stopped) {
3280a9
+
3280a9
+        Slapi_Eq_Context id;
3280a9
+
3280a9
+        tmp = eq_new(fn, arg, when, 0UL);
3280a9
+        id = tmp->ec_id;
3280a9
+
3280a9
+        eq_enqueue(tmp);
3280a9
+
3280a9
+        /* After this point, <tmp> may have      */
3280a9
+        /* been freed, depending on the thread   */
3280a9
+        /* scheduling. Too bad             */
3280a9
+
3280a9
+        slapi_log_err(SLAPI_LOG_HOUSE, NULL,
3280a9
+                      "added one-time event id %p at time %ld\n",
3280a9
+                      id, when);
3280a9
+        return (id);
3280a9
+    }
3280a9
+    return NULL; /* JCM - Not sure if this should be 0 or something else. */
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * slapi_eq_repeat: cause an event to happen repeatedly.
3280a9
+ *
3280a9
+ * Arguments:
3280a9
+ *  fn: the function to call
3280a9
+ *  arg: an argument to pass to the called function
3280a9
+ *  when: the time that the function should first be called
3280a9
+ *  interval: the amount of time (in milliseconds) between
3280a9
+ *            successive calls to the function
3280a9
+ * Returns:
3280a9
+ *  slapi_eq_context - a handle to an opaque object which
3280a9
+ *  the caller can use to refer to this particular scheduled
3280a9
+ */
3280a9
+Slapi_Eq_Context
3280a9
+slapi_eq_repeat(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
3280a9
+{
3280a9
+    slapi_eq_context *tmp;
3280a9
+    PR_ASSERT(eq_initialized);
3280a9
+    if (!eq_stopped) {
3280a9
+        tmp = eq_new(fn, arg, when, interval);
3280a9
+        eq_enqueue(tmp);
3280a9
+        slapi_log_err(SLAPI_LOG_HOUSE, NULL,
3280a9
+                      "added repeating event id %p at time %ld, interval %lu\n",
3280a9
+                      tmp->ec_id, when, interval);
3280a9
+        return (tmp->ec_id);
3280a9
+    }
3280a9
+    return NULL; /* JCM - Not sure if this should be 0 or something else. */
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * slapi_eq_cancel: cancel a pending event.
3280a9
+ * Arguments:
3280a9
+ *  ctx: the context of the event which should be de-scheduled
3280a9
+ */
3280a9
+int
3280a9
+slapi_eq_cancel(Slapi_Eq_Context ctx)
3280a9
+{
3280a9
+    slapi_eq_context **p, *tmp = NULL;
3280a9
+    int found = 0;
3280a9
+
3280a9
+    PR_ASSERT(eq_initialized);
3280a9
+    if (!eq_stopped) {
3280a9
+        PR_Lock(eq->eq_lock);
3280a9
+        p = &(eq->eq_queue);
3280a9
+        while (!found && *p != NULL) {
3280a9
+            if ((*p)->ec_id == ctx) {
3280a9
+                tmp = *p;
3280a9
+                *p = (*p)->ec_next;
3280a9
+                slapi_ch_free((void **)&tmp);
3280a9
+                found = 1;
3280a9
+            } else {
3280a9
+                p = &((*p)->ec_next);
3280a9
+            }
3280a9
+        }
3280a9
+        PR_Unlock(eq->eq_lock);
3280a9
+    }
3280a9
+    slapi_log_err(SLAPI_LOG_HOUSE, NULL,
3280a9
+                  "cancellation of event id %p requested: %s\n",
3280a9
+                  ctx, found ? "cancellation succeeded" : "event not found");
3280a9
+    return found;
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * Construct a new ec structure
3280a9
+ */
3280a9
+static slapi_eq_context *
3280a9
+eq_new(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
3280a9
+{
3280a9
+    slapi_eq_context *retptr = (slapi_eq_context *)slapi_ch_calloc(1, sizeof(slapi_eq_context));
3280a9
+
3280a9
+    retptr->ec_fn = fn;
3280a9
+    retptr->ec_arg = arg;
3280a9
+    /*
3280a9
+     * retptr->ec_when = when < now ? now : when;
3280a9
+     * we used to amke this check, but it make no sense: when queued, if when
3280a9
+     * has expired, we'll be executed anyway. save the cycles, and just set
3280a9
+     * ec_when.
3280a9
+     */
3280a9
+    retptr->ec_when = when;
3280a9
+    retptr->ec_interval = interval == 0UL ? 0UL : (interval + 999) / 1000;
3280a9
+    retptr->ec_id = (Slapi_Eq_Context)retptr;
3280a9
+    return retptr;
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * Add a new event to the event queue.
3280a9
+ */
3280a9
+static void
3280a9
+eq_enqueue(slapi_eq_context *newec)
3280a9
+{
3280a9
+    slapi_eq_context **p;
3280a9
+
3280a9
+    PR_ASSERT(NULL != newec);
3280a9
+    PR_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
+            break;
3280a9
+        }
3280a9
+    }
3280a9
+    if (NULL != *p) {
3280a9
+        newec->ec_next = *p;
3280a9
+    } else {
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
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * If there is an event in the queue scheduled at time
3280a9
+ * <now> or before, dequeue it and return a pointer
3280a9
+ * to it. Otherwise, return NULL.
3280a9
+ */
3280a9
+static slapi_eq_context *
3280a9
+eq_dequeue(time_t now)
3280a9
+{
3280a9
+    slapi_eq_context *retptr = NULL;
3280a9
+
3280a9
+    PR_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
+    return retptr;
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * Call all events which are due to run.
3280a9
+ * Note that if we've missed a schedule
3280a9
+ * opportunity, we don't try to catch up
3280a9
+ * by calling the function repeatedly.
3280a9
+ */
3280a9
+static void
3280a9
+eq_call_all(void)
3280a9
+{
3280a9
+    slapi_eq_context *p;
3280a9
+    time_t curtime = slapi_current_utc_time();
3280a9
+
3280a9
+    while ((p = eq_dequeue(curtime)) != NULL) {
3280a9
+        /* Call the scheduled function */
3280a9
+        p->ec_fn(p->ec_when, p->ec_arg);
3280a9
+        slapi_log_err(SLAPI_LOG_HOUSE, NULL,
3280a9
+                      "Event id %p called at %ld (scheduled for %ld)\n",
3280a9
+                      p->ec_id, curtime, p->ec_when);
3280a9
+        if (0UL != p->ec_interval) {
3280a9
+            /* This is a repeating event. Requeue it. */
3280a9
+            do {
3280a9
+                p->ec_when += p->ec_interval;
3280a9
+            } while (p->ec_when < curtime);
3280a9
+            eq_enqueue(p);
3280a9
+        } else {
3280a9
+            slapi_ch_free((void **)&p);
3280a9
+        }
3280a9
+    }
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * The main event queue loop.
3280a9
+ */
3280a9
+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
+        int until;
3280a9
+        PR_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
+                goto bye;
3280a9
+            }
3280a9
+            /* Compute new timeout */
3280a9
+            if (NULL != eq->eq_queue) {
3280a9
+                until = eq->eq_queue->ec_when - curtime;
3280a9
+                timeout = PR_SecondsToInterval(until);
3280a9
+            } else {
3280a9
+                timeout = PR_INTERVAL_NO_TIMEOUT;
3280a9
+            }
3280a9
+            PR_WaitCondVar(eq->eq_cv, timeout);
3280a9
+            curtime = slapi_current_utc_time();
3280a9
+        }
3280a9
+        /* There is some work to do */
3280a9
+        PR_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
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * Allocate and initialize the event queue structures.
3280a9
+ */
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
+        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
+        exit(1);
3280a9
+    }
3280a9
+    if ((ss_lock = PR_NewLock()) == NULL) {
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create", "PR_NewLock failed\n");
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
+        exit(1);
3280a9
+    }
3280a9
+    eq->eq_queue = NULL;
3280a9
+    eq_initialized = 1;
3280a9
+    return PR_SUCCESS;
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * eq_start: start the event queue system.
3280a9
+ *
3280a9
+ * This should be called exactly once. It will start a
3280a9
+ * thread which wakes up periodically and schedules events.
3280a9
+ */
3280a9
+void
3280a9
+eq_start()
3280a9
+{
3280a9
+    PR_ASSERT(eq_initialized);
3280a9
+    eq_running = 1;
3280a9
+    if ((eq_loop_tid = PR_CreateThread(PR_USER_THREAD, (VFP)eq_loop,
3280a9
+                                       NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,
3280a9
+                                       SLAPD_DEFAULT_THREAD_STACKSIZE)) == NULL) {
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_start", "eq_loop PR_CreateThread failed\n");
3280a9
+        exit(1);
3280a9
+    }
3280a9
+    slapi_log_err(SLAPI_LOG_HOUSE, NULL, "event queue services have started\n");
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * eq_init: initialize the event queue system.
3280a9
+ *
3280a9
+ * This function should be called early in server startup.
3280a9
+ * Once it has been called, the event queue will queue
3280a9
+ * events, but will not fire any events. Once all of the
3280a9
+ * server plugins have been started, the eq_start()
3280a9
+ * function should be called, and events will then start
3280a9
+ * to fire.
3280a9
+ */
3280a9
+void
3280a9
+eq_init()
3280a9
+{
3280a9
+    if (!eq_initialized) {
3280a9
+        if (PR_SUCCESS != PR_CallOnce(&init_once, eq_create)) {
3280a9
+            slapi_log_err(SLAPI_LOG_ERR, "eq_init", "eq_create failed\n");
3280a9
+        }
3280a9
+    }
3280a9
+}
3280a9
+
3280a9
+
3280a9
+/*
3280a9
+ * eq_stop: shut down the event queue system.
3280a9
+ * Does not return until event queue is fully
3280a9
+ * shut down.
3280a9
+ */
3280a9
+void
3280a9
+eq_stop()
3280a9
+{
3280a9
+    slapi_eq_context *p, *q;
3280a9
+
3280a9
+    if (NULL == eq || NULL == eq->eq_lock) { /* never started */
3280a9
+        eq_stopped = 1;
3280a9
+        return;
3280a9
+    }
3280a9
+
3280a9
+    eq_stopped = 0;
3280a9
+    eq_running = 0;
3280a9
+    /*
3280a9
+     * Signal the eq thread function to stop, and wait until
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
+    }
3280a9
+    (void)PR_JoinThread(eq_loop_tid);
3280a9
+    /*
3280a9
+     * XXXggood we don't free the actual event queue data structures.
3280a9
+     * This is intentional, to allow enqueueing/cancellation of events
3280a9
+     * even after event queue services have shut down (these are no-ops).
3280a9
+     * The downside is that the event queue can't be stopped and restarted
3280a9
+     * easily.
3280a9
+     */
3280a9
+    PR_Lock(eq->eq_lock);
3280a9
+    p = eq->eq_queue;
3280a9
+    while (p != NULL) {
3280a9
+        q = p->ec_next;
3280a9
+        slapi_ch_free((void **)&p);
3280a9
+        /* Some ec_arg could get leaked here in shutdown (e.g., replica_name)
3280a9
+         * This can be fixed by specifying a flag when the context is queued.
3280a9
+         * [After 6.2]
3280a9
+         */
3280a9
+        p = q;
3280a9
+    }
3280a9
+    PR_Unlock(eq->eq_lock);
3280a9
+    slapi_log_err(SLAPI_LOG_HOUSE, NULL, "event queue services have shut down\n");
3280a9
+}
3280a9
+
3280a9
+/*
3280a9
+ * return arg (ec_arg) only if the context is in the event queue
3280a9
+ */
3280a9
+void *
3280a9
+slapi_eq_get_arg(Slapi_Eq_Context ctx)
3280a9
+{
3280a9
+    slapi_eq_context **p;
3280a9
+
3280a9
+    PR_ASSERT(eq_initialized);
3280a9
+    if (eq && !eq_stopped) {
3280a9
+        PR_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
+                return (*p)->ec_arg;
3280a9
+            } else {
3280a9
+                p = &((*p)->ec_next);
3280a9
+            }
3280a9
+        }
3280a9
+        PR_Unlock(eq->eq_lock);
3280a9
+    }
3280a9
+    return NULL;
3280a9
+}
3280a9
diff --git a/ldap/servers/slapd/eventq.c b/ldap/servers/slapd/eventq.c
3280a9
index e1900724f..4c39e08cf 100644
3280a9
--- a/ldap/servers/slapd/eventq.c
3280a9
+++ b/ldap/servers/slapd/eventq.c
3280a9
@@ -17,14 +17,14 @@ eventq.c - Event queue/scheduling system.
3280a9
 
3280a9
 There are 3 publicly-accessible entry points:
3280a9
 
3280a9
-slapi_eq_once(): cause an event to happen exactly once
3280a9
-slapi_eq_repeat(): cause an event to happen repeatedly
3280a9
-slapi_eq_cancel(): cancel a pending event
3280a9
+slapi_eq_once_rel(): cause an event to happen exactly once
3280a9
+slapi_eq_repeat_rel(): cause an event to happen repeatedly
3280a9
+slapi_eq_cancel_rel(): cancel a pending event
3280a9
 
3280a9
 There is also an initialization point which must be
3280a9
 called by the server to initialize the event queue system:
3280a9
-eq_start(), and an entry point used to shut down the system:
3280a9
-eq_stop().
3280a9
+eq_start_rel(), and an entry point used to shut down the system:
3280a9
+eq_stop_rel().
3280a9
 *********************************************************** */
3280a9
 
3280a9
 #include "slap.h"
3280a9
@@ -60,36 +60,36 @@ typedef struct _event_queue
3280a9
 /*
3280a9
  * The event queue itself.
3280a9
  */
3280a9
-static event_queue eqs = {0};
3280a9
-static event_queue *eq = &eqs;
3280a9
+static event_queue eqs_rel = {0};
3280a9
+static event_queue *eq_rel = &eqs_rel;
3280a9
 
3280a9
 /*
3280a9
  * Thread ID of the main thread loop
3280a9
  */
3280a9
-static PRThread *eq_loop_tid = NULL;
3280a9
+static PRThread *eq_loop_rel_tid = NULL;
3280a9
 
3280a9
 /*
3280a9
  * Flags used to control startup/shutdown of the event queue
3280a9
  */
3280a9
-static int eq_running = 0;
3280a9
-static int eq_stopped = 0;
3280a9
-static int eq_initialized = 0;
3280a9
-static pthread_mutex_t ss_lock;
3280a9
-static pthread_cond_t ss_cv;
3280a9
-PRCallOnceType init_once = {0};
3280a9
+static int eq_rel_running = 0;
3280a9
+static int eq_rel_stopped = 0;
3280a9
+static int eq_rel_initialized = 0;
3280a9
+static pthread_mutex_t ss_rel_lock;
3280a9
+static pthread_cond_t ss_rel_cv;
3280a9
+PRCallOnceType init_once_rel = {0};
3280a9
 
3280a9
 /* Forward declarations */
3280a9
-static slapi_eq_context *eq_new(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval);
3280a9
-static void eq_enqueue(slapi_eq_context *newec);
3280a9
-static slapi_eq_context *eq_dequeue(time_t now);
3280a9
-static PRStatus eq_create(void);
3280a9
+static slapi_eq_context *eq_new_rel(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval);
3280a9
+static void eq_enqueue_rel(slapi_eq_context *newec);
3280a9
+static slapi_eq_context *eq_dequeue_rel(time_t now);
3280a9
+static PRStatus eq_create_rel(void);
3280a9
 
3280a9
 
3280a9
 /* ******************************************************** */
3280a9
 
3280a9
 
3280a9
 /*
3280a9
- * slapi_eq_once: cause an event to happen exactly once.
3280a9
+ * slapi_eq_once_rel: cause an event to happen exactly once.
3280a9
  *
3280a9
  * Arguments:
3280a9
  *  fn: the function to call
3280a9
@@ -101,18 +101,18 @@ static PRStatus eq_create(void);
3280a9
  *  event.
3280a9
  */
3280a9
 Slapi_Eq_Context
3280a9
-slapi_eq_once(slapi_eq_fn_t fn, void *arg, time_t when)
3280a9
+slapi_eq_once_rel(slapi_eq_fn_t fn, void *arg, time_t when)
3280a9
 {
3280a9
     slapi_eq_context *tmp;
3280a9
-    PR_ASSERT(eq_initialized);
3280a9
-    if (!eq_stopped) {
3280a9
+    PR_ASSERT(eq_rel_initialized);
3280a9
+    if (!eq_rel_stopped) {
3280a9
 
3280a9
         Slapi_Eq_Context id;
3280a9
 
3280a9
-        tmp = eq_new(fn, arg, when, 0UL);
3280a9
+        tmp = eq_new_rel(fn, arg, when, 0UL);
3280a9
         id = tmp->ec_id;
3280a9
 
3280a9
-        eq_enqueue(tmp);
3280a9
+        eq_enqueue_rel(tmp);
3280a9
 
3280a9
         /* After this point, <tmp> may have      */
3280a9
         /* been freed, depending on the thread   */
3280a9
@@ -128,7 +128,7 @@ slapi_eq_once(slapi_eq_fn_t fn, void *arg, time_t when)
3280a9
 
3280a9
 
3280a9
 /*
3280a9
- * slapi_eq_repeat: cause an event to happen repeatedly.
3280a9
+ * slapi_eq_repeat_rel: cause an event to happen repeatedly.
3280a9
  *
3280a9
  * Arguments:
3280a9
  *  fn: the function to call
3280a9
@@ -141,13 +141,13 @@ slapi_eq_once(slapi_eq_fn_t fn, void *arg, time_t when)
3280a9
  *  the caller can use to refer to this particular scheduled
3280a9
  */
3280a9
 Slapi_Eq_Context
3280a9
-slapi_eq_repeat(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
3280a9
+slapi_eq_repeat_rel(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
3280a9
 {
3280a9
     slapi_eq_context *tmp;
3280a9
-    PR_ASSERT(eq_initialized);
3280a9
-    if (!eq_stopped) {
3280a9
-        tmp = eq_new(fn, arg, when, interval);
3280a9
-        eq_enqueue(tmp);
3280a9
+    PR_ASSERT(eq_rel_initialized);
3280a9
+    if (!eq_rel_stopped) {
3280a9
+        tmp = eq_new_rel(fn, arg, when, interval);
3280a9
+        eq_enqueue_rel(tmp);
3280a9
         slapi_log_err(SLAPI_LOG_HOUSE, NULL,
3280a9
                       "added repeating event id %p at time %ld, interval %lu\n",
3280a9
                       tmp->ec_id, when, interval);
3280a9
@@ -158,20 +158,20 @@ slapi_eq_repeat(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval
3280a9
 
3280a9
 
3280a9
 /*
3280a9
- * slapi_eq_cancel: cancel a pending event.
3280a9
+ * slapi_eq_cancel_rel: cancel a pending event.
3280a9
  * Arguments:
3280a9
  *  ctx: the context of the event which should be de-scheduled
3280a9
  */
3280a9
 int
3280a9
-slapi_eq_cancel(Slapi_Eq_Context ctx)
3280a9
+slapi_eq_cancel_rel(Slapi_Eq_Context ctx)
3280a9
 {
3280a9
     slapi_eq_context **p, *tmp = NULL;
3280a9
     int found = 0;
3280a9
 
3280a9
-    PR_ASSERT(eq_initialized);
3280a9
-    if (!eq_stopped) {
3280a9
-        pthread_mutex_lock(&(eq->eq_lock));
3280a9
-        p = &(eq->eq_queue);
3280a9
+    PR_ASSERT(eq_rel_initialized);
3280a9
+    if (!eq_rel_stopped) {
3280a9
+        pthread_mutex_lock(&(eq_rel->eq_lock));
3280a9
+        p = &(eq_rel->eq_queue);
3280a9
         while (!found && *p != NULL) {
3280a9
             if ((*p)->ec_id == ctx) {
3280a9
                 tmp = *p;
3280a9
@@ -182,7 +182,7 @@ slapi_eq_cancel(Slapi_Eq_Context ctx)
3280a9
                 p = &((*p)->ec_next);
3280a9
             }
3280a9
         }
3280a9
-        pthread_mutex_unlock(&(eq->eq_lock));
3280a9
+        pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
     }
3280a9
     slapi_log_err(SLAPI_LOG_HOUSE, NULL,
3280a9
                   "cancellation of event id %p requested: %s\n",
3280a9
@@ -195,7 +195,7 @@ slapi_eq_cancel(Slapi_Eq_Context ctx)
3280a9
  * Construct a new ec structure
3280a9
  */
3280a9
 static slapi_eq_context *
3280a9
-eq_new(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
3280a9
+eq_new_rel(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
3280a9
 {
3280a9
     slapi_eq_context *retptr = (slapi_eq_context *)slapi_ch_calloc(1, sizeof(slapi_eq_context));
3280a9
 
3280a9
@@ -218,14 +218,14 @@ eq_new(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval)
3280a9
  * Add a new event to the event queue.
3280a9
  */
3280a9
 static void
3280a9
-eq_enqueue(slapi_eq_context *newec)
3280a9
+eq_enqueue_rel(slapi_eq_context *newec)
3280a9
 {
3280a9
     slapi_eq_context **p;
3280a9
 
3280a9
     PR_ASSERT(NULL != newec);
3280a9
-    pthread_mutex_lock(&(eq->eq_lock));
3280a9
+    pthread_mutex_lock(&(eq_rel->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
+    for (p = &(eq_rel->eq_queue); *p != NULL; p = &((*p)->ec_next)) {
3280a9
         if ((*p)->ec_when > newec->ec_when) {
3280a9
             break;
3280a9
         }
3280a9
@@ -236,8 +236,8 @@ eq_enqueue(slapi_eq_context *newec)
3280a9
         newec->ec_next = NULL;
3280a9
     }
3280a9
     *p = newec;
3280a9
-    pthread_cond_signal(&(eq->eq_cv)); /* wake up scheduler thread */
3280a9
-    pthread_mutex_unlock(&(eq->eq_lock));
3280a9
+    pthread_cond_signal(&(eq_rel->eq_cv)); /* wake up scheduler thread */
3280a9
+    pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
 }
3280a9
 
3280a9
 
3280a9
@@ -247,16 +247,16 @@ eq_enqueue(slapi_eq_context *newec)
3280a9
  * to it. Otherwise, return NULL.
3280a9
  */
3280a9
 static slapi_eq_context *
3280a9
-eq_dequeue(time_t now)
3280a9
+eq_dequeue_rel(time_t now)
3280a9
 {
3280a9
     slapi_eq_context *retptr = NULL;
3280a9
 
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
+    pthread_mutex_lock(&(eq_rel->eq_lock));
3280a9
+    if (NULL != eq_rel->eq_queue && eq_rel->eq_queue->ec_when <= now) {
3280a9
+        retptr = eq_rel->eq_queue;
3280a9
+        eq_rel->eq_queue = retptr->ec_next;
3280a9
     }
3280a9
-    pthread_mutex_unlock(&(eq->eq_lock));
3280a9
+    pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
     return retptr;
3280a9
 }
3280a9
 
3280a9
@@ -268,12 +268,12 @@ eq_dequeue(time_t now)
3280a9
  * by calling the function repeatedly.
3280a9
  */
3280a9
 static void
3280a9
-eq_call_all(void)
3280a9
+eq_call_all_rel(void)
3280a9
 {
3280a9
     slapi_eq_context *p;
3280a9
     time_t curtime = slapi_current_rel_time_t();
3280a9
 
3280a9
-    while ((p = eq_dequeue(curtime)) != NULL) {
3280a9
+    while ((p = eq_dequeue_rel(curtime)) != NULL) {
3280a9
         /* Call the scheduled function */
3280a9
         p->ec_fn(p->ec_when, p->ec_arg);
3280a9
         slapi_log_err(SLAPI_LOG_HOUSE, NULL,
3280a9
@@ -284,7 +284,7 @@ eq_call_all(void)
3280a9
             do {
3280a9
                 p->ec_when += p->ec_interval;
3280a9
             } while (p->ec_when < curtime);
3280a9
-            eq_enqueue(p);
3280a9
+            eq_enqueue_rel(p);
3280a9
         } else {
3280a9
             slapi_ch_free((void **)&p);
3280a9
         }
3280a9
@@ -296,38 +296,38 @@ eq_call_all(void)
3280a9
  * The main event queue loop.
3280a9
  */
3280a9
 static void
3280a9
-eq_loop(void *arg __attribute__((unused)))
3280a9
+eq_loop_rel(void *arg __attribute__((unused)))
3280a9
 {
3280a9
-    while (eq_running) {
3280a9
+    while (eq_rel_running) {
3280a9
         time_t curtime = slapi_current_rel_time_t();
3280a9
         int until;
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
-                pthread_mutex_unlock(&(eq->eq_lock));
3280a9
+        pthread_mutex_lock(&(eq_rel->eq_lock));
3280a9
+        while (!((NULL != eq_rel->eq_queue) && (eq_rel->eq_queue->ec_when <= curtime))) {
3280a9
+            if (!eq_rel_running) {
3280a9
+                pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
                 goto bye;
3280a9
             }
3280a9
             /* Compute new timeout */
3280a9
-            if (NULL != eq->eq_queue) {
3280a9
+            if (NULL != eq_rel->eq_queue) {
3280a9
                 struct timespec current_time = slapi_current_rel_time_hr();
3280a9
-                until = eq->eq_queue->ec_when - curtime;
3280a9
+                until = eq_rel->eq_queue->ec_when - curtime;
3280a9
                 current_time.tv_sec += until;
3280a9
-                pthread_cond_timedwait(&eq->eq_cv, &eq->eq_lock, &current_time);
3280a9
+                pthread_cond_timedwait(&eq_rel->eq_cv, &eq_rel->eq_lock, &current_time);
3280a9
             } else {
3280a9
-                pthread_cond_wait(&eq->eq_cv, &eq->eq_lock);
3280a9
+                pthread_cond_wait(&eq_rel->eq_cv, &eq_rel->eq_lock);
3280a9
             }
3280a9
             curtime = slapi_current_rel_time_t();
3280a9
         }
3280a9
         /* There is some work to do */
3280a9
-        pthread_mutex_unlock(&(eq->eq_lock));
3280a9
-        eq_call_all();
3280a9
+        pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
+        eq_call_all_rel();
3280a9
     }
3280a9
 bye:
3280a9
-    eq_stopped = 1;
3280a9
-    pthread_mutex_lock(&ss_lock);
3280a9
-    pthread_cond_broadcast(&ss_cv);
3280a9
-    pthread_mutex_unlock(&ss_lock);
3280a9
+    eq_rel_stopped = 1;
3280a9
+    pthread_mutex_lock(&ss_rel_lock);
3280a9
+    pthread_cond_broadcast(&ss_rel_cv);
3280a9
+    pthread_mutex_unlock(&ss_rel_lock);
3280a9
 }
3280a9
 
3280a9
 
3280a9
@@ -335,73 +335,73 @@ bye:
3280a9
  * Allocate and initialize the event queue structures.
3280a9
  */
3280a9
 static PRStatus
3280a9
-eq_create(void)
3280a9
+eq_create_rel(void)
3280a9
 {
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
+    if (pthread_mutex_init(&eq_rel->eq_lock, NULL) != 0) {
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create_rel",
3280a9
                       "Failed to create 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, "eq_create",
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create_rel",
3280a9
                       "Failed to 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, "eq_create",
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create_rel",
3280a9
                       "Cannot set condition attr clock. error %d (%s)\n",
3280a9
                       rc, strerror(rc));
3280a9
         exit(1);
3280a9
     }
3280a9
-    if ((rc = pthread_cond_init(&eq->eq_cv, &condAttr)) != 0) {
3280a9
-        slapi_log_err(SLAPI_LOG_ERR, "eq_create",
3280a9
+    if ((rc = pthread_cond_init(&eq_rel->eq_cv, &condAttr)) != 0) {
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create_rel",
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
+    if (pthread_mutex_init(&ss_rel_lock, NULL) != 0) {
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create_rel",
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
+    if ((rc = pthread_cond_init(&ss_rel_cv, &condAttr)) != 0) {
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_create_rel",
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
+    eq_rel->eq_queue = NULL;
3280a9
+    eq_rel_initialized = 1;
3280a9
     return PR_SUCCESS;
3280a9
 }
3280a9
 
3280a9
 
3280a9
 /*
3280a9
- * eq_start: start the event queue system.
3280a9
+ * eq_start_rel: start the event queue system.
3280a9
  *
3280a9
  * This should be called exactly once. It will start a
3280a9
  * thread which wakes up periodically and schedules events.
3280a9
  */
3280a9
 void
3280a9
-eq_start()
3280a9
+eq_start_rel()
3280a9
 {
3280a9
-    PR_ASSERT(eq_initialized);
3280a9
-    eq_running = 1;
3280a9
-    if ((eq_loop_tid = PR_CreateThread(PR_USER_THREAD, (VFP)eq_loop,
3280a9
+    PR_ASSERT(eq_rel_initialized);
3280a9
+    eq_rel_running = 1;
3280a9
+    if ((eq_loop_rel_tid = PR_CreateThread(PR_USER_THREAD, (VFP)eq_loop_rel,
3280a9
                                        NULL, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_JOINABLE_THREAD,
3280a9
                                        SLAPD_DEFAULT_THREAD_STACKSIZE)) == NULL) {
3280a9
-        slapi_log_err(SLAPI_LOG_ERR, "eq_start", "eq_loop PR_CreateThread failed\n");
3280a9
+        slapi_log_err(SLAPI_LOG_ERR, "eq_start_rel", "eq_loop_rel PR_CreateThread failed\n");
3280a9
         exit(1);
3280a9
     }
3280a9
     slapi_log_err(SLAPI_LOG_HOUSE, NULL, "event queue services have started\n");
3280a9
@@ -409,55 +409,55 @@ eq_start()
3280a9
 
3280a9
 
3280a9
 /*
3280a9
- * eq_init: initialize the event queue system.
3280a9
+ * eq_init_rel: initialize the event queue system.
3280a9
  *
3280a9
  * This function should be called early in server startup.
3280a9
  * Once it has been called, the event queue will queue
3280a9
  * events, but will not fire any events. Once all of the
3280a9
- * server plugins have been started, the eq_start()
3280a9
+ * server plugins have been started, the eq_start_rel()
3280a9
  * function should be called, and events will then start
3280a9
  * to fire.
3280a9
  */
3280a9
 void
3280a9
-eq_init()
3280a9
+eq_init_rel()
3280a9
 {
3280a9
-    if (!eq_initialized) {
3280a9
-        if (PR_SUCCESS != PR_CallOnce(&init_once, eq_create)) {
3280a9
-            slapi_log_err(SLAPI_LOG_ERR, "eq_init", "eq_create failed\n");
3280a9
+    if (!eq_rel_initialized) {
3280a9
+        if (PR_SUCCESS != PR_CallOnce(&init_once_rel, eq_create_rel)) {
3280a9
+            slapi_log_err(SLAPI_LOG_ERR, "eq_init_rel", "eq_create_rel failed\n");
3280a9
         }
3280a9
     }
3280a9
 }
3280a9
 
3280a9
 
3280a9
 /*
3280a9
- * eq_stop: shut down the event queue system.
3280a9
+ * eq_stop_rel: shut down the event queue system.
3280a9
  * Does not return until event queue is fully
3280a9
  * shut down.
3280a9
  */
3280a9
 void
3280a9
-eq_stop()
3280a9
+eq_stop_rel()
3280a9
 {
3280a9
     slapi_eq_context *p, *q;
3280a9
 
3280a9
-    if (NULL == eq) { /* never started */
3280a9
-        eq_stopped = 1;
3280a9
+    if (NULL == eq_rel) { /* never started */
3280a9
+        eq_rel_stopped = 1;
3280a9
         return;
3280a9
     }
3280a9
 
3280a9
-    eq_stopped = 0;
3280a9
-    eq_running = 0;
3280a9
+    eq_rel_stopped = 0;
3280a9
+    eq_rel_running = 0;
3280a9
     /*
3280a9
      * Signal the eq thread function to stop, and wait until
3280a9
-     * it acknowledges by setting eq_stopped.
3280a9
+     * it acknowledges by setting eq_rel_stopped.
3280a9
      */
3280a9
-    while (!eq_stopped) {
3280a9
+    while (!eq_rel_stopped) {
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
+        pthread_mutex_lock(&(eq_rel->eq_lock));
3280a9
+        pthread_cond_broadcast(&(eq_rel->eq_cv));
3280a9
+        pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
 
3280a9
-        pthread_mutex_lock(&ss_lock);
3280a9
+        pthread_mutex_lock(&ss_rel_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
@@ -467,10 +467,10 @@ eq_stop()
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
+        pthread_cond_timedwait(&ss_rel_cv, &ss_rel_lock, &current_time);
3280a9
+        pthread_mutex_unlock(&ss_rel_lock);
3280a9
     }
3280a9
-    (void)PR_JoinThread(eq_loop_tid);
3280a9
+    (void)PR_JoinThread(eq_loop_rel_tid);
3280a9
     /*
3280a9
      * XXXggood we don't free the actual event queue data structures.
3280a9
      * This is intentional, to allow enqueueing/cancellation of events
3280a9
@@ -478,8 +478,8 @@ eq_stop()
3280a9
      * The downside is that the event queue can't be stopped and restarted
3280a9
      * easily.
3280a9
      */
3280a9
-    pthread_mutex_lock(&(eq->eq_lock));
3280a9
-    p = eq->eq_queue;
3280a9
+    pthread_mutex_lock(&(eq_rel->eq_lock));
3280a9
+    p = eq_rel->eq_queue;
3280a9
     while (p != NULL) {
3280a9
         q = p->ec_next;
3280a9
         slapi_ch_free((void **)&p);
3280a9
@@ -489,7 +489,7 @@ eq_stop()
3280a9
          */
3280a9
         p = q;
3280a9
     }
3280a9
-    pthread_mutex_unlock(&(eq->eq_lock));
3280a9
+    pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
     slapi_log_err(SLAPI_LOG_HOUSE, NULL, "event queue services have shut down\n");
3280a9
 }
3280a9
 
3280a9
@@ -497,23 +497,23 @@ eq_stop()
3280a9
  * return arg (ec_arg) only if the context is in the event queue
3280a9
  */
3280a9
 void *
3280a9
-slapi_eq_get_arg(Slapi_Eq_Context ctx)
3280a9
+slapi_eq_get_arg_rel(Slapi_Eq_Context ctx)
3280a9
 {
3280a9
     slapi_eq_context **p;
3280a9
 
3280a9
-    PR_ASSERT(eq_initialized);
3280a9
-    if (eq && !eq_stopped) {
3280a9
-        pthread_mutex_lock(&(eq->eq_lock));
3280a9
-        p = &(eq->eq_queue);
3280a9
+    PR_ASSERT(eq_rel_initialized);
3280a9
+    if (eq_rel && !eq_rel_stopped) {
3280a9
+        pthread_mutex_lock(&(eq_rel->eq_lock));
3280a9
+        p = &(eq_rel->eq_queue);
3280a9
         while (p && *p != NULL) {
3280a9
             if ((*p)->ec_id == ctx) {
3280a9
-                pthread_mutex_unlock(&(eq->eq_lock));
3280a9
+                pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
                 return (*p)->ec_arg;
3280a9
             } else {
3280a9
                 p = &((*p)->ec_next);
3280a9
             }
3280a9
         }
3280a9
-        pthread_mutex_unlock(&(eq->eq_lock));
3280a9
+        pthread_mutex_unlock(&(eq_rel->eq_lock));
3280a9
     }
3280a9
     return NULL;
3280a9
 }
3280a9
diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c
3280a9
index 104f6826c..dbc8cec15 100644
3280a9
--- a/ldap/servers/slapd/main.c
3280a9
+++ b/ldap/servers/slapd/main.c
3280a9
@@ -979,7 +979,8 @@ main(int argc, char **argv)
3280a9
         fedse_create_startOK(DSE_FILENAME, DSE_STARTOKFILE,
3280a9
                              slapdFrontendConfig->configdir);
3280a9
 
3280a9
-        eq_init(); /* must be done before plugins started */
3280a9
+        eq_init(); /* DEPRECATED */
3280a9
+        eq_init_rel(); /* must be done before plugins started */
3280a9
 
3280a9
         /* Start the SNMP collator if counters are enabled. */
3280a9
         if (config_get_slapi_counters()) {
3280a9
@@ -1035,7 +1036,8 @@ main(int argc, char **argv)
3280a9
             goto cleanup;
3280a9
         }
3280a9
 
3280a9
-        eq_start(); /* must be done after plugins started */
3280a9
+        eq_start(); /* must be done after plugins started - DEPRECATED */
3280a9
+        eq_start_rel(); /* must be done after plugins started */
3280a9
 
3280a9
 #ifdef HPUX10
3280a9
         /* HPUX linker voodoo */
3280a9
@@ -2205,10 +2207,13 @@ slapd_exemode_db2ldif(int argc, char **argv, struct main_config *mcfg)
3280a9
              */
3280a9
             plugin_get_plugin_dependencies(repl_plg_name, &plugin_list);
3280a9
 
3280a9
-            eq_init();                /* must be done before plugins started */
3280a9
+            eq_init(); /* must be done before plugins started - DEPRECATED */
3280a9
+            eq_init_rel(); /* must be done before plugins started */
3280a9
+
3280a9
             ps_init_psearch_system(); /* must come before plugin_startall() */
3280a9
             plugin_startall(argc, argv, plugin_list);
3280a9
-            eq_start(); /* must be done after plugins started */
3280a9
+            eq_start(); /* must be done after plugins started - DEPRECATED*/
3280a9
+            eq_start_rel(); /* must be done after plugins started */
3280a9
             charray_free(plugin_list);
3280a9
         }
3280a9
 
3280a9
@@ -2263,8 +2268,9 @@ slapd_exemode_db2ldif(int argc, char **argv, struct main_config *mcfg)
3280a9
     charray_free(mcfg->cmd_line_instance_names);
3280a9
     charray_free(mcfg->db2ldif_include);
3280a9
     if (mcfg->db2ldif_dump_replica) {
3280a9
-        eq_stop(); /* event queue should be shutdown before closing
3280a9
-                              all plugins (especailly, replication plugin) */
3280a9
+        eq_stop(); /* DEPRECATED*/
3280a9
+        eq_stop_rel(); /* event queue should be shutdown before closing
3280a9
+                          all plugins (especially, replication plugin) */
3280a9
         plugin_closeall(1 /* Close Backends */, 1 /* Close Globals */);
3280a9
     }
3280a9
     return (return_value);
3280a9
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
3280a9
index 3acc24f03..87080dd82 100644
3280a9
--- a/ldap/servers/slapd/proto-slap.h
3280a9
+++ b/ldap/servers/slapd/proto-slap.h
3280a9
@@ -1322,7 +1322,6 @@ void factory_destroy_extension(int type, void *object, void *parent, void **exte
3280a9
 /*
3280a9
  * auditlog.c
3280a9
  */
3280a9
-
3280a9
 void write_audit_log_entry(Slapi_PBlock *pb);
3280a9
 void auditlog_hide_unhashed_pw(void);
3280a9
 void auditlog_expose_unhashed_pw(void);
3280a9
@@ -1334,10 +1333,15 @@ void auditfaillog_expose_unhashed_pw(void);
3280a9
 /*
3280a9
  * eventq.c
3280a9
  */
3280a9
+void eq_init_rel(void);
3280a9
+void eq_start_rel(void);
3280a9
+void eq_stop_rel(void);
3280a9
+/* Deprecated eventq that uses REALTIME clock instead of MONOTONIC */
3280a9
 void eq_init(void);
3280a9
 void eq_start(void);
3280a9
 void eq_stop(void);
3280a9
 
3280a9
+
3280a9
 /*
3280a9
  * uniqueidgen.c
3280a9
  */
3280a9
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
3280a9
index 55ded5eb8..f76b86e3c 100644
3280a9
--- a/ldap/servers/slapd/slapi-plugin.h
3280a9
+++ b/ldap/servers/slapd/slapi-plugin.h
3280a9
@@ -6084,7 +6084,7 @@ void slapi_lock_mutex(Slapi_Mutex *mutex);
3280a9
 int slapi_unlock_mutex(Slapi_Mutex *mutex);
3280a9
 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_wait_condvar(Slapi_CondVar *cvar, struct timeval *timeout) __attribute__((deprecated));
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
@@ -8059,24 +8059,24 @@ typedef void (*slapi_eq_fn_t)(time_t when, void *arg);
3280a9
  *
3280a9
  * \param fn The function to call when the event is triggered.
3280a9
  * \param arg An argument to pass to the called function.
3280a9
- * \param when The time that the function should be called.
3280a9
+ * \param when The time that the function should be called(MONOTONIC clock).
3280a9
  *
3280a9
  * \return slapi_eq_context
3280a9
  */
3280a9
-Slapi_Eq_Context slapi_eq_once(slapi_eq_fn_t fn, void *arg, time_t when);
3280a9
+Slapi_Eq_Context slapi_eq_once_rel(slapi_eq_fn_t fn, void *arg, time_t when);
3280a9
 
3280a9
 /**
3280a9
  * Cause an event to happen repeatedly.
3280a9
  *
3280a9
  * \param fn The function to call when the vent is triggered.
3280a9
  * \param arg An argument to pass to the called function.
3280a9
- * \param when The time that the function should be called.
3280a9
+ * \param when The time that the function should be called(MONOTONIC clock).
3280a9
  * \param interval The amount of time (in milliseconds) between
3280a9
  *                 successive calls to the function.
3280a9
  *
3280a9
  * \return slapi_eq_context
3280a9
  */
3280a9
-Slapi_Eq_Context slapi_eq_repeat(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval);
3280a9
+Slapi_Eq_Context slapi_eq_repeat_rel(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval);
3280a9
 
3280a9
 /**
3280a9
  * Cause a scheduled event to be canceled.
3280a9
@@ -8086,7 +8086,7 @@ Slapi_Eq_Context slapi_eq_repeat(slapi_eq_fn_t fn, void *arg, time_t when, unsig
3280a9
  * \return 1 If event was found and canceled.
3280a9
  * \return 0 If event was not found in the queue.
3280a9
  */
3280a9
-int slapi_eq_cancel(Slapi_Eq_Context ctx);
3280a9
+int slapi_eq_cancel_rel(Slapi_Eq_Context ctx);
3280a9
 
3280a9
 /**
3280a9
  * Return the event's argument.
3280a9
@@ -8095,7 +8095,55 @@ int slapi_eq_cancel(Slapi_Eq_Context ctx);
3280a9
  *
3280a9
  * \return A pointer to the event argument.
3280a9
  */
3280a9
-void *slapi_eq_get_arg(Slapi_Eq_Context ctx);
3280a9
+void *slapi_eq_get_arg_rel(Slapi_Eq_Context ctx);
3280a9
+
3280a9
+/*
3280a9
+ * These event queue functions are now DEPRECATED as they REALTIME clocks
3280a9
+ * instead of the preferred MONOTONIC clocks.
3280a9
+ */
3280a9
+
3280a9
+/**
3280a9
+ * Cause an event to happen exactly once.
3280a9
+ *
3280a9
+ * \param fn The function to call when the event is triggered.
3280a9
+ * \param arg An argument to pass to the called function.
3280a9
+ * \param when The time that the function should be called(REALTIME clock).
3280a9
+ *
3280a9
+ * \return slapi_eq_context
3280a9
+ */
3280a9
+Slapi_Eq_Context slapi_eq_once(slapi_eq_fn_t fn, void *arg, time_t when) __attribute__((deprecated));
3280a9
+
3280a9
+/**
3280a9
+ * Cause an event to happen repeatedly.
3280a9
+ *
3280a9
+ * \param fn The function to call when the vent is triggered.
3280a9
+ * \param arg An argument to pass to the called function.
3280a9
+ * \param when The time that the function should be called(REALTIME clock).
3280a9
+ * \param interval The amount of time (in milliseconds) between
3280a9
+ *                 successive calls to the function.
3280a9
+ *
3280a9
+ * \return slapi_eq_context
3280a9
+ */
3280a9
+Slapi_Eq_Context slapi_eq_repeat(slapi_eq_fn_t fn, void *arg, time_t when, unsigned long interval) __attribute__((deprecated));
3280a9
+
3280a9
+/**
3280a9
+ * Cause a scheduled event to be canceled.
3280a9
+ *
3280a9
+ * \param ctx The event object to cancel
3280a9
+ *
3280a9
+ * \return 1 If event was found and canceled.
3280a9
+ * \return 0 If event was not found in the queue.
3280a9
+ */
3280a9
+int slapi_eq_cancel(Slapi_Eq_Context ctx) __attribute__((deprecated));
3280a9
+
3280a9
+/**
3280a9
+ * Return the event's argument.
3280a9
+ *
3280a9
+ * \param ctx The event object
3280a9
+ *
3280a9
+ * \return A pointer to the event argument.
3280a9
+ */
3280a9
+void *slapi_eq_get_arg(Slapi_Eq_Context ctx) __attribute__((deprecated));
3280a9
 
3280a9
 /**
3280a9
  * Construct a full path and name of a plugin.
3280a9
diff --git a/ldap/servers/slapd/slapi2runtime.c b/ldap/servers/slapd/slapi2runtime.c
3280a9
index 85dc4c9a8..53927934a 100644
3280a9
--- a/ldap/servers/slapd/slapi2runtime.c
3280a9
+++ b/ldap/servers/slapd/slapi2runtime.c
3280a9
@@ -133,7 +133,7 @@ slapi_destroy_condvar(Slapi_CondVar *cvar)
3280a9
 
3280a9
 
3280a9
 /*
3280a9
- * Function: slapi_wait_condvar
3280a9
+ * Function: slapi_wait_condvar (DEPRECATED)
3280a9
  * Description: behaves just like PR_WaitCondVar() except timeout is
3280a9
  *    in seconds and microseconds instead of PRIntervalTime units.
3280a9
  *    If timeout is NULL, this call blocks indefinitely.
3280a9
@@ -145,9 +145,26 @@ slapi_destroy_condvar(Slapi_CondVar *cvar)
3280a9
 int
3280a9
 slapi_wait_condvar(Slapi_CondVar *cvar, struct timeval *timeout)
3280a9
 {
3280a9
-    /* deprecated in favor of slapi_wait_condvar_pt() which requires that the
3280a9
+    /* Deprecated in favor of slapi_wait_condvar_pt() which requires that the
3280a9
      * mutex be passed in */
3280a9
-    return (0);
3280a9
+    PRIntervalTime prit;
3280a9
+
3280a9
+    if (cvar == NULL) {
3280a9
+        return (0);
3280a9
+    }
3280a9
+
3280a9
+    if (timeout == NULL) {
3280a9
+        prit = PR_INTERVAL_NO_TIMEOUT;
3280a9
+    } else {
3280a9
+        prit = PR_SecondsToInterval(timeout->tv_sec) + PR_MicrosecondsToInterval(timeout->tv_usec);
3280a9
+    }
3280a9
+
3280a9
+    if (PR_WaitCondVar((PRCondVar *)cvar, prit) != PR_SUCCESS) {
3280a9
+        return (0);
3280a9
+    }
3280a9
+
3280a9
+    return (1);
3280a9
+
3280a9
 }
3280a9
 
3280a9
 int
3280a9
diff --git a/ldap/servers/slapd/snmp_collator.c b/ldap/servers/slapd/snmp_collator.c
3280a9
index 3dd3af657..d760515f4 100644
3280a9
--- a/ldap/servers/slapd/snmp_collator.c
3280a9
+++ b/ldap/servers/slapd/snmp_collator.c
3280a9
@@ -385,8 +385,9 @@ snmp_collator_start()
3280a9
     snmp_collator_init();
3280a9
 
3280a9
     /* Arrange to be called back periodically to update the mmap'd stats file. */
3280a9
-    snmp_eq_ctx = slapi_eq_repeat(snmp_collator_update, NULL, (time_t)0,
3280a9
-                                  SLAPD_SNMP_UPDATE_INTERVAL);
3280a9
+    snmp_eq_ctx = slapi_eq_repeat_rel(snmp_collator_update, NULL,
3280a9
+                                      slapi_current_rel_time_t(),
3280a9
+                                      SLAPD_SNMP_UPDATE_INTERVAL);
3280a9
     return 0;
3280a9
 }
3280a9
 
3280a9
@@ -411,7 +412,7 @@ snmp_collator_stop()
3280a9
     }
3280a9
 
3280a9
     /* Abort any pending events */
3280a9
-    slapi_eq_cancel(snmp_eq_ctx);
3280a9
+    slapi_eq_cancel_rel(snmp_eq_ctx);
3280a9
     snmp_collator_stopped = 1;
3280a9
 
3280a9
     /* acquire the semaphore */
3280a9
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
3280a9
index 26f281cba..bded287c6 100644
3280a9
--- a/ldap/servers/slapd/task.c
3280a9
+++ b/ldap/servers/slapd/task.c
3280a9
@@ -387,7 +387,7 @@ slapi_task_status_changed(Slapi_Task *task)
3280a9
                 ttl = (24*3600); /* be reasonable, allow to check task status not longer than one day  */
3280a9
             task->task_flags |= SLAPI_TASK_DESTROYING;
3280a9
             /* queue an event to destroy the state info */
3280a9
-            slapi_eq_once(destroy_task, (void *)task, slapi_current_rel_time_t() + ttl);
3280a9
+            slapi_eq_once_rel(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/uuid.c b/ldap/servers/slapd/uuid.c
3280a9
index a8bd6ee6c..31384a544 100644
3280a9
--- a/ldap/servers/slapd/uuid.c
3280a9
+++ b/ldap/servers/slapd/uuid.c
3280a9
@@ -186,7 +186,8 @@ uuid_init(const char *configDir, const Slapi_DN *configDN, PRBool mtGen)
3280a9
 
3280a9
     /* schedule update task for multithreaded generation */
3280a9
     if (_state.mtGen)
3280a9
-        slapi_eq_repeat(uuid_update_state, NULL, (time_t)0, UPDATE_INTERVAL);
3280a9
+        slapi_eq_repeat_rel(uuid_update_state, NULL, slapi_current_rel_time_t(),
3280a9
+                            UPDATE_INTERVAL);
3280a9
 
3280a9
     _state.initialized = PR_TRUE;
3280a9
     return UUID_SUCCESS;
3280a9
-- 
3280a9
2.26.2
3280a9