Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Rozsival <simon@rozsival.com>2022-02-17 12:56:21 +0300
committerGitHub <noreply@github.com>2022-02-17 12:56:21 +0300
commit36daf033a620d800f6e65f4544ea55a3ecef7af0 (patch)
tree743efdb53cff978fd4cd44b36b98b7bdb416500a
parent1faa76848158e160207fa65a18fc0ff462799c4b (diff)
[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
-rw-r--r--mono/eglib/Makefile.am2
-rw-r--r--mono/eglib/eglib-remap.h2
-rw-r--r--mono/eglib/gclock-nanosleep.c31
-rw-r--r--mono/eglib/gdate-unix.c2
-rw-r--r--mono/eglib/glib.h6
-rw-r--r--mono/mini/mini-posix.c5
-rw-r--r--mono/utils/mono-threads.c3
7 files changed, 46 insertions, 5 deletions
diff --git a/mono/eglib/Makefile.am b/mono/eglib/Makefile.am
index fac81325d9f..f767d88859f 100644
--- a/mono/eglib/Makefile.am
+++ b/mono/eglib/Makefile.am
@@ -16,7 +16,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 \
- gspawn.c
+ gspawn.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 c3e956842de..f127f9630a6 100644
--- a/mono/eglib/eglib-remap.h
+++ b/mono/eglib/eglib-remap.h
@@ -318,3 +318,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 dbcc3997eff..2023e1a0548 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.
@@ -1520,4 +1521,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 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 dc8a6f2a1ee..bbafa91581c 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>
@@ -578,7 +579,7 @@ clock_init_for_profiler (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_clock = CLOCK_PROCESS_CPUTIME_ID;
break;
}
@@ -602,7 +603,7 @@ clock_sleep_ns_abs (guint64 ns_abs)
then.tv_nsec = ns_abs % 1000000000;
do {
- ret = clock_nanosleep (sampling_clock, TIMER_ABSTIME, &then, NULL);
+ ret = g_clock_nanosleep (sampling_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 8fb5deefd86..57a7849e6ac 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>
@@ -1750,7 +1751,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);