blob: 9773e4ed1fecb0ac2d1cb23e11e50c962864f61a (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
/** \file cmdline_progress_throttle.cc */ // -*-c++-*-
#include "cmdline_progress_throttle.h"
// Local includes:
#include <loggers.h>
// System includes:
#include <boost/make_shared.hpp>
#include <boost/optional.hpp>
#include <generic/util/util.h>
#include <errno.h>
#include <sys/time.h>
using aptitude::Loggers;
using boost::make_shared;
using boost::optional;
using boost::shared_ptr;
using logging::LoggerPtr;
namespace aptitude
{
namespace cmdline
{
namespace
{
class progress_throttle_impl : public progress_throttle
{
boost::optional<struct timeval> last_update;
logging::LoggerPtr logger;
// Used to ensure that we only warn once about gettimeofday()
// failing.
bool wrote_time_error;
static const double update_interval = 0.7;
void write_time_error(int errnum);
public:
progress_throttle_impl();
/** \return \b true if the progress display should be updated. */
bool update_required();
/** \brief Reset the timer that controls when the display is
* updated.
*/
void reset_timer();
};
const double progress_throttle_impl::update_interval;
void progress_throttle_impl::write_time_error(int errnum)
{
if(!wrote_time_error)
{
LOG_ERROR(logger,
"gettimeofday() failed: " <<
sstrerror(errnum));
wrote_time_error = true;
}
}
progress_throttle_impl::progress_throttle_impl()
: logger(Loggers::getAptitudeCmdlineThrottle()),
wrote_time_error(false)
{
}
bool progress_throttle_impl::update_required()
{
if(!last_update)
return true;
else
{
// Time checking code shamelessly stolen from apt, since
// we know theirs works.
struct timeval now;
if(gettimeofday(&now, 0) != 0)
{
write_time_error(errno);
return false;
}
else
{
const struct timeval &last_update_time = *last_update;
double diff =
now.tv_sec - last_update_time.tv_sec +
(now.tv_usec - last_update_time.tv_usec)/1000000.0;
bool rval = diff >= update_interval;
return rval;
}
}
}
void progress_throttle_impl::reset_timer()
{
LOG_TRACE(logger, "Resetting the update timer.");
struct timeval now;
if(gettimeofday(&now, 0) != 0)
write_time_error(errno);
else
last_update = now;
}
}
progress_throttle::~progress_throttle()
{
}
shared_ptr<progress_throttle> create_progress_throttle()
{
return make_shared<progress_throttle_impl>();
}
}
}
|