Index: trunk/test/t-0000375.c
===================================================================
--- trunk/test/t-0000375.c	(Revision 0)
+++ trunk/test/t-0000375.c	(Revision 0)
@@ -0,0 +1,78 @@
+#include "/inc/base.inc"
+
+/* These functions are for the clone (the player object). */
+void start_client()
+{
+    net_connect("127.0.0.1", query_mud_port());
+    set_heart_beat(1);
+}
+
+int logon(int flag)
+{
+    enable_telnet(0);
+    set_prompt("");
+
+    return 1;
+}
+
+object connect()
+{
+   enable_telnet(0);
+   set_prompt("");
+
+   return clone_object(this_object());
+}
+
+void fun(int* oldtime)
+{
+    int* now = utime();
+
+    remove_call_out(#'shutdown);
+
+    // Is there a time difference of
+    // at least 0.5 seconds?
+    if (oldtime[1] < 500000)
+        oldtime[1] += 500000;
+    else
+    {
+        oldtime[1] -= 500000;
+        oldtime[0] += 1;
+    }
+
+    if ((oldtime[0] == now[0])
+       ?(oldtime[1] < now[1])
+       :(oldtime[0] < now[0]))
+        shutdown(0);
+    else
+        shutdown(1);
+}
+
+void heart_beat()
+{
+    call_out("fun", __ALARM_TIME__, utime());
+}
+
+void run_test()
+{
+    int result;
+
+    msg("\nRunning test for #0000375:\n"
+        "--------------------------\n");
+
+    call_out("run_test2", 0);
+}
+
+void run_test2()
+{
+    object dummy;
+    dummy = clone_object(this_object());
+    dummy->start_client();
+
+    call_out(#'shutdown, (__HEART_BEAT_INTERVAL__+__ALARM_TIME__)*2, 1); // Just to make sure.
+}
+
+string *epilog(int eflag)
+{
+    run_test();
+    return 0;
+}
Index: trunk/src/call_out.c
===================================================================
--- trunk/src/call_out.c	(Revision 2592)
+++ trunk/src/call_out.c	(Arbeitskopie)
@@ -216,28 +216,19 @@
     return sp;
 } /* v_call_out() */
 
+
 /*-------------------------------------------------------------------------*/
 void
-call_out (void)
+next_call_out_cycle (void)
 
-/* Check if there is any callout due to be called. If yes, do so.
- * This function is called from the heart_beat handling in the backend.c.
- * It sets up its own error recovery context so that errors during an
- * execution won't disturb the rest of the game.
+/* Starts the next call_out cycle by decrementing the first delta.
+ * This function is called in the backend cycle before heart_beats are handled.
  */
 
 {
     static int last_time;
       /* Last time this function was called */
 
-    static struct call *current_call_out;
-      /* Current callout, static so that longjmp() won't clobber it. */
-
-    static object_t *called_object;
-      /* Object last called, static so that longjmp() won't clobber it */
-
-    struct error_recovery_info error_recovery_info;
-
     /* No calls pending: just update the last_time and return */
 
     if (call_list == NULL)
@@ -250,12 +241,38 @@
     if (last_time == 0)
         last_time = current_time;
 
-    /* Update the first .delta in the list (so it won't happen
-     * twice in case of an error.
+    /* Update the first .delta in the list.
      */
     call_list->delta -= current_time - last_time;
 
     last_time = current_time;
+} /* next_call_out_cycle() */
+
+
+/*-------------------------------------------------------------------------*/
+void
+call_out (void)
+
+/* Check if there is any callout due to be called. If yes, do so.
+ * This function is called from the heart_beat handling in the backend.c.
+ * It sets up its own error recovery context so that errors during an
+ * execution won't disturb the rest of the game.
+ */
+
+{
+    static struct call *current_call_out;
+      /* Current callout, static so that longjmp() won't clobber it. */
+
+    static object_t *called_object;
+      /* Object last called, static so that longjmp() won't clobber it */
+
+    struct error_recovery_info error_recovery_info;
+
+    /* No calls pending: fine. */
+
+    if (call_list == NULL)
+        return;
+
     current_interactive = NULL;
 
     /* Activate the local error recovery context */
Index: trunk/src/call_out.h
===================================================================
--- trunk/src/call_out.h	(Revision 2592)
+++ trunk/src/call_out.h	(Arbeitskopie)
@@ -8,6 +8,7 @@
 /* --- Prototypes --- */
 
 extern void  call_out(void);
+extern void  next_call_out_cycle(void);
 extern size_t  call_out_status(strbuf_t *sbuf, Bool verbose);
 extern void  callout_dinfo_status(svalue_t *svp, int value);
 extern void  remove_stale_call_outs(void);
Index: trunk/src/backend.c
===================================================================
--- trunk/src/backend.c	(Revision 2592)
+++ trunk/src/backend.c	(Arbeitskopie)
@@ -717,6 +717,11 @@
             time_to_call_heart_beat = MY_FALSE;
             alarm(alarm_time);
 
+            /* So call_outs from heart_beats are
+             * correctly timed.
+             */
+            next_call_out_cycle();
+
             /* Do the timed events */
 	    if (!synch_heart_beats
              || time_of_last_hb + heart_beat_interval <= current_time)
