From: Ludovic Henry Date: Thu, 19 Jan 2017 14:31:01 +0000 (-0500) Subject: [threads] Fix crash on unknown policy (#4264) X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=82f231ff9129c09431f964b5fe25a25ca4713fa2 [threads] Fix crash on unknown policy (#4264) Fixes https://bugzilla.xamarin.com/show_bug.cgi?id=51545 --- diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index fd424bdfb90..b5ffc020231 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -476,7 +476,8 @@ mono_thread_internal_set_priority (MonoInternalThread *internal, MonoThreadPrior param.sched_priority = 0; break; default: - g_error ("%s: unknown policy %d", __func__, policy); + g_warning ("%s: unknown policy %d", __func__, policy); + return; } } diff --git a/mono/utils/mono-threads-posix.c b/mono/utils/mono-threads-posix.c index 66746ad3dfa..430738591c6 100644 --- a/mono/utils/mono-threads-posix.c +++ b/mono/utils/mono-threads-posix.c @@ -35,16 +35,62 @@ extern int tkill (pid_t tid, int signal); #include +static void +reset_priority (pthread_attr_t *attr) +{ + struct sched_param param; + gint res; + gint policy; + + memset (¶m, 0, sizeof (param)); + + res = pthread_attr_getschedpolicy (attr, &policy); + if (res != 0) + g_error ("%s: pthread_attr_getschedpolicy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); + +#ifdef _POSIX_PRIORITY_SCHEDULING + gint max, min; + + /* Necessary to get valid priority range */ + + min = sched_get_priority_min (policy); + max = sched_get_priority_max (policy); + + if (max > 0 && min >= 0 && max > min) + param.sched_priority = (max - min) / 2 + min; + else +#endif + { + switch (policy) { + case SCHED_FIFO: + case SCHED_RR: + param.sched_priority = 50; + break; +#ifdef SCHED_BATCH + case SCHED_BATCH: +#endif + case SCHED_OTHER: + param.sched_priority = 0; + break; + default: + g_warning ("%s: unknown policy %d", __func__, policy); + return; + } + } + + res = pthread_attr_setschedparam (attr, ¶m); + if (res != 0) + g_error ("%s: pthread_attr_setschedparam failed, error: \"%s\" (%d)", __func__, g_strerror (res), res); +} + int mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid) { pthread_attr_t attr; pthread_t thread; - int policy; - struct sched_param param; gint res; gsize set_stack_size; - size_t min_size; + gsize min_stack_size; res = pthread_attr_init (&attr); g_assert (!res); @@ -75,51 +121,14 @@ mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_ g_assert (!res); #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */ - memset (¶m, 0, sizeof (param)); - - res = pthread_attr_getschedpolicy (&attr, &policy); - if (res != 0) - g_error ("%s: pthread_attr_getschedpolicy failed, error: \"%s\" (%d)", g_strerror (res), res); - -#ifdef _POSIX_PRIORITY_SCHEDULING - int max, min; - - /* Necessary to get valid priority range */ - - min = sched_get_priority_min (policy); - max = sched_get_priority_max (policy); - - if (max > 0 && min >= 0 && max > min) - param.sched_priority = (max - min) / 2 + min; - else -#endif - { - switch (policy) { - case SCHED_FIFO: - case SCHED_RR: - param.sched_priority = 50; - break; -#ifdef SCHED_BATCH - case SCHED_BATCH: -#endif - case SCHED_OTHER: - param.sched_priority = 0; - break; - default: - g_error ("%s: unknown policy %d", __func__, policy); - } - } - - res = pthread_attr_setschedparam (&attr, ¶m); - if (res != 0) - g_error ("%s: pthread_attr_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res); + reset_priority (&attr); if (stack_size) { - res = pthread_attr_getstacksize (&attr, &min_size); + res = pthread_attr_getstacksize (&attr, &min_stack_size); if (res != 0) g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", g_strerror (res), res); - else - *stack_size = min_size; + + *stack_size = min_stack_size; } /* Actually start the thread */