diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-02-07 20:29:47 +0000 |
---|---|---|
committer | Eric Wong <normalperson@yhbt.net> | 2013-02-07 20:29:47 +0000 |
commit | 4f45f562180489a97a4572ebd3822e9f15289bd6 (patch) | |
tree | 78be2c75cc7b92da8ff5b101664a9328ffe61323 | |
parent | 315487f70c90b117aa4e9d63bbb21abae8af80ab (diff) | |
download | cmogstored-4f45f562180489a97a4572ebd3822e9f15289bd6.tar.gz |
Pthreads implementations do not require mutexes be in a consistent/usable state in a forked child Since we don't need the mutex in a single-threaded forked child, we can just skip it and avoid reinitializing it entirely.
-rw-r--r-- | cmogstored.h | 1 | ||||
-rw-r--r-- | svc.c | 25 | ||||
-rw-r--r-- | upgrade.c | 18 |
3 files changed, 27 insertions, 17 deletions
diff --git a/cmogstored.h b/cmogstored.h index 1b3d1be..eafbae6 100644 --- a/cmogstored.h +++ b/cmogstored.h @@ -309,6 +309,7 @@ void mog_set_maxconns(unsigned long); struct mog_svc *mog_svc_new(const char *docroot); typedef int (*mog_scandev_cb)(const struct mog_dev *, struct mog_svc *); size_t mog_svc_each(Hash_processor processor, void *data); +void mog_svc_upgrade_prepare(void); /* dev.c */ struct mog_dev * mog_dev_new(struct mog_svc *, uint32_t mog_devid); @@ -118,3 +118,28 @@ size_t mog_svc_each(Hash_processor processor, void *data) return rv; } + +static bool cloexec_disable(int fd) +{ + if (fd >= 0) + CHECK(int, 0, mog_set_cloexec(fd, false)); + return true; +} + +static bool svc_cloexec_off_i(void *svcptr, void *unused) +{ + struct mog_svc *svc = svcptr; + + return (cloexec_disable(svc->mgmt_fd) + && cloexec_disable(svc->http_fd) + && cloexec_disable(svc->httpget_fd)); +} + +/* + * Only call this from a freshly forked upgrade child process. + * This holds no locks to avoid potential deadlocks in post-fork mutexes + */ +void mog_svc_upgrade_prepare(void) +{ + (void)hash_do_for_each(by_docroot, svc_cloexec_off_i, NULL); +} @@ -81,22 +81,6 @@ static bool svc_emit_fd_i(void *svcptr, void *_fp) && emit_fd(fp, svc->httpget_fd)); } -static bool cloexec_disable(int fd) -{ - if (fd >= 0) - CHECK(int, 0, mog_set_cloexec(fd, false)); - return true; -} - -static bool svc_cloexec_off_i(void *svcptr, void *unused) -{ - struct mog_svc *svc = svcptr; - - return (cloexec_disable(svc->mgmt_fd) - && cloexec_disable(svc->http_fd) - && cloexec_disable(svc->httpget_fd)); -} - /* returns the PID of the newly spawned child */ pid_t mog_upgrade_spawn(void) { @@ -145,7 +129,7 @@ pid_t mog_upgrade_spawn(void) /* CMOGSTORED_FD= is set here */ CHECK(int, 0, putenv(dst)); - mog_svc_each(svc_cloexec_off_i, NULL); + mog_svc_upgrade_prepare(); mog_intr_enable(); execvp(start.argv[0], start.argv); die_errno("execvp %s", start.argv[0]); |