about summary refs log tree commit homepage
diff options
context:
space:
mode:
authorEric Wong <normalperson@yhbt.net>2013-07-11 19:06:27 +0000
committerEric Wong <normalperson@yhbt.net>2013-07-11 19:06:27 +0000
commitf83d0466afc32542f3f4ff962105c817a1be2c96 (patch)
treec6b9e2b0b9002baf4b6f2cabb982dd0820cceba6
parentdaab757f5e52ce36a47e2d713365d68367a0e6dd (diff)
downloadcmogstored-f83d0466afc32542f3f4ff962105c817a1be2c96.tar.gz
We want to yield dying threads as soon as possible during
thread shutdown, so we check the quit flag and yield the
running thread to trigger a MOG_NEXT_ACTIVE.
-rw-r--r--cmogstored.h1
-rw-r--r--digest.c2
-rw-r--r--digest.h1
-rw-r--r--mgmt.c4
-rw-r--r--thrpool.c6
5 files changed, 13 insertions, 1 deletions
diff --git a/cmogstored.h b/cmogstored.h
index 4162931..487a70d 100644
--- a/cmogstored.h
+++ b/cmogstored.h
@@ -426,6 +426,7 @@ char *mog_canonpath_die(const char *path, enum canonicalize_mode_t canon_mode);
 
 /* thrpool.c */
 void mog_thr_test_quit(void);
+bool mog_thr_prepare_quit(void) MOG_CHECK;
 void mog_thrpool_start(struct mog_thrpool *, size_t n,
                        void *(*start_fn)(void *), void *arg);
 void mog_thrpool_quit(struct mog_thrpool *, struct mog_queue *);
diff --git a/digest.c b/digest.c
index 2f2b6d7..090c695 100644
--- a/digest.c
+++ b/digest.c
@@ -28,6 +28,8 @@ enum mog_digest_next mog_digest_read(struct mog_digest *digest, int fd)
 
                 if (r > 0) { /* most likely */
                         gc_hash_write(digest->ctx, r, buf);
+                        if (mog_thr_prepare_quit())
+                                return MOG_DIGEST_YIELD;
                 } else if (r == 0) {
                         /* wait for user to call mog_digest_hex() */
                         return MOG_DIGEST_EOF;
diff --git a/digest.h b/digest.h
index bef35b8..c037fcd 100644
--- a/digest.h
+++ b/digest.h
@@ -4,6 +4,7 @@
  */
 enum mog_digest_next {
         MOG_DIGEST_CONTINUE = 0,
+        MOG_DIGEST_YIELD,
         MOG_DIGEST_EOF,
         MOG_DIGEST_ERROR
 };
diff --git a/mgmt.c b/mgmt.c
index 4b8ef8b..aaf96a5 100644
--- a/mgmt.c
+++ b/mgmt.c
@@ -34,7 +34,9 @@ static void mgmt_digest_step(struct mog_fd *mfd)
         assert(mgmt->wbuf == NULL && "wbuf should be NULL here");
 
         switch (next) {
-        case MOG_DIGEST_CONTINUE: return;
+        case MOG_DIGEST_CONTINUE:
+        case MOG_DIGEST_YIELD:
+                return;
         case MOG_DIGEST_EOF:
                 mog_mgmt_fn_digest_emit(mgmt);
                 break;
diff --git a/thrpool.c b/thrpool.c
index 9cf8196..918fef8 100644
--- a/thrpool.c
+++ b/thrpool.c
@@ -66,6 +66,12 @@ void mog_thr_test_quit(void)
         }
 }
 
+bool mog_thr_prepare_quit(void)
+{
+        /* no barriers or atomic instructions, this is just a hint */
+        return !!mog_do_quit;
+}
+
 /*
  * we no longer rely on pthreads cancellation, so our explicit checks for
  * thread quitting requires us to continuously signal a thread for death