}
nleft -= nread;
ptr += nread;
+ if (bsock->use_bwlimit()) {
+ bsock->control_bwlimit(nread);
+ }
}
return nbytes - nleft; /* return >= 0 */
}
}
nleft -= nwritten;
ptr += nwritten;
+ if (bsock->use_bwlimit()) {
+ bsock->control_bwlimit(nwritten);
+ }
}
return nbytes - nleft;
}
dir->host(), dir->port());
return false;
}
+
+/* Try to limit the bandwidth of a network connection
+ */
+void BSOCK::control_bwlimit(int bytes)
+{
+ btime_t now, temp;
+ if (bytes == 0) {
+ return;
+ }
+
+ now = get_current_btime(); /* microseconds */
+ temp = now - m_last_tick; /* microseconds */
+
+ m_nb_bytes += bytes;
+
+ /* Less than 0.1ms since the last call, see the next time */
+ if (temp < 100) {
+ return;
+ }
+
+ if (temp > 10000000) { /* Take care of clock problems (>10s) */
+ m_nb_bytes = bytes;
+ m_last_tick = now;
+ return;
+ }
+
+ /* Remove what was authorised to be written in temp us */
+ m_nb_bytes -= temp * ((double)m_bwlimit / 1000000.0);
+
+ if (m_nb_bytes < 0) {
+ m_nb_bytes = 0;
+ }
+
+ /* What exceed should be converted in sleep time */
+ int64_t usec_sleep = m_nb_bytes / ((double)m_bwlimit / 1000000.0);
+ if (usec_sleep > 100) {
+ bmicrosleep(0, usec_sleep);
+ m_last_tick = get_current_btime();
+ m_nb_bytes = 0;
+ } else {
+ m_last_tick = now;
+ }
+}
bool m_spool: 1; /* set for spooling */
bool m_use_locking: 1; /* set to use locking */
+ int64_t m_bwlimit; /* set to limit bandwidth */
+ int64_t m_nb_bytes; /* bytes sent/recv since the last tick */
+ btime_t m_last_tick; /* last tick used by bwlimit */
+
void fin_init(JCR * jcr, int sockfd, const char *who, const char *host, int port,
struct sockaddr *lclient_addr);
bool open(JCR *jcr, const char *name, char *host, char *service,
bool set_locking(); /* in bsock.c */
void clear_locking(); /* in bsock.c */
void set_source_address(dlist *src_addr_list);
+ void control_bwlimit(int bytes); /* in bsock.c */
/* Inline functions */
void set_jcr(JCR *jcr) { m_jcr = jcr; };
bool is_stop() { return errors || is_terminated(); }
bool is_error() { errno = b_errno; return errors; }
void set_data_end() { if (m_spool) m_data_end = ftello(m_spool_fd); };
+ void set_bwlimit(int64_t maxspeed) { m_bwlimit = maxspeed; };
+ bool use_bwlimit() { return m_bwlimit > 0;};
void set_spooling() { m_spool = true; };
void clear_spooling() { m_spool = false; };
void set_duped() { m_duped = true; };