From: Richard Levitte Date: Mon, 3 Oct 2022 05:10:34 +0000 (+0200) Subject: Rename ossl_sleep() to OSSL_sleep() and make it public X-Git-Tag: openssl-3.2.0-alpha1~1960 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=82d28c6b3cbd8074faaa34cc2ce57dacc580792f;p=thirdparty%2Fopenssl.git Rename ossl_sleep() to OSSL_sleep() and make it public ossl_sleep() was implemented as a static inline function in internal/e_os.h, using usleep() on Unix and Sleep() on Windows. So far well and good. However, it also has a fallback implementation for systems that do not have usleep() or Sleep(), and that implementation happens to use ossl_time_now(), which is a normal function, private to libcrypto, and is judged to be too complex to sanely make into a static inline function. This fallback creates a problem, because we do use ossl_sleep() in apps/ and a few test programs in test/, and when they are linked with libcrypto in shared library form, ossl_time_now() can't be found, since it's not publicly exposed. Something needs to give, and the easiest, and hopefully sanest answer is to make ossl_sleep() a publicly exposed function, which requires a slight name change. Documentation and 'make update' result included. Reviewed-by: Paul Dale Reviewed-by: Matt Caswell Reviewed-by: Tim Hudson Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/19330) --- diff --git a/crypto/build.info b/crypto/build.info index 1c9ca3a8099..24985f443c2 100644 --- a/crypto/build.info +++ b/crypto/build.info @@ -107,7 +107,7 @@ SOURCE[../libcrypto]=$UTIL_COMMON \ mem.c mem_sec.c \ cversion.c info.c cpt_err.c ebcdic.c uid.c o_time.c o_dir.c \ o_fopen.c getenv.c o_init.c init.c trace.c provider.c provider_child.c \ - punycode.c passphrase.c + punycode.c passphrase.c sleep.c SOURCE[../providers/libfips.a]=$UTIL_COMMON SOURCE[../libcrypto]=$UPLINKSRC diff --git a/crypto/sleep.c b/crypto/sleep.c new file mode 100644 index 00000000000..1554d936cfa --- /dev/null +++ b/crypto/sleep.c @@ -0,0 +1,110 @@ +/* + * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/e_os.h" + +/* system-specific variants defining OSSL_sleep() */ +#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) + +void OSSL_sleep(uint64_t millis) +{ +# ifdef OPENSSL_SYS_VXWORKS + struct timespec ts; + + ts.tv_sec = (long int) (millis / 1000); + ts.tv_nsec = (long int) (millis % 1000) * 1000000ul; + nanosleep(&ts, NULL); +# elif defined(__TANDEM) +# if !defined(_REENTRANT) +# include + + /* HPNS does not support usleep for non threaded apps */ + PROCESS_DELAY_(millis * 1000); +# elif defined(_SPT_MODEL_) +# include +# include + + usleep(millis * 1000); +# else + usleep(millis * 1000); +# endif +# else + usleep(millis * 1000); +# endif +} +#elif defined(_WIN32) +# include + +void OSSL_sleep(uint64_t millis) +{ + /* + * Windows' Sleep() takes a DWORD argument, which is smaller than + * a uint64_t, so we need to split the two to shut the compiler up. + */ + DWORD dword_times; + DWORD i; + + dword_times = (DWORD)(millis >> (8 * sizeof(DWORD))); + millis &= (DWORD)-1; + if (dword_times > 0) { + for (i = dword_times; i-- > 0;) + Sleep((DWORD)-1); + /* + * The loop above slept 1 millisec less on each iteration than it + * should, this compensates by sleeping as many milliseconds as there + * were iterations. Yes, this is nit picky! + */ + Sleep(dword_times); + } + + /* Now, sleep the remaining milliseconds */ + Sleep((DWORD)(millis)); +} +#else +/* Fallback to a busy wait */ +# include "internal/time.h" + +static void ossl_sleep_secs(uint64_t secs) +{ + /* + * sleep() takes an unsigned int argument, which is smaller than + * a uint64_t, so it needs to be called in smaller increments. + */ + unsigned int uint_times; + unsigned int i; + + uint_times = (unsigned int)(secs >> (8 * sizeof(unsigned int))); + if (uint_times > 0) { + for (i = uint_times; i-- > 0;) + sleep((unsigned int)-1); + /* + * The loop above slept 1 second less on each iteration than it + * should, this compensates by sleeping as many seconds as there were + * iterations. Yes, this is nit picky! + */ + sleep(uint_times); + } +} + +static void ossl_sleep_millis(uint64_t millis) +{ + const OSSL_TIME finish + = ossl_time_add(ossl_time_now(), ossl_ms2time(millis)); + + while (ossl_time_compare(ossl_time_now(), finish) < 0) + /* busy wait */ ; +} + +void OSSL_sleep(uint64_t millis) +{ + ossl_sleep_secs(millis / 1000); + ossl_sleep_millis(millis % 1000); +} +#endif /* defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) */ diff --git a/doc/build.info b/doc/build.info index 809ffee95bb..45886a4f27d 100644 --- a/doc/build.info +++ b/doc/build.info @@ -1723,6 +1723,10 @@ DEPEND[html/man3/OSSL_STORE_open.html]=man3/OSSL_STORE_open.pod GENERATE[html/man3/OSSL_STORE_open.html]=man3/OSSL_STORE_open.pod DEPEND[man/man3/OSSL_STORE_open.3]=man3/OSSL_STORE_open.pod GENERATE[man/man3/OSSL_STORE_open.3]=man3/OSSL_STORE_open.pod +DEPEND[html/man3/OSSL_sleep.html]=man3/OSSL_sleep.pod +GENERATE[html/man3/OSSL_sleep.html]=man3/OSSL_sleep.pod +DEPEND[man/man3/OSSL_sleep.3]=man3/OSSL_sleep.pod +GENERATE[man/man3/OSSL_sleep.3]=man3/OSSL_sleep.pod DEPEND[html/man3/OSSL_trace_enabled.html]=man3/OSSL_trace_enabled.pod GENERATE[html/man3/OSSL_trace_enabled.html]=man3/OSSL_trace_enabled.pod DEPEND[man/man3/OSSL_trace_enabled.3]=man3/OSSL_trace_enabled.pod @@ -3194,6 +3198,7 @@ html/man3/OSSL_STORE_SEARCH.html \ html/man3/OSSL_STORE_attach.html \ html/man3/OSSL_STORE_expect.html \ html/man3/OSSL_STORE_open.html \ +html/man3/OSSL_sleep.html \ html/man3/OSSL_trace_enabled.html \ html/man3/OSSL_trace_get_category_num.html \ html/man3/OSSL_trace_set_channel.html \ @@ -3797,6 +3802,7 @@ man/man3/OSSL_STORE_SEARCH.3 \ man/man3/OSSL_STORE_attach.3 \ man/man3/OSSL_STORE_expect.3 \ man/man3/OSSL_STORE_open.3 \ +man/man3/OSSL_sleep.3 \ man/man3/OSSL_trace_enabled.3 \ man/man3/OSSL_trace_get_category_num.3 \ man/man3/OSSL_trace_set_channel.3 \ diff --git a/doc/man3/OSSL_sleep.pod b/doc/man3/OSSL_sleep.pod new file mode 100644 index 00000000000..5264d2b569e --- /dev/null +++ b/doc/man3/OSSL_sleep.pod @@ -0,0 +1,37 @@ +=pod + +=head1 NAME + +OSSL_sleep - delay execution for a specified number of milliseconds + +=head1 SYNOPSIS + + #include + + void OSSL_sleep(uint64_t millis); + +=head1 DESCRIPTION + +OSSL_sleep() is a convenience function to delay execution of the calling +thread for (at least) I milliseconds. The delay is not guaranteed; +it may be affected by system activity, by the time spent processing the call +or by system timer granularity. + +=head1 RETURN VALUES + +OSSL_sleep() does not return any value. + +=head1 HISTORY + +OSSL_sleep() was added in OpenSSL 3.2. + +=head1 COPYRIGHT + +Copyright 2022 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/internal/e_os.h b/include/internal/e_os.h index 059fae40404..6fc1c74c97c 100644 --- a/include/internal/e_os.h +++ b/include/internal/e_os.h @@ -286,50 +286,6 @@ struct servent *getservbyname(const char *name, const char *proto); # endif /* end vxworks */ -/* system-specific variants defining ossl_sleep() */ -#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__) -# include -static ossl_inline void ossl_sleep(unsigned long millis) -{ -# ifdef OPENSSL_SYS_VXWORKS - struct timespec ts; - ts.tv_sec = (long int) (millis / 1000); - ts.tv_nsec = (long int) (millis % 1000) * 1000000ul; - nanosleep(&ts, NULL); -# elif defined(__TANDEM) -# if !defined(_REENTRANT) -# include - /* HPNS does not support usleep for non threaded apps */ - PROCESS_DELAY_(millis * 1000); -# elif defined(_SPT_MODEL_) -# include -# include - usleep(millis * 1000); -# else - usleep(millis * 1000); -# endif -# else - usleep(millis * 1000); -# endif -} -#elif defined(_WIN32) -# include -static ossl_inline void ossl_sleep(unsigned long millis) -{ - Sleep(millis); -} -#else -/* Fallback to a busy wait */ -# include "internal/time.h" -static ossl_inline void ossl_sleep(unsigned long millis) -{ - const OSSL_TIME finish = ossl_time_add(ossl_time_now(), ossl_ms2time(millis)); - - while (ossl_time_compare(ossl_time_now(), finish) < 0) - /* busy wait */ ; -} -#endif /* defined OPENSSL_SYS_UNIX */ - /* ----------------------------- HP NonStop -------------------------------- */ /* Required to support platform variant without getpid() and pid_t. */ # if defined(__TANDEM) && defined(_GUARDIAN_TARGET) diff --git a/include/openssl/crypto.h.in b/include/openssl/crypto.h.in index fb0c7cbb871..963bc635fb1 100644 --- a/include/openssl/crypto.h.in +++ b/include/openssl/crypto.h.in @@ -529,6 +529,8 @@ void OSSL_LIB_CTX_free(OSSL_LIB_CTX *); OSSL_LIB_CTX *OSSL_LIB_CTX_get0_global_default(void); OSSL_LIB_CTX *OSSL_LIB_CTX_set0_default(OSSL_LIB_CTX *libctx); +void OSSL_sleep(uint64_t millis); + # ifdef __cplusplus } # endif diff --git a/util/libcrypto.num b/util/libcrypto.num index 4c5cd7907d3..f9c1395859f 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -5465,3 +5465,4 @@ EVP_PKEY_auth_encapsulate_init ? 3_1_0 EXIST::FUNCTION: EVP_PKEY_auth_decapsulate_init ? 3_1_0 EXIST::FUNCTION: PKCS12_SAFEBAG_set0_attrs ? 3_1_0 EXIST::FUNCTION: PKCS12_create_ex2 ? 3_1_0 EXIST::FUNCTION: +OSSL_sleep ? 3_1_0 EXIST::FUNCTION: