r12372: - make the periodic scheduling a bit easier, instead of passing
authorStefan Metzmacher <metze@samba.org>
Mon, 19 Dec 2005 21:52:37 +0000 (21:52 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:47:31 +0000 (13:47 -0500)
  an uint32_t next_interval everywhere, we now call wreplsrv_periodic_schedule()
  if we want to schedule an event
- also prevent us from looping with a 0 interval, by using 1s as minimum interval

metze
(This used to be commit b6943b11fc6e501d5081d591336185518943ee5a)

source4/wrepl_server/wrepl_out_push.c
source4/wrepl_server/wrepl_periodic.c
source4/wrepl_server/wrepl_server.h

index 0afa6c570428c924e9516d8425e182fc431e5b5d..1d0ad3206168eff2a1cb5bbd1bf8f960af825189 100644 (file)
@@ -44,7 +44,6 @@ static void wreplsrv_push_handler_creq(struct composite_context *creq)
 
        partner->push.last_status = wreplsrv_push_notify_recv(partner->push.creq);
        partner->push.creq = NULL;
-       partner->push.last_run = timeval_current();
 
        old_notify_io = partner->push.notify_io;
        partner->push.notify_io = NULL;
@@ -112,7 +111,7 @@ static uint32_t wreplsrv_calc_change_count(struct wreplsrv_partner *partner)
        return (uint32_t)-1;
 }
 
-uint32_t wreplsrv_out_push_run(struct wreplsrv_service *service, uint32_t next_interval)
+NTSTATUS wreplsrv_out_push_run(struct wreplsrv_service *service)
 {
        struct wreplsrv_partner *partner;
        uint32_t change_count;
@@ -133,5 +132,5 @@ uint32_t wreplsrv_out_push_run(struct wreplsrv_service *service, uint32_t next_i
                wreplsrv_out_partner_push(partner, False);
        }
 
-       return next_interval;
+       return NT_STATUS_OK;
 }
index 12e1448139c23bc64f27ba2d060ce8cbbdc6a1c4..28c966879ae119f021975f6f6665bc692cbce28a 100644 (file)
 #include "libcli/wrepl/winsrepl.h"
 #include "wrepl_server/wrepl_out_helpers.h"
 
-static uint32_t wreplsrv_periodic_run(struct wreplsrv_service *service, uint32_t next_interval)
+static NTSTATUS wreplsrv_periodic_run(struct wreplsrv_service *service)
 {
-       next_interval = wreplsrv_out_push_run(service, next_interval);
+       NTSTATUS status;
+
+       status = wreplsrv_out_push_run(service);
+       NT_STATUS_NOT_OK_RETURN(status);
 
-       DEBUG(2,("wreplsrv_periodic_run: next in %u secs\n", next_interval));
-       return next_interval;
+       return NT_STATUS_OK;
 }
 
 static void wreplsrv_periodic_handler_te(struct event_context *ev, struct timed_event *te,
                                         struct timeval t, void *ptr)
 {
        struct wreplsrv_service *service = talloc_get_type(ptr, struct wreplsrv_service);
-       uint32_t next_interval;
+       NTSTATUS status;
 
        service->periodic.te = NULL;
-       service->periodic.current_event = t;
-
-       next_interval = wreplsrv_periodic_run(service, service->config.periodic_interval);
 
-       service->periodic.next_event = timeval_current_ofs(next_interval, 0);
-       service->periodic.te = event_add_timed(service->task->event_ctx, service,
-                                              service->periodic.next_event,
-                                              wreplsrv_periodic_handler_te, service);
-       if (!service->periodic.te) {
-               task_server_terminate(service->task,"event_add_timed() failed! no memory!\n");
+       status = wreplsrv_periodic_schedule(service, service->config.periodic_interval);
+       if (!NT_STATUS_IS_OK(status)) {
+               task_server_terminate(service->task, nt_errstr(status));
                return;
        }
+
+       status = wreplsrv_periodic_run(service);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("wresrv_periodic_run() failed: %s\n", nt_errstr(status)));
+       }
+}
+
+NTSTATUS wreplsrv_periodic_schedule(struct wreplsrv_service *service, uint32_t next_interval)
+{
+       TALLOC_CTX *tmp_mem;
+       struct timed_event *new_te;
+       struct timeval next_time;
+
+       /* prevent looping */
+       if (next_interval == 0) next_interval = 1;
+
+       next_time = timeval_current_ofs(next_interval, 0);
+
+       if (service->periodic.te) {
+               /*
+                * if the timestamp of the new event is higher,
+                * as current next we don't need to reschedule
+                */
+               if (timeval_compare(&next_time, &service->periodic.next_event) > 0) {
+                       return NT_STATUS_OK;
+               }
+       }
+
+       /* reset the next scheduled timestamp */
+       service->periodic.next_event = next_time;
+
+       new_te = event_add_timed(service->task->event_ctx, service,
+                                service->periodic.next_event,
+                                wreplsrv_periodic_handler_te, service);
+       NT_STATUS_HAVE_NO_MEMORY(new_te);
+
+       tmp_mem = talloc_new(service);
+       DEBUG(4,("wreplsrv_periodic_schedule(%u) %sscheduled for: %s\n",
+               next_interval,
+               (service->periodic.te?"re":""),
+               nt_time_string(tmp_mem, timeval_to_nttime(&next_time))));
+       talloc_free(tmp_mem);
+
+       talloc_free(service->periodic.te);
+       service->periodic.te = new_te;
+
+       return NT_STATUS_OK;
 }
 
 NTSTATUS wreplsrv_setup_periodic(struct wreplsrv_service *service)
@@ -75,11 +118,8 @@ NTSTATUS wreplsrv_setup_periodic(struct wreplsrv_service *service)
        status = wreplsrv_setup_out_connections(service);
        NT_STATUS_NOT_OK_RETURN(status);
 
-       service->periodic.next_event = timeval_current();
-       service->periodic.te = event_add_timed(service->task->event_ctx, service,
-                                              service->periodic.next_event,
-                                              wreplsrv_periodic_handler_te, service);
-       NT_STATUS_HAVE_NO_MEMORY(service->periodic.te);
+       status = wreplsrv_periodic_schedule(service, 0);
+       NT_STATUS_NOT_OK_RETURN(status);
 
        return NT_STATUS_OK;
 }
index 9631f0abc85bded3f7deb4ec81f9dcde02a42548..3c283c1b6fe7fff4cd92c7720131d7f485cc2e99 100644 (file)
@@ -178,9 +178,6 @@ struct wreplsrv_partner {
                /* the status of the last push cycle */
                NTSTATUS last_status;
 
-               /* the timestamp of the last run */
-               struct timeval last_run;
-
                /* the outgoing connection to the partner */
                struct wreplsrv_out_connection *wreplconn;
 
@@ -260,11 +257,6 @@ struct wreplsrv_service {
 
        /* some stuff for periodic processing */
        struct {
-               /*
-                * the timestamp for the current event,
-                */
-               struct timeval current_event;
-
                /*
                 * the timestamp for the next event,
                 * this is the timstamp passed to event_add_timed()