diff options
| -rw-r--r-- | source4/wrepl_server/wrepl_out_push.c | 5 | ||||
| -rw-r--r-- | source4/wrepl_server/wrepl_periodic.c | 78 | ||||
| -rw-r--r-- | source4/wrepl_server/wrepl_server.h | 8 | 
3 files changed, 61 insertions, 30 deletions
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; @@ -261,11 +258,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()  		 */  | 
