fix: correctness — bw throttle underflow, glob **, protocol version, valgrind
CI / lint (pull_request) Failing after 3s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
CI / lint (pull_request) Failing after 3s
CI / build-and-test (pull_request) Has been skipped
CI / sanitizers (address) (pull_request) Has been skipped
CI / sanitizers (undefined) (pull_request) Has been skipped
CI / fuzz-build (pull_request) Has been skipped
CI / coverage (pull_request) Has been skipped
CI / valgrind (pull_request) Has been skipped
This commit is contained in:
+10
-3
@@ -36,10 +36,17 @@ static void bw_throttle(size_t bytes_written) {
|
|||||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||||
|
|
||||||
/* Use unsigned long long for elapsed_ns to avoid overflow in multiplication.
|
/* Use unsigned long long for elapsed_ns to avoid overflow in multiplication.
|
||||||
* time_t differences fit comfortably in 64-bit for any practical runtime. */
|
* time_t differences fit comfortably in 64-bit for any practical runtime.
|
||||||
|
* Handle nanosecond carry/borrow to avoid unsigned wraparound when
|
||||||
|
* now.tv_nsec < bw_last_refill.tv_nsec. */
|
||||||
|
long long sec_diff = (long long)(now.tv_sec - bw_last_refill.tv_sec);
|
||||||
|
long long nsec_diff = (long long)(now.tv_nsec - bw_last_refill.tv_nsec);
|
||||||
|
if (nsec_diff < 0) {
|
||||||
|
sec_diff--;
|
||||||
|
nsec_diff += 1000000000LL;
|
||||||
|
}
|
||||||
unsigned long long elapsed_ns =
|
unsigned long long elapsed_ns =
|
||||||
(unsigned long long)(now.tv_sec - bw_last_refill.tv_sec) * 1000000000ULL +
|
(unsigned long long)sec_diff * 1000000000ULL + (unsigned long long)nsec_diff;
|
||||||
(unsigned long long)(now.tv_nsec - bw_last_refill.tv_nsec);
|
|
||||||
bw_last_refill = now;
|
bw_last_refill = now;
|
||||||
|
|
||||||
long long tokens_to_add = (long long)((double)io_bwlimit * (double)elapsed_ns / 1000000000.0);
|
long long tokens_to_add = (long long)((double)io_bwlimit * (double)elapsed_ns / 1000000000.0);
|
||||||
|
|||||||
+7
-4
@@ -92,13 +92,16 @@ bool glob_match(const char* pattern, const char* str) {
|
|||||||
str++;
|
str++;
|
||||||
} else {
|
} else {
|
||||||
if (*pattern != *str) {
|
if (*pattern != *str) {
|
||||||
/* If pattern has a '/' followed by '**', allow zero path components */
|
/* If pattern has a '/' followed by '**', allow zero path components.
|
||||||
|
* Only skip slash-double-star if the remainder is empty or starts with '/';
|
||||||
|
* otherwise fall through to normal character matching. */
|
||||||
if (*pattern == '/' && *(pattern + 1) == '*' && *(pattern + 2) == '*') {
|
if (*pattern == '/' && *(pattern + 1) == '*' && *(pattern + 2) == '*') {
|
||||||
/* Skip over slash-double-star and try to match rest against current str */
|
|
||||||
const char* rest = pattern + 3;
|
const char* rest = pattern + 3;
|
||||||
if (*rest == '/')
|
if (*rest == '\0')
|
||||||
rest++;
|
|
||||||
return glob_match(rest, str);
|
return glob_match(rest, str);
|
||||||
|
if (*rest == '/')
|
||||||
|
return glob_match(rest + 1, str);
|
||||||
|
/* slash-double-star X where X does not start with '/' — fall through */
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user