From a4eb8fc49b078d17cc7c502bd2ace36195ef1be9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 19 Dec 2005 21:52:37 +0000 Subject: r12372: - make the periodic scheduling a bit easier, instead of passing 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 | 5 +-- source4/wrepl_server/wrepl_periodic.c | 78 ++++++++++++++++++++++++++--------- source4/wrepl_server/wrepl_server.h | 8 ---- 3 files changed, 61 insertions(+), 30 deletions(-) (limited to 'source4/wrepl_server') diff --git a/source4/wrepl_server/wrepl_out_push.c b/source4/wrepl_server/wrepl_out_push.c index 0afa6c5704..1d0ad32061 100644 --- a/source4/wrepl_server/wrepl_out_push.c +++ b/source4/wrepl_server/wrepl_out_push.c @@ -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; } diff --git a/source4/wrepl_server/wrepl_periodic.c b/source4/wrepl_server/wrepl_periodic.c index 12e1448139..28c966879a 100644 --- a/source4/wrepl_server/wrepl_periodic.c +++ b/source4/wrepl_server/wrepl_periodic.c @@ -35,33 +35,76 @@ #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; } diff --git a/source4/wrepl_server/wrepl_server.h b/source4/wrepl_server/wrepl_server.h index 9631f0abc8..3c283c1b6f 100644 --- a/source4/wrepl_server/wrepl_server.h +++ b/source4/wrepl_server/wrepl_server.h @@ -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() -- cgit