1 /* Downloads progression stuff. */
2 /* $Id: progress.c,v 1.35 2005/09/09 07:27:48 zas Exp $ */
10 #include "network/progress.h"
11 #include "util/error.h"
12 #include "util/memory.h"
13 #include "util/time.h"
15 #define SPD_DISP_TIME ((milliseconds_T) 100)
16 #define CURRENT_SPD_AFTER ((milliseconds_T) 100)
20 has_progress(struct progress
*progress
)
22 timeval_T current_speed_after
;
24 timeval_from_milliseconds(¤t_speed_after
, CURRENT_SPD_AFTER
);
26 return (timeval_cmp(&progress
->elapsed
, ¤t_speed_after
) >= 0);
30 init_progress(off_t start
)
32 struct progress
*progress
= mem_calloc(1, sizeof(*progress
));
35 progress
->start
= start
;
36 progress
->timer
= TIMER_ID_UNDEF
;
43 done_progress(struct progress
*progress
)
49 update_progress(struct progress
*progress
, off_t loaded
, off_t size
, off_t pos
)
52 timeval_T now
, elapsed
, dis_b_max
, dis_b_interval
;
55 timeval_sub(&elapsed
, &progress
->last_time
, &now
);
56 timeval_copy(&progress
->last_time
, &now
);
58 progress
->loaded
= loaded
;
59 bytes_delta
= progress
->loaded
- progress
->last_loaded
;
60 progress
->last_loaded
= progress
->loaded
;
62 timeval_add_interval(&progress
->elapsed
, &elapsed
);
64 timeval_add_interval(&progress
->dis_b
, &elapsed
);
65 timeval_from_milliseconds(&dis_b_max
, mult_ms(SPD_DISP_TIME
, CURRENT_SPD_SEC
));
66 timeval_from_milliseconds(&dis_b_interval
, SPD_DISP_TIME
);
68 while (timeval_cmp(&progress
->dis_b
, &dis_b_max
) >= 0) {
69 progress
->cur_loaded
-= progress
->data_in_secs
[0];
70 memmove(progress
->data_in_secs
, progress
->data_in_secs
+ 1,
71 sizeof(*progress
->data_in_secs
) * (CURRENT_SPD_SEC
- 1));
72 progress
->data_in_secs
[CURRENT_SPD_SEC
- 1] = 0;
73 timeval_sub_interval(&progress
->dis_b
, &dis_b_interval
);
75 progress
->data_in_secs
[CURRENT_SPD_SEC
- 1] += bytes_delta
;
76 progress
->cur_loaded
+= bytes_delta
;
78 progress
->current_speed
= progress
->cur_loaded
/ (CURRENT_SPD_SEC
* ((long) SPD_DISP_TIME
) / 1000);
81 progress
->size
= size
;
82 if (progress
->size
!= -1 && progress
->size
< progress
->pos
)
83 progress
->size
= progress
->pos
;
85 progress
->average_speed
= timeval_div_off_t(progress
->loaded
, &progress
->elapsed
);
86 if (progress
->average_speed
) /* Division by zero risk */
87 timeval_from_seconds(&progress
->estimated_time
,
88 (progress
->size
- progress
->pos
) / progress
->average_speed
);
90 install_timer(&progress
->timer
, SPD_DISP_TIME
, progress
->timer_func
, progress
->timer_func_data
);
94 start_update_progress(struct progress
*progress
, void (*timer_func
)(void *),
95 void *timer_func_data
)
97 if (!progress
->valid
) {
100 /* Just copy useful fields from invalid progress. */
101 memset(&tmp
, 0, sizeof(tmp
));
102 tmp
.start
= progress
->start
;
103 tmp
.seek
= progress
->seek
;
106 memcpy(progress
, &tmp
, sizeof(*progress
));
108 timeval_now(&progress
->last_time
);
109 progress
->last_loaded
= progress
->loaded
;
110 progress
->timer_func
= timer_func
;
111 progress
->timer_func_data
= timer_func_data
;