about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-02-16 12:55:42 +0000
committerEric Wong <normalperson@yhbt.net>2013-02-16 12:55:42 +0000
commit719e4fc320e1978bc9ea6ee8be9f8249dcb54dab (patch)
tree4c736a4619c9f2ad373bb05e3711520e88b9f8cf
parent13cbdcea65248271668562064aafdcc9634ef9ce (diff)
downloadcmogstored-719e4fc320e1978bc9ea6ee8be9f8249dcb54dab.tar.gz
Older glibc will return ENOMEM on mprotect() failures.  This bug
was only fixed in 2011, so the long-term distros and old
installations may not have the necessary backports.

ref: http://www.sourceware.org/bugzilla/show_bug.cgi?id=386
-rw-r--r--mnt.c2
-rw-r--r--thrpool.c2
-rw-r--r--util.h11
3 files changed, 13 insertions, 2 deletions
diff --git a/mnt.c b/mnt.c
index 09a2030..7205c2c 100644
--- a/mnt.c
+++ b/mnt.c
@@ -159,7 +159,7 @@ static void timed_init_once(void)
                         break;
 
                 /* this must succeed, keep looping */
-                if (rc == EAGAIN) {
+                if (mog_pthread_create_retry(rc)) {
                         if ((++tries % 1024) == 0)
                                 warn("pthread_create: %s (tries: %lu)",
                                      strerror(rc), tries);
diff --git a/thrpool.c b/thrpool.c
index 718c568..8030e19 100644
--- a/thrpool.c
+++ b/thrpool.c
@@ -96,7 +96,7 @@ static void thrpool_set_size(struct mog_thrpool *tp, size_t size)
                 if (rc == 0) {
                         tp->n_threads++;
                         nr_eagain = 0;
-                } else if (rc == EAGAIN) {
+                } else if (mog_pthread_create_retry(rc)) {
                         if (!thr_create_fail_retry(tp, size, &nr_eagain, rc))
                                 goto out;
                 } else {
diff --git a/util.h b/util.h
index e679c56..072f429 100644
--- a/util.h
+++ b/util.h
@@ -83,3 +83,14 @@ static inline int mog_set_cloexec(int fd, const bool set)
 {
         return fcntl(fd, F_SETFD, set ? FD_CLOEXEC : 0);
 }
+
+static inline bool mog_pthread_create_retry(const int err)
+{
+        /*
+         * older versions of glibc return ENOMEM instead of EAGAIN
+         * ref: http://www.sourceware.org/bugzilla/show_bug.cgi?id=386
+         * Remove the ENOMEM check by 2023 (unless other OSes have this
+         * bug).
+         */
+        return (err == EAGAIN || err == ENOMEM);
+}