mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-27 22:03:31 +01:00
Merge branch 'ticket26064'
This commit is contained in:
commit
beca6a585c
5
changes/ticket26064
Normal file
5
changes/ticket26064
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
o Minor features (accounting):
|
||||||
|
- When we become dormant, use a scheduled event to wake up at the right
|
||||||
|
time. Previously, we would use the per-second timer to check whether
|
||||||
|
to wake up, but we no longer have any per-second timers enabled when
|
||||||
|
the network is disabled. Closes ticket 26064.
|
@ -52,6 +52,10 @@ static time_t hibernate_end_time = 0;
|
|||||||
* we aren't shutting down. */
|
* we aren't shutting down. */
|
||||||
static time_t shutdown_time = 0;
|
static time_t shutdown_time = 0;
|
||||||
|
|
||||||
|
/** A timed event that we'll use when it's time to wake up from
|
||||||
|
* hibernation. */
|
||||||
|
static mainloop_event_t *wakeup_event = NULL;
|
||||||
|
|
||||||
/** Possible accounting periods. */
|
/** Possible accounting periods. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
UNIT_MONTH=1, UNIT_WEEK=2, UNIT_DAY=3,
|
UNIT_MONTH=1, UNIT_WEEK=2, UNIT_DAY=3,
|
||||||
@ -131,6 +135,8 @@ static time_t start_of_accounting_period_after(time_t now);
|
|||||||
static time_t start_of_accounting_period_containing(time_t now);
|
static time_t start_of_accounting_period_containing(time_t now);
|
||||||
static void accounting_set_wakeup_time(void);
|
static void accounting_set_wakeup_time(void);
|
||||||
static void on_hibernate_state_change(hibernate_state_t prev_state);
|
static void on_hibernate_state_change(hibernate_state_t prev_state);
|
||||||
|
static void hibernate_schedule_wakeup_event(time_t now, time_t end_time);
|
||||||
|
static void wakeup_event_callback(mainloop_event_t *ev, void *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the human-readable name for the hibernation state <b>state</b>
|
* Return the human-readable name for the hibernation state <b>state</b>
|
||||||
@ -936,6 +942,63 @@ hibernate_go_dormant(time_t now)
|
|||||||
|
|
||||||
or_state_mark_dirty(get_or_state(),
|
or_state_mark_dirty(get_or_state(),
|
||||||
get_options()->AvoidDiskWrites ? now+600 : 0);
|
get_options()->AvoidDiskWrites ? now+600 : 0);
|
||||||
|
|
||||||
|
hibernate_schedule_wakeup_event(now, hibernate_end_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Schedule a mainloop event at <b>end_time</b> to wake up from a dormant
|
||||||
|
* state. We can't rely on this happening from second_elapsed_callback,
|
||||||
|
* since second_elapsed_callback will be shut down when we're dormant.
|
||||||
|
*
|
||||||
|
* (Note that We might immediately go back to sleep after we set the next
|
||||||
|
* wakeup time.)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
hibernate_schedule_wakeup_event(time_t now, time_t end_time)
|
||||||
|
{
|
||||||
|
struct timeval delay = { 0, 0 };
|
||||||
|
|
||||||
|
if (now >= end_time) {
|
||||||
|
// In these cases we always wait at least a second, to avoid running
|
||||||
|
// the callback in a tight loop.
|
||||||
|
delay.tv_sec = 1;
|
||||||
|
} else {
|
||||||
|
delay.tv_sec = (end_time - now);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!wakeup_event) {
|
||||||
|
wakeup_event = mainloop_event_postloop_new(wakeup_event_callback, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
mainloop_event_schedule(wakeup_event, &delay);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called at the end of the interval, or at the wakeup time of the current
|
||||||
|
* interval, to exit the dormant state.
|
||||||
|
**/
|
||||||
|
static void
|
||||||
|
wakeup_event_callback(mainloop_event_t *ev, void *data)
|
||||||
|
{
|
||||||
|
(void) ev;
|
||||||
|
(void) data;
|
||||||
|
|
||||||
|
const time_t now = time(NULL);
|
||||||
|
accounting_run_housekeeping(now);
|
||||||
|
consider_hibernation(now);
|
||||||
|
if (hibernate_state != HIBERNATE_STATE_DORMANT) {
|
||||||
|
/* We woke up, so everything's great here */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* We're still dormant. */
|
||||||
|
if (now < interval_wakeup_time)
|
||||||
|
hibernate_end_time = interval_wakeup_time;
|
||||||
|
else
|
||||||
|
hibernate_end_time = interval_end_time;
|
||||||
|
|
||||||
|
hibernate_schedule_wakeup_event(now, hibernate_end_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Called when hibernate_end_time has arrived. */
|
/** Called when hibernate_end_time has arrived. */
|
||||||
@ -1126,6 +1189,16 @@ on_hibernate_state_change(hibernate_state_t prev_state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Free all resources held by the accounting module */
|
||||||
|
void
|
||||||
|
accounting_free_all(void)
|
||||||
|
{
|
||||||
|
mainloop_event_free(wakeup_event);
|
||||||
|
hibernate_state = HIBERNATE_STATE_INITIAL;
|
||||||
|
hibernate_end_time = 0;
|
||||||
|
shutdown_time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
/**
|
/**
|
||||||
* Manually change the hibernation state. Private; used only by the unit
|
* Manually change the hibernation state. Private; used only by the unit
|
||||||
|
@ -30,6 +30,7 @@ int getinfo_helper_accounting(control_connection_t *conn,
|
|||||||
const char *question, char **answer,
|
const char *question, char **answer,
|
||||||
const char **errmsg);
|
const char **errmsg);
|
||||||
uint64_t get_accounting_max_total(void);
|
uint64_t get_accounting_max_total(void);
|
||||||
|
void accounting_free_all(void);
|
||||||
|
|
||||||
#ifdef HIBERNATE_PRIVATE
|
#ifdef HIBERNATE_PRIVATE
|
||||||
/** Possible values of hibernate_state */
|
/** Possible values of hibernate_state */
|
||||||
|
@ -3662,6 +3662,8 @@ tor_free_all(int postfork)
|
|||||||
hs_free_all();
|
hs_free_all();
|
||||||
dos_free_all();
|
dos_free_all();
|
||||||
circuitmux_ewma_free_all();
|
circuitmux_ewma_free_all();
|
||||||
|
accounting_free_all();
|
||||||
|
|
||||||
if (!postfork) {
|
if (!postfork) {
|
||||||
config_free_all();
|
config_free_all();
|
||||||
or_state_free_all();
|
or_state_free_all();
|
||||||
|
Loading…
Reference in New Issue
Block a user