Skip to content

Commit 0f4b6db

Browse files
etbuiragitster
authored andcommitted
Handle atexit list internaly for unthreaded builds
Wrap atexit()s calls on unthreaded builds to handle callback list internally. This is needed because on unthreaded builds, asyncs inherits parent's atexit() list, that gets run as soon as the async exit()s (and again at the end of async's parent process). That led to remove temporary files too early. Also remove a by-atexit-callback guard against this kind of issue in clone.c, as this patch makes it redundant. Fixes test 5537 (temporary shallow file vanished before unpack-objects could open it) BTW remove an unused variable in shallow.c. Helped-by: Duy Nguyen <[email protected]> Helped-by: Andreas Schwab <[email protected]> Helped-by: Junio C Hamano <[email protected]> Signed-off-by: Etienne Buira <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 0c45d25 commit 0f4b6db

File tree

4 files changed

+47
-10
lines changed

4 files changed

+47
-10
lines changed

builtin/clone.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,6 @@ static void clone_local(const char *src_repo, const char *dest_repo)
390390

391391
static const char *junk_work_tree;
392392
static const char *junk_git_dir;
393-
static pid_t junk_pid;
394393
static enum {
395394
JUNK_LEAVE_NONE,
396395
JUNK_LEAVE_REPO,
@@ -417,8 +416,6 @@ static void remove_junk(void)
417416
break;
418417
}
419418

420-
if (getpid() != junk_pid)
421-
return;
422419
if (junk_git_dir) {
423420
strbuf_addstr(&sb, junk_git_dir);
424421
remove_dir_recursively(&sb, 0);
@@ -759,8 +756,6 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
759756
struct refspec *refspec;
760757
const char *fetch_pattern;
761758

762-
junk_pid = getpid();
763-
764759
packet_trace_identity("clone");
765760
argc = parse_options(argc, argv, prefix, builtin_clone_options,
766761
builtin_clone_usage, 0);

git-compat-util.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,11 @@ int inet_pton(int af, const char *src, void *dst);
594594
const char *inet_ntop(int af, const void *src, char *dst, size_t size);
595595
#endif
596596

597+
#ifdef NO_PTHREADS
598+
#define atexit git_atexit
599+
extern int git_atexit(void (*handler)(void));
600+
#endif
601+
597602
extern void release_pack_memory(size_t);
598603

599604
typedef void (*try_to_free_t)(size_t);

run-command.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,45 @@ static int async_die_is_recursing(void)
620620
return ret != NULL;
621621
}
622622

623+
#else
624+
625+
static struct {
626+
void (**handlers)(void);
627+
size_t nr;
628+
size_t alloc;
629+
} git_atexit_hdlrs;
630+
631+
static int git_atexit_installed;
632+
633+
static void git_atexit_dispatch()
634+
{
635+
size_t i;
636+
637+
for (i=git_atexit_hdlrs.nr ; i ; i--)
638+
git_atexit_hdlrs.handlers[i-1]();
639+
}
640+
641+
static void git_atexit_clear()
642+
{
643+
free(git_atexit_hdlrs.handlers);
644+
memset(&git_atexit_hdlrs, 0, sizeof(git_atexit_hdlrs));
645+
git_atexit_installed = 0;
646+
}
647+
648+
#undef atexit
649+
int git_atexit(void (*handler)(void))
650+
{
651+
ALLOC_GROW(git_atexit_hdlrs.handlers, git_atexit_hdlrs.nr + 1, git_atexit_hdlrs.alloc);
652+
git_atexit_hdlrs.handlers[git_atexit_hdlrs.nr++] = handler;
653+
if (!git_atexit_installed) {
654+
if (atexit(&git_atexit_dispatch))
655+
return -1;
656+
git_atexit_installed = 1;
657+
}
658+
return 0;
659+
}
660+
#define atexit git_atexit
661+
623662
#endif
624663

625664
int start_async(struct async *async)
@@ -678,6 +717,7 @@ int start_async(struct async *async)
678717
close(fdin[1]);
679718
if (need_out)
680719
close(fdout[0]);
720+
git_atexit_clear();
681721
exit(!!async->proc(proc_in, proc_out, async->data));
682722
}
683723

shallow.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,6 @@ static void remove_temporary_shallow_on_signal(int signo)
226226

227227
const char *setup_temporary_shallow(const struct sha1_array *extra)
228228
{
229-
static int installed_handler;
230229
struct strbuf sb = STRBUF_INIT;
231230
int fd;
232231

@@ -237,10 +236,8 @@ const char *setup_temporary_shallow(const struct sha1_array *extra)
237236
strbuf_addstr(&temporary_shallow, git_path("shallow_XXXXXX"));
238237
fd = xmkstemp(temporary_shallow.buf);
239238

240-
if (!installed_handler) {
241-
atexit(remove_temporary_shallow);
242-
sigchain_push_common(remove_temporary_shallow_on_signal);
243-
}
239+
atexit(remove_temporary_shallow);
240+
sigchain_push_common(remove_temporary_shallow_on_signal);
244241

245242
if (write_in_full(fd, sb.buf, sb.len) != sb.len)
246243
die_errno("failed to write to %s",

0 commit comments

Comments
 (0)