Skip to content

Commit 9d41a3f

Browse files
authored
Merge pull request libgit2#6535 from libgit2/ethomson/timeouts
2 parents 905e4d1 + 8f695c8 commit 9d41a3f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+779
-410
lines changed

ci/test.sh

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ if [ -z "$SKIP_PROXY_TESTS" ]; then
171171
fi
172172
173173
if [ -z "$SKIP_NTLM_TESTS" -o -z "$SKIP_ONLINE_TESTS" ]; then
174-
curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.5.1/poxygit-0.5.1.jar >poxygit.jar
174+
curl --location --silent --show-error https://github.com/ethomson/poxygit/releases/download/v0.6.0/poxygit-0.6.0.jar >poxygit.jar
175175
176176
echo "Starting HTTP server..."
177177
HTTP_DIR=`mktemp -d ${TMPDIR}/http.XXXXXXXX`
@@ -271,9 +271,13 @@ if [ -z "$SKIP_ONLINE_TESTS" ]; then
271271
272272
export GITTEST_REMOTE_REDIRECT_INITIAL="http://localhost:9000/initial-redirect/libgit2/TestGitRepository"
273273
export GITTEST_REMOTE_REDIRECT_SUBSEQUENT="http://localhost:9000/subsequent-redirect/libgit2/TestGitRepository"
274+
export GITTEST_REMOTE_SPEED_SLOW="http://localhost:9000/speed-9600/test.git"
275+
export GITTEST_REMOTE_SPEED_TIMESOUT="http://localhost:9000/speed-0.5/test.git"
274276
run_test online
275277
unset GITTEST_REMOTE_REDIRECT_INITIAL
276278
unset GITTEST_REMOTE_REDIRECT_SUBSEQUENT
279+
unset GITTEST_REMOTE_SPEED_SLOW
280+
unset GITTEST_REMOTE_SPEED_TIMESOUT
277281
278282
# Run the online tests that immutably change global state separately
279283
# to avoid polluting the test environment.

include/git2/common.h

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,11 @@ typedef enum {
224224
GIT_OPT_GET_OWNER_VALIDATION,
225225
GIT_OPT_SET_OWNER_VALIDATION,
226226
GIT_OPT_GET_HOMEDIR,
227-
GIT_OPT_SET_HOMEDIR
227+
GIT_OPT_SET_HOMEDIR,
228+
GIT_OPT_SET_SERVER_CONNECT_TIMEOUT,
229+
GIT_OPT_GET_SERVER_CONNECT_TIMEOUT,
230+
GIT_OPT_SET_SERVER_TIMEOUT,
231+
GIT_OPT_GET_SERVER_TIMEOUT
228232
} git_libgit2_opt_t;
229233

230234
/**
@@ -480,6 +484,27 @@ typedef enum {
480484
* >
481485
* > - `path` directory of home directory.
482486
*
487+
* opts(GIT_OPT_GET_SERVER_CONNECT_TIMEOUT, int *timeout)
488+
* > Gets the timeout (in milliseconds) to attempt connections to
489+
* > a remote server.
490+
*
491+
* opts(GIT_OPT_SET_SERVER_CONNECT_TIMEOUT, int timeout)
492+
* > Sets the timeout (in milliseconds) to attempt connections to
493+
* > a remote server. This is supported only for HTTP(S) connections
494+
* > and is not supported by SSH. Set to 0 to use the system default.
495+
* > Note that this may not be able to be configured longer than the
496+
* > system default, typically 75 seconds.
497+
*
498+
* opts(GIT_OPT_GET_SERVER_TIMEOUT, int *timeout)
499+
* > Gets the timeout (in milliseconds) for reading from and writing
500+
* > to a remote server.
501+
*
502+
* opts(GIT_OPT_SET_SERVER_TIMEOUT, int timeout)
503+
* > Sets the timeout (in milliseconds) for reading from and writing
504+
* > to a remote server. This is supported only for HTTP(S)
505+
* > connections and is not supported by SSH. Set to 0 to use the
506+
* > system default.
507+
*
483508
* @param option Option key
484509
* @param ... value to set the option
485510
* @return 0 on success, <0 on failure

include/git2/errors.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ typedef enum {
5858
GIT_EMISMATCH = -33, /**< Hashsum mismatch in object */
5959
GIT_EINDEXDIRTY = -34, /**< Unsaved changes in the index would be overwritten */
6060
GIT_EAPPLYFAIL = -35, /**< Patch application failed */
61-
GIT_EOWNER = -36 /**< The object is not owned by the current user */
61+
GIT_EOWNER = -36, /**< The object is not owned by the current user */
62+
GIT_TIMEOUT = -37 /**< The operation timed out */
6263
} git_error_code;
6364

