diff options
author | Alexander Köplinger <alex.koeplinger@outlook.com> | 2022-02-17 19:50:29 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-17 19:50:29 +0300 |
commit | f34bd77e39212e3a3910775ff08489adfc1013e6 (patch) | |
tree | 8eed63b5081d3f51cda9141287553d89717537cb | |
parent | 0f5e80e5770d4aeae06831f65d9f211d99d678f4 (diff) |
[2020-02][Android] Workaround for invalid return value from clock_nanosleep (#21435)mono-6.12.0.173
* [Android] Workaround for invalid return value from clock_nanosleep (#21433)
Fixes https://github.com/xamarin/xamarin-android/issues/6600
Backported from https://github.com/dotnet/runtime/pull/64679 and https://github.com/dotnet/runtime/pull/65373
(cherry picked from commit 36daf033a620d800f6e65f4544ea55a3ecef7af0)
* Fix Windows build
Co-authored-by: Simon Rozsival <simon@rozsival.com>
-rw-r--r-- | mono/eglib/Makefile.am | 2 | ||||
-rw-r--r-- | mono/eglib/eglib-remap.h | 2 | ||||
-rw-r--r-- | mono/eglib/gclock-nanosleep.c | 31 | ||||
-rw-r--r-- | mono/eglib/gdate-unix.c | 2 | ||||
-rw-r--r-- | mono/eglib/glib.h | 6 | ||||
-rw-r--r-- | mono/mini/mini-posix.c | 5 | ||||
-rw-r--r-- | mono/utils/mono-threads.c | 3 |
7 files changed, 46 insertions, 5 deletions
diff --git a/mono/eglib/Makefile.am b/mono/eglib/Makefile.am index dfdcd0e6797..ab20333b857 100644 --- a/mono/eglib/Makefile.am +++ b/mono/eglib/Makefile.am @@ -15,7 +15,7 @@ win_files = \ unix_files = \ gdate-unix.c gdir-unix.c gfile-unix.c gmisc-unix.c \ - gmodule-unix.c gtimer-unix.c gmodule-aix.c + gmodule-unix.c gtimer-unix.c gmodule-aix.c gclock-nanosleep.c if HOST_WIN32 os_files = $(win_files) diff --git a/mono/eglib/eglib-remap.h b/mono/eglib/eglib-remap.h index c9751049c3b..b7471efb00d 100644 --- a/mono/eglib/eglib-remap.h +++ b/mono/eglib/eglib-remap.h @@ -314,3 +314,5 @@ #define g_ascii_charcmp monoeg_ascii_charcmp #define g_ascii_charcasecmp monoeg_ascii_charcasecmp #define g_warning_d monoeg_warning_d + +#define g_clock_nanosleep monoeg_clock_nanosleep diff --git a/mono/eglib/gclock-nanosleep.c b/mono/eglib/gclock-nanosleep.c new file mode 100644 index 00000000000..f2ced8b2c07 --- /dev/null +++ b/mono/eglib/gclock-nanosleep.c @@ -0,0 +1,31 @@ +/* + * gclock_nanosleep.c: Clock nanosleep on platforms that have clock_nanosleep(). + * + * Copyright 2022 Microsoft + * Licensed under the MIT license. See LICENSE file in the project root for full license information. +*/ + +#include <config.h> +#include <glib.h> +#include <errno.h> + +gint +g_clock_nanosleep (clockid_t clockid, gint flags, const struct timespec *request, struct timespec *remain) +{ + gint ret = 0; + +#if defined(HAVE_CLOCK_NANOSLEEP) && !defined(__PASE__) + ret = clock_nanosleep (clockid, flags, request, remain); +#else + g_assert_not_reached (); +#endif + +#ifdef HOST_ANDROID + // Workaround for incorrect implementation of clock_nanosleep return value on old Android (<=5.1) + // See https://github.com/xamarin/xamarin-android/issues/6600 + if (ret == -1) + ret = errno; +#endif + + return ret; +} diff --git a/mono/eglib/gdate-unix.c b/mono/eglib/gdate-unix.c index 53f4bbb3d5a..9a98e663045 100644 --- a/mono/eglib/gdate-unix.c +++ b/mono/eglib/gdate-unix.c @@ -64,7 +64,7 @@ g_usleep (gulong microseconds) } do { - ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); + ret = g_clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); if (ret != 0 && ret != EINTR) g_error ("%s: clock_nanosleep () returned %d", __func__, ret); } while (ret == EINTR); diff --git a/mono/eglib/glib.h b/mono/eglib/glib.h index 4d84563481b..d6d76cb6cda 100644 --- a/mono/eglib/glib.h +++ b/mono/eglib/glib.h @@ -31,6 +31,7 @@ #else #include <eglib-config.h> #endif +#include <time.h> // - Pointers should only be converted to or from pointer-sized integers. // - Any size integer can be converted to any other size integer. @@ -1486,4 +1487,9 @@ mono_qsort (void* base, size_t num, size_t size, int (*compare)(const void*, con #define g_try_realloc(obj, size) (g_cast (monoeg_try_realloc ((obj), (size)))) #define g_memdup(mem, size) (g_cast (monoeg_g_memdup ((mem), (size)))) +#ifndef G_OS_WIN32 +gint +g_clock_nanosleep (clockid_t clockid, gint flags, const struct timespec *request, struct timespec *remain); +#endif + #endif // __GLIB_H diff --git a/mono/mini/mini-posix.c b/mono/mini/mini-posix.c index 7f9537423d1..1cee3b530b4 100644 --- a/mono/mini/mini-posix.c +++ b/mono/mini/mini-posix.c @@ -80,6 +80,7 @@ #include "debugger-agent.h" #include "mini-runtime.h" #include "jit-icalls.h" +#include <glib.h> #ifdef HOST_DARWIN #include <mach/mach.h> @@ -600,7 +601,7 @@ clock_init (MonoProfilerSampleMode mode) * CLOCK_PROCESS_CPUTIME_ID clock but don't actually support it. For * those systems, we fall back to CLOCK_MONOTONIC if we get EINVAL. */ - if (clock_nanosleep (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME, &ts, NULL) != EINVAL) { + if (g_clock_nanosleep (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME, &ts, NULL) != EINVAL) { sampling_posix_clock = CLOCK_PROCESS_CPUTIME_ID; break; } @@ -640,7 +641,7 @@ clock_sleep_ns_abs (guint64 ns_abs) then.tv_nsec = ns_abs % 1000000000; do { - ret = clock_nanosleep (sampling_posix_clock, TIMER_ABSTIME, &then, NULL); + ret = g_clock_nanosleep (sampling_posix_clock, TIMER_ABSTIME, &then, NULL); if (ret != 0 && ret != EINTR) g_error ("%s: clock_nanosleep () returned %d", __func__, ret); diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c index ec9f98c7317..7df25cd4c1f 100644 --- a/mono/utils/mono-threads.c +++ b/mono/utils/mono-threads.c @@ -33,6 +33,7 @@ #include <mono/utils/mono-threads-debug.h> #include <mono/utils/os-event.h> #include <mono/utils/w32api.h> +#include <glib.h> #include <errno.h> #include <mono/utils/mono-errno.h> @@ -1699,7 +1700,7 @@ mono_thread_info_sleep (guint32 ms, gboolean *alerted) } do { - ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); + ret = g_clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); } while (ret != 0); #elif HOST_WIN32 Sleep (ms); |