Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:23
erlang
1428-erts-Ensure-ethr_event-can-handle-huge-tim...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 1428-erts-Ensure-ethr_event-can-handle-huge-timeouts.patch of Package erlang
From bb02aa139d19e3992de7eb7d282b323e9bf26b0e Mon Sep 17 00:00:00 2001 From: Rickard Green <rickard@erlang.org> Date: Sat, 23 Dec 2023 22:35:24 +0100 Subject: [PATCH 2/3] [erts] Ensure ethr_event can handle huge timeouts --- erts/include/internal/erl_errno.h | 3 +++ erts/lib_src/pthread/ethr_event.c | 41 ++++++++++++++++++++++++++----- erts/lib_src/win/ethr_event.c | 15 +++++++++-- 3 files changed, 51 insertions(+), 8 deletions(-) diff --git a/erts/include/internal/erl_errno.h b/erts/include/internal/erl_errno.h index 1ae045805e..dad9e36a90 100644 --- a/erts/include/internal/erl_errno.h +++ b/erts/include/internal/erl_errno.h @@ -47,6 +47,9 @@ # ifndef ETIMEDOUT # define ETIMEDOUT EAGAIN # endif +# ifndef EINTR +# define EINTR (INT_MAX-1) +# endif #endif #endif diff --git a/erts/lib_src/pthread/ethr_event.c b/erts/lib_src/pthread/ethr_event.c index 26f4da7d60..6b6235122a 100644 --- a/erts/lib_src/pthread/ethr_event.c +++ b/erts/lib_src/pthread/ethr_event.c @@ -52,6 +52,7 @@ #include <sched.h> #include <errno.h> +#include <limits.h> #define ETHR_YIELD_AFTER_BUSY_LOOPS 50 @@ -92,6 +93,7 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout) #ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME ethr_sint64_t start = 0; /* SHUT UP annoying faulty warning... */ #endif + int timeout_res = ETIMEDOUT; if (spincount < 0) ETHR_FATAL_ERROR__(EINVAL); @@ -131,6 +133,7 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout) } if (timeout >= 0) { + ethr_sint64_t sec, nsec; #ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME time = timeout - (ethr_get_monotonic_time() - start); #endif @@ -141,8 +144,18 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout) goto return_event_on; return ETIMEDOUT; } - ts.tv_sec = time / (1000*1000*1000); - ts.tv_nsec = time % (1000*1000*1000); + sec = time / (1000*1000*1000); + nsec = time % (1000*1000*1000); + if (sizeof(ts.tv_sec) == 8 + || sec <= (ethr_sint64_t) INT_MAX) { + ts.tv_sec = sec; + ts.tv_nsec = nsec; + } + else { + ts.tv_sec = INT_MAX; + ts.tv_nsec = 0; + timeout_res = EINTR; + } } if (val != ETHR_EVENT_OFF_WAITER__) { @@ -160,8 +173,10 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout) ETHR_EVENT_OFF_WAITER__, tsp); switch (res) { - case EINTR: case ETIMEDOUT: + res = timeout_res; + /* Fall through... */ + case EINTR: return res; case 0: case EWOULDBLOCK: @@ -189,6 +204,7 @@ return_event_on: #include <sys/select.h> #include <errno.h> #include <string.h> +#include <limits.h> #include "erl_misc_utils.h" @@ -358,6 +374,7 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout) #ifdef ETHR_HAVE_ETHR_GET_MONOTONIC_TIME ethr_sint64_t timeout_time = 0; /* SHUT UP annoying faulty warning... */ #endif + int timeout_res = ETIMEDOUT; val = ethr_atomic32_read(&e->state); if (val == ETHR_EVENT_ON__) @@ -452,6 +469,7 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout) #ifdef ETHR_HAVE_PTHREAD_COND_TIMEDWAIT_MONOTONIC if (timeout > 0) { if (time != timeout_time) { + ethr_sint64_t sec, nsec; time = timeout_time; #if ERTS_USE_PREMATURE_TIMEOUT @@ -467,11 +485,22 @@ wait__(ethr_event *e, int spincount, ethr_sint64_t timeout) time -= ERTS_PREMATURE_TIMEOUT(rtmo, 1000*1000*1000); } #endif - - cond_timeout.tv_sec = time / (1000*1000*1000); - cond_timeout.tv_nsec = time % (1000*1000*1000); + sec = time / (1000*1000*1000); + nsec = time % (1000*1000*1000); + if (sizeof(cond_timeout.tv_sec) == 8 + || sec <= (ethr_sint64_t) INT_MAX) { + cond_timeout.tv_sec = sec; + cond_timeout.tv_nsec = nsec; + } + else { + cond_timeout.tv_sec = INT_MAX; + cond_timeout.tv_nsec = 0; + timeout_res = EINTR; + } } res = pthread_cond_timedwait(&e->cnd, &e->mtx, &cond_timeout); + if (res == ETIMEDOUT) + res = timeout_res; if (res == EINTR || (res == ETIMEDOUT #if ERTS_USE_PREMATURE_TIMEOUT diff --git a/erts/lib_src/win/ethr_event.c b/erts/lib_src/win/ethr_event.c index 383f7c876e..d03c6342cc 100644 --- a/erts/lib_src/win/ethr_event.c +++ b/erts/lib_src/win/ethr_event.c @@ -71,11 +71,14 @@ ethr_event_reset(ethr_event *e) ethr_event_reset__(e); } +#define MILLISECONDS_PER_WEEK__ (7*24*60*60*1000) + static ETHR_INLINE int wait(ethr_event *e, int spincount, ethr_sint64_t timeout) { DWORD code, tmo; int sc, res, until_yield = ETHR_YIELD_AFTER_BUSY_LOOPS; + int timeout_res = ETIMEDOUT; if (timeout < 0) tmo = INFINITE; @@ -88,11 +91,19 @@ wait(ethr_event *e, int spincount, ethr_sint64_t timeout) return ETIMEDOUT; } else { + ethr_sint64_t tmo_ms; /* * Timeout in nano-seconds, but we can only * wait for milli-seconds... */ - tmo = (DWORD) (timeout - 1) / (1000*1000) + 1; + tmo_ms = (timeout - 1) / (1000*1000) + 1; + if (tmo_ms <= MILLISECONDS_PER_WEEK__) { + tmo = (DWORD) tmo_ms; + } + else { + tmo = MILLISECONDS_PER_WEEK__; + timeout_res = EINTR; + } } if (spincount < 0) @@ -131,7 +142,7 @@ wait(ethr_event *e, int spincount, ethr_sint64_t timeout) code = WaitForSingleObject(e->handle, tmo); if (code == WAIT_TIMEOUT) - return ETIMEDOUT; + return timeout_res; if (code != WAIT_OBJECT_0) ETHR_FATAL_ERROR__(ethr_win_get_errno__()); } -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor