]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
asterisk.c: When astcanary dies on linux, reset priority on all threads. 18/3918/2
authorWalter Doekes <walter+github@wjd.nu>
Mon, 19 Sep 2016 14:40:40 +0000 (16:40 +0200)
committerWalter Doekes <walter+asterisk@wjd.nu>
Mon, 19 Sep 2016 19:24:49 +0000 (14:24 -0500)
Previously only the canary checking thread itself had its priority set
to SCHED_OTHER. Now all threads are traversed and adjusted.

ASTERISK-19867 #close
Reported by: Xavier Hienne

Change-Id: Ie0dd02a3ec42f66a78303e9c1aac28f7ed9aae39

main/asterisk.c

index b8eedfa38b51dcd96a3f287eb5ed7435acfce83b..f463849e58107bd3e423a73afa10c39595823a20 100644 (file)
@@ -1863,6 +1863,46 @@ static void set_icon(char *text)
                fprintf(stdout, "\033]1;%s\007", text);
 }
 
+/*! \brief Set priority on all known threads. */
+static int set_priority_all(int pri)
+{
+#if !defined(__linux__)
+       /* The non-linux version updates the entire process prio. */
+       return ast_set_priority(pri);
+#elif defined(LOW_MEMORY)
+       ast_log(LOG_WARNING, "Unable to enumerate all threads to update priority\n");
+       return ast_set_priority(pri);
+#else
+       struct thread_list_t *cur;
+       struct sched_param sched;
+       char const *policy_str;
+       int policy;
+
+       memset(&sched, 0, sizeof(sched));
+       if (pri) {
+               policy = SCHED_RR;
+               policy_str = "realtime";
+               sched.sched_priority = 10;
+       } else {
+               policy = SCHED_OTHER;
+               policy_str = "regular";
+               sched.sched_priority = 0;
+       }
+       if (sched_setscheduler(getpid(), policy, &sched)) {
+               ast_log(LOG_WARNING, "Unable to set %s thread priority on main thread\n", policy_str);
+               return -1;
+       }
+       ast_verb(1, "Setting %s thread priority on all threads\n", policy_str);
+       AST_RWLIST_RDLOCK(&thread_list);
+       AST_RWLIST_TRAVERSE(&thread_list, cur, list) {
+               /* Don't care about the return value. It should work. */
+               sched_setscheduler(cur->lwp, policy, &sched);
+       }
+       AST_RWLIST_UNLOCK(&thread_list);
+       return 0;
+#endif
+}
+
 /*! \brief We set ourselves to a high priority, that we might pre-empt
  * everything else.  If your PBX has heavy activity on it, this is a
  * good thing.
@@ -3832,7 +3872,7 @@ static void *canary_thread(void *unused)
                                "He's kicked the bucket.  He's shuffled off his mortal coil, "
                                "run down the curtain, and joined the bleeding choir invisible!!  "
                                "THIS is an EX-CANARY.  (Reducing priority)\n");
-                       ast_set_priority(0);
+                       set_priority_all(0);
                        pthread_exit(NULL);
                }