Skip to content

Instantly share code, notes, and snippets.

@rolfbjarne
Last active February 11, 2016 11:25
Show Gist options
  • Save rolfbjarne/0ab4e14300b0bf175a13 to your computer and use it in GitHub Desktop.
Save rolfbjarne/0ab4e14300b0bf175a13 to your computer and use it in GitHub Desktop.
commit 881d382a2b2ac6eed60f6e61460640fc61de1b51
Author: Rolf Bjarne Kvinge <[email protected]>
Date: Thu Feb 11 12:19:07 2016 +0100
[threads] Use 64-bit math (and nanoseconds) to keep track of time in sleep_interruptable. Fixes #38663.
mono_msec_ticks returns a 32-bit value of milliseconds since the last boot.
This value overflows after ~20 days, causing deadlocks since the timeout might
end up becoming -1, which means an infinite timeout.
Instead use mono_100ns_ticks, which is a 64-bit value that won't overflow
for ~500 years.
diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c
index e677ada..43cb9a2 100644
--- a/mono/utils/mono-threads.c
+++ b/mono/utils/mono-threads.c
@@ -1124,27 +1124,27 @@ sleep_interrupt (gpointer data)
static inline guint32
sleep_interruptable (guint32 ms, gboolean *alerted)
{
- guint32 start, now, end;
+ gint64 start, now, end;
g_assert (INFINITE == G_MAXUINT32);
g_assert (alerted);
*alerted = FALSE;
- start = mono_msec_ticks ();
+ start = mono_100ns_ticks ();
- if (start < G_MAXUINT32 - ms) {
+ if (start < G_MAXINT64 - ms) {
end = start + ms;
} else {
- /* start + ms would overflow guint32 */
- end = G_MAXUINT32;
+ /* start + ms would overflow gint64 */
+ end = G_MAXINT64;
}
mono_lazy_initialize (&sleep_init, sleep_initialize);
mono_coop_mutex_lock (&sleep_mutex);
- for (now = mono_msec_ticks (); ms == INFINITE || now - start < ms; now = mono_msec_ticks ()) {
+ for (now = mono_100ns_ticks (); ms == INFINITE || now - start < ms; now = mono_100ns_ticks ()) {
mono_thread_info_install_interrupt (sleep_interrupt, NULL, alerted);
if (*alerted) {
mono_coop_mutex_unlock (&sleep_mutex);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment