Skip to content

Commit 12f82b0

Browse files
committed
Merge branch 'ps/lockfile-cleanup-fix'
Some lockfile code called free() in signal-death code path, which has been corrected. * ps/lockfile-cleanup-fix: fetch: fix deadlock when cleaning up lockfiles in async signals
2 parents 453cef7 + 58d4d7f commit 12f82b0

File tree

4 files changed

+33
-11
lines changed

4 files changed

+33
-11
lines changed

builtin/clone.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
12901290
*/
12911291
submodule_progress = transport->progress;
12921292

1293-
transport_unlock_pack(transport);
1293+
transport_unlock_pack(transport, 0);
12941294
transport_disconnect(transport);
12951295

12961296
if (option_dissociate) {

builtin/fetch.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -223,17 +223,22 @@ static struct option builtin_fetch_options[] = {
223223
OPT_END()
224224
};
225225

226-
static void unlock_pack(void)
226+
static void unlock_pack(unsigned int flags)
227227
{
228228
if (gtransport)
229-
transport_unlock_pack(gtransport);
229+
transport_unlock_pack(gtransport, flags);
230230
if (gsecondary)
231-
transport_unlock_pack(gsecondary);
231+
transport_unlock_pack(gsecondary, flags);
232+
}
233+
234+
static void unlock_pack_atexit(void)
235+
{
236+
unlock_pack(0);
232237
}
233238

234239
static void unlock_pack_on_signal(int signo)
235240
{
236-
unlock_pack();
241+
unlock_pack(TRANSPORT_UNLOCK_PACK_IN_SIGNAL_HANDLER);
237242
sigchain_pop(signo);
238243
raise(signo);
239244
}
@@ -1329,7 +1334,7 @@ static int fetch_and_consume_refs(struct transport *transport,
13291334
trace2_region_leave("fetch", "consume_refs", the_repository);
13301335

13311336
out:
1332-
transport_unlock_pack(transport);
1337+
transport_unlock_pack(transport, 0);
13331338
return ret;
13341339
}
13351340

@@ -1978,7 +1983,7 @@ static int fetch_one(struct remote *remote, int argc, const char **argv,
19781983
gtransport->server_options = &server_options;
19791984

19801985
sigchain_push_common(unlock_pack_on_signal);
1981-
atexit(unlock_pack);
1986+
atexit(unlock_pack_atexit);
19821987
sigchain_push(SIGPIPE, SIG_IGN);
19831988
exit_code = do_fetch(gtransport, &rs);
19841989
sigchain_pop(SIGPIPE);

transport.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1456,13 +1456,18 @@ int transport_fetch_refs(struct transport *transport, struct ref *refs)
14561456
return rc;
14571457
}
14581458

1459-
void transport_unlock_pack(struct transport *transport)
1459+
void transport_unlock_pack(struct transport *transport, unsigned int flags)
14601460
{
1461+
int in_signal_handler = !!(flags & TRANSPORT_UNLOCK_PACK_IN_SIGNAL_HANDLER);
14611462
int i;
14621463

14631464
for (i = 0; i < transport->pack_lockfiles.nr; i++)
1464-
unlink_or_warn(transport->pack_lockfiles.items[i].string);
1465-
string_list_clear(&transport->pack_lockfiles, 0);
1465+
if (in_signal_handler)
1466+
unlink(transport->pack_lockfiles.items[i].string);
1467+
else
1468+
unlink_or_warn(transport->pack_lockfiles.items[i].string);
1469+
if (!in_signal_handler)
1470+
string_list_clear(&transport->pack_lockfiles, 0);
14661471
}
14671472

14681473
int transport_connect(struct transport *transport, const char *name,

transport.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,19 @@ const struct ref *transport_get_remote_refs(struct transport *transport,
279279
*/
280280
const struct git_hash_algo *transport_get_hash_algo(struct transport *transport);
281281
int transport_fetch_refs(struct transport *transport, struct ref *refs);
282-
void transport_unlock_pack(struct transport *transport);
282+
283+
/*
284+
* If this flag is set, unlocking will avoid to call non-async-signal-safe
285+
* functions. This will necessarily leave behind some data structures which
286+
* cannot be cleaned up.
287+
*/
288+
#define TRANSPORT_UNLOCK_PACK_IN_SIGNAL_HANDLER (1 << 0)
289+
290+
/*
291+
* Unlock all packfiles locked by the transport.
292+
*/
293+
void transport_unlock_pack(struct transport *transport, unsigned int flags);
294+
283295
int transport_disconnect(struct transport *transport);
284296
char *transport_anonymize_url(const char *url);
285297
void transport_take_over(struct transport *transport,

0 commit comments

Comments
 (0)