6465
/**

include/git2/sys/stream.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,22 @@ GIT_BEGIN_DECL
2929
typedef struct git_stream {
3030
int version;
3131

32-
int encrypted;
33-
int proxy_support;
32+
int encrypted : 1,
33+
proxy_support : 1;
34+
35+
/**
36+
* Timeout for read and write operations; can be set to `0` to
37+
* block indefinitely.
38+
*/
39+
int timeout;
40+
41+
/**
42+
* Timeout to connect to the remote server; can be set to `0`
43+
* to use the system defaults. This can be shorter than the
44+
* system default - often 75 seconds - but cannot be longer.
45+
*/
46+
int connect_timeout;
47+
3448
int GIT_CALLBACK(connect)(struct git_stream *);
3549
int GIT_CALLBACK(certificate)(git_cert **, struct git_stream *);
3650
int GIT_CALLBACK(set_proxy)(struct git_stream *, const git_proxy_options *proxy_opts);

src/CMakeLists.txt

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,17 @@ check_prototype_definition_safe(qsort_s
8484

8585
# random / entropy data
8686

87-
check_function_exists(getentropy GIT_RAND_GETENTROPY)
88-
check_function_exists(getloadavg GIT_RAND_GETLOADAVG)
87+
check_symbol_exists(getentropy unistd.h GIT_RAND_GETENTROPY)
88+
check_symbol_exists(getloadavg stdlib.h GIT_RAND_GETLOADAVG)
89+
90+
# poll
91+
92+
if(WIN32)
93+
set(GIT_IO_WSAPOLL 1)
94+
else()
95+
check_symbol_exists(poll poll.h GIT_IO_POLL)
96+
check_symbol_exists(select sys/select.h GIT_IO_SELECT)
97+
endif()
8998

9099
# determine architecture of the machine
91100

src/cli/progress.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
/*
1616
* Show updates to the percentage and number of objects received
1717
* separately from the throughput to give an accurate progress while
18-
* avoiding too much noise on the screen.
18+
* avoiding too much noise on the screen. (In milliseconds.)
1919
*/
20-
#define PROGRESS_UPDATE_TIME 0.10
21-
#define THROUGHPUT_UPDATE_TIME 1.00
20+
#define PROGRESS_UPDATE_TIME 60
21+
#define THROUGHPUT_UPDATE_TIME 500
2222

2323
#define is_nl(c) ((c) == '\r' || (c) == '\n')
2424

@@ -54,7 +54,7 @@ static int progress_write(cli_progress *progress, bool force, git_str *line)
5454
bool has_nl;
5555
size_t no_nl = no_nl_len(line->ptr, line->size);
5656
size_t nl = nl_len(&has_nl, line->ptr + no_nl, line->size - no_nl);
57-
double now = git__timer();
57+
uint64_t now = git_time_monotonic();
5858
size_t i;
5959

6060
/* Avoid spamming the console with progress updates */
@@ -191,20 +191,21 @@ static int fetch_receiving(
191191
{
192192
char *recv_units[] = { "B", "KiB", "MiB", "GiB", "TiB", NULL };
193193
char *rate_units[] = { "B/s", "KiB/s", "MiB/s", "GiB/s", "TiB/s", NULL };
194+
uint64_t now, elapsed;
194195

195-
double now, recv_len, rate, elapsed;
196+
double recv_len, rate;
196197
size_t recv_unit_idx = 0, rate_unit_idx = 0;
197198
bool done = (stats->received_objects == stats->total_objects);
198199

199200
if (!progress->action_start)
200-
progress->action_start = git__timer();
201+
progress->action_start = git_time_monotonic();
201202

202203
if (done && progress->action_finish)
203204
now = progress->action_finish;
204205
else if (done)
205-
progress->action_finish = now = git__timer();
206+
progress->action_finish = now = git_time_monotonic();
206207
else
207-
now = git__timer();
208+
now = git_time_monotonic();
208209

209210
if (progress->throughput_update &&
210211
now - progress->throughput_update < THROUGHPUT_UPDATE_TIME) {

src/cli/progress.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,19 @@ typedef struct {
3030
cli_progress_t action;
3131

3232
/* Actions may time themselves (eg fetch) but are not required to */
33-
double action_start;
34-
double action_finish;
33+
uint64_t action_start;
34+
uint64_t action_finish;
3535

3636
/* Last console update, avoid too frequent updates. */
37-
double last_update;
37+
uint64_t last_update;
3838

3939
/* Accumulators for partial output and deferred updates. */
4040
git_str sideband;
4141
git_str onscreen;
4242
git_str deferred;
4343

4444
/* Last update about throughput */
45-
double throughput_update;
45+
uint64_t throughput_update;
4646
double throughput_bytes;
4747
} cli_progress;
4848

src/libgit2/fetch.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
#include "remote.h"
1818
#include "refspec.h"
1919
#include "pack.h"
20-
#include "netops.h"
2120
#include "repository.h"
2221
#include "refs.h"
2322
#include "transports/smart.h"

src/libgit2/fetch.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
#include "git2/remote.h"
1313

14-
#include "netops.h"
15-
1614
int git_fetch_negotiate(git_remote *remote, const git_fetch_options *opts);
1715

1816
int git_fetch_download_pack(git_remote *remote);

src/libgit2/libgit2.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ extern size_t git_indexer__max_objects;
4848
extern bool git_disable_pack_keep_file_checks;
4949
extern int git_odb__packed_priority;
5050
extern int git_odb__loose_priority;
51+
extern int git_socket_stream__connect_timeout;
52+
extern int git_socket_stream__timeout;
5153

5254
char *git__user_agent;
5355
char *git__ssl_ciphers;
@@ -436,6 +438,40 @@ int git_libgit2_opts(int key, ...)
436438
error = git_sysdir_set(GIT_SYSDIR_HOME, va_arg(ap, const char *));
437439
break;
438440

441+
case GIT_OPT_GET_SERVER_CONNECT_TIMEOUT:
442+
*(va_arg(ap, int *)) = git_socket_stream__connect_timeout;
443+
break;
444+
445+
case GIT_OPT_SET_SERVER_CONNECT_TIMEOUT:
446+
{
447+
int timeout = va_arg(ap, int);
448+
449+
if (timeout < 0) {
450+
git_error_set(GIT_ERROR_INVALID, "invalid connect timeout");
451+
error = -1;
452+
} else {
453+
git_socket_stream__connect_timeout = timeout;
454+
}
455+
}
456+
break;
457+
458+
case GIT_OPT_GET_SERVER_TIMEOUT:
459+
*(va_arg(ap, int *)) = git_socket_stream__timeout;
460+
break;
461+
462+
case GIT_OPT_SET_SERVER_TIMEOUT:
463+
{
464+
int timeout = va_arg(ap, int);
465+
466+
if (timeout < 0) {
467+
git_error_set(GIT_ERROR_INVALID, "invalid timeout");
468+
error = -1;
469+
} else {
470+
git_socket_stream__timeout = timeout;
471+
}
472+
}
473+
break;
474+
439475
default:
440476
git_error_set(GIT_ERROR_INVALID, "invalid option key");
441477
error = -1;

0 commit comments

Comments
 (0)