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

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