summaryrefslogtreecommitdiff
path: root/threadproc
Commit message (Collapse)AuthorAgeFilesLines
* apr_thread: Follow up to r1897207: apr_thread_current_create() is ENOTIMPL ↵Yann Ylavic2023-03-155-10/+20
| | | | | | | | | | w/o APR_HAS_THREAD_LOCAL. It's useless when !APR_HAS_THREAD_LOCAL since apr_thread_current() can't work. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1908417 13f79535-47bb-0310-9956-ffa450edef68
* Improve comment.Ivan Zhakov2023-01-231-2/+2
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1906943 13f79535-47bb-0310-9956-ffa450edef68
* Merge thread-name branch (PR 60587) [1]:Ivan Zhakov2023-01-215-0/+167
|\ | | | | | | | | | | | | | | | | * Introduce apr_thread_name_set() and apr_thread_name_get(). [1] https://bz.apache.org/bugzilla/show_bug.cgi?id=60587 [2] https://lists.apache.org/thread/z24logzc6v8tc0p2q3375cc10qo9y5yw git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1906889 13f79535-47bb-0310-9956-ffa450edef68
| * On 'thread-name' branch: Check pthread_setname_np()/pthread_getname_np()Ivan Zhakov2022-06-291-0/+8
| | | | | | | | | | | | | | | | | | | | support. * threadproc/unix/thread.c (apr_thread_name_set, apr_thread_name_get): Return APR_ENOTIMPL if not HAVE_PTHREAD_SETNAME_NP. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/thread-name@1902352 13f79535-47bb-0310-9956-ffa450edef68
| * On 'thread-name' branch: Add apr_thread_name_get() and apr_thread_name_set()Ivan Zhakov2022-06-275-0/+159
| | | | | | | | | | | | API to get/set thread name. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/thread-name@1902297 13f79535-47bb-0310-9956-ffa450edef68
* | Follow-up to r1906885.Ivan Zhakov2023-01-211-12/+14
| | | | | | | | | | | | | | | | | | * threadproc/win32/proc.c (apr_proc_create): Close redirect pipes only on success to match pre-r1906885 behavior. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1906888 13f79535-47bb-0310-9956-ffa450edef68
* | Simplify code.Ivan Zhakov2023-01-211-3/+3
| | | | | | | | | | | | | | | | | | * threadproc/win32/proc.c (apr_proc_create): Use apr_wchar_t for pEnvBlock local variable and avoid unnecessary casts. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1906887 13f79535-47bb-0310-9956-ffa450edef68
* | Use sizeof(apr_wchar_t) instead of magic 2.Ivan Zhakov2023-01-211-1/+1
| | | | | | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1906886 13f79535-47bb-0310-9956-ffa450edef68
* | Fix potential handle leak when apr_proc_create() is used from from multipleIvan Zhakov2023-01-211-9/+15
| | | | | | | | | | | | | | | | | | | | | | threads on Windows. * threadproc/win32/proc.c (apr_proc_create): Close our side of pipes before releasing lock: otherwise they could like to other process when apr_proc_create() is used from from multiple threads. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1906885 13f79535-47bb-0310-9956-ffa450edef68
* | apr_proc_create(): Fix incorrect error handling when pipes are redirectedIvan Zhakov2023-01-211-6/+19
| | | | | | | | | | | | | | | | | | | | | | on Windows. * threadproc/win32/proc.c (apr_proc_create): Save last error immediately after CreateProcessAsUserW()/ CreateProcessW() call, otherwise it can be lost by later calls. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1906863 13f79535-47bb-0310-9956-ffa450edef68
* | Remove trailing whitespaces in *.c.Ivan Zhakov2022-11-2018-215/+215
| | | | | | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1905414 13f79535-47bb-0310-9956-ffa450edef68
* | apr_thread: Provide apr_threadattr_max_free_set().Yann Ylavic2022-07-145-50/+60
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When creating a thread, this allows to specify the "max_free" of its pool allocator (i.e. apr_allocator_max_free_set), so that one can create thread local subpools and have their memory usage regulated on cleanup/destroy. One could achieve that already with: apr_allocator_max_free_set(apr_thread_pool_get(thread), max_free); in the thread startup function, but it's more convenient, simpler and race free to handle that in the thread attribute itself at creation time. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902715 13f79535-47bb-0310-9956-ffa450edef68
* | Replace tabs to spaces.Ivan Zhakov2022-07-084-120/+120
|/ | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902583 13f79535-47bb-0310-9956-ffa450edef68
* win32: Fix potential race condition in apr_thread_create.Ivan Zhakov2022-06-271-1/+3
| | | | | | | | | | | * CHANGES: Add changelog entry. * threadproc/win32/thread.c (apr_thread_create): Create suspended thread, initialize apr_thread_t->td and only after that resume thread. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902277 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Fix pointer to int conversion warning.Yann Ylavic2022-06-231-1/+1
| | | | | | | | | * threadproc/win32/thread.c(dummy_worker): First cast to apr_uinptr_t before conversion pointer to int. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902198 13f79535-47bb-0310-9956-ffa450edef68
* proc: Fix different 'const' qualifiers warning.Yann Ylavic2022-06-231-3/+3
| | | | | | | | | * threadproc/win32/proc.c(apr_proc_create): Don't assign const strings to "cmdline". git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902197 13f79535-47bb-0310-9956-ffa450edef68
* win32: Fix spurious apr_thread_once() failures.Ivan Zhakov2022-06-211-3/+1
| | | | | | | | | | | * threadproc/win32/thread.c (apr_thread_once): Pass NULL as lpContext argument in call to InitOnceExecuteOnce(). According to documentation pointer stored in lpContext should be DWORD aligned. We do not use lpContext argument and lpContext is optional, so just use NULL. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902129 13f79535-47bb-0310-9956-ffa450edef68
* * threadproc/win32/thread.cIvan Zhakov2022-06-201-3/+3
| | | | | | | | (apr_thread_create): Do not cast function pointer... (dummy_worker): ... cast return value. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902077 13f79535-47bb-0310-9956-ffa450edef68
* * threadproc/win32/thread.cIvan Zhakov2022-06-191-1/+1
| | | | | | | (dummy_worker): Use correct calling convention (APR_THREAD_FUNC). git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902076 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1897207 and r1897471: s/AP_HAS_/APR_HAS_/gYann Ylavic2022-06-174-4/+4
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1902019 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1897207: apr_thread_current_create() compilation.Yann Ylavic2022-02-085-2/+7
| | | | | | | | | Fix compilation of apr_thread_current_create() for OS/2 and Windows. Set *current to NULL on failure. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897879 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1897207: Provide apr_thread_current_after_fork().Yann Ylavic2022-01-259-0/+47
| | | | | | | | | | | thread_local variables are not (always?) reset on fork(), so APR (and the user) needs a way to set the current_thread to NULL. Use apr_thread_current_after_fork() in apr_proc_fork()'s child process. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897470 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1897207: Make APR_HAS_THREAD_LOCAL a boolean..Yann Ylavic2022-01-255-21/+21
| | | | | | | | .. rather than a defined(). git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897447 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1897207: Don't NULLify current_thread on exit.Yann Ylavic2022-01-255-33/+5
| | | | | | | | It's not needed, when the thread exits it's not accessible anyway. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897445 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1897179: abort_fn on apr_allocator_create() failure.Yann Ylavic2022-01-245-10/+20
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897419 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Use compiler's TLS to track the current apr_thread_t's pointer.Yann Ylavic2022-01-195-56/+398
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | All modern compilers provide a Thread Local Storage keyword that allows to store per-thread data efficiently (C++11 's thread_local, C11's _Thread_local, gcc/clang's __thread or MSVC's __declspec(thread)). Use that to have an apr_thread_t pointer associated with each thread created by apr_thread_create() or any native thread (like the process' initial thread) that registered itself with the new apr_thread_current_create() function. This mechanism allows to implement apr_thread_current() quite efficiently, if available, otherwise the function returns NULL. If available APR_HAS_THREAD_LOCAL is #define'd to 1 and the APR_THREAD_LOCAL macro is the keyword usable to register TLS variables natively. Both APR_HAS_THREAD_LOCAL and APR_THREAD_LOCAL are #undef'ined if the compiler does not provide the mechanism. This allows to test for the functionality at compile time. When APR_HAS_THREAD_LOCAL, the user can load his/her own TLS data with: apr_thread_data_get(&my_data, my_key, apr_thread_current()); and store them with: apr_thread_data_set(my_data, my_key, my_data_cleanup, apr_thread_current()); which can be nice to avoid the proliferation of native TLS keys. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897207 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1897197: Safer apr_thread_join().Yann Ylavic2022-01-193-20/+15
| | | | | | | | | Make sure apr_thread_join() behaves correctly w.r.t. the returned value and pool destroy for all archs. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897198 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Allocate the apr_thread_t struct on the thread's pool.Yann Ylavic2022-01-195-64/+71
| | | | | | | | | | | | | | | | apr_thread_create() was allocating the created apr_thread_t on the given pool, which caused e.g. short-living threads to leak memory on that pool without a way to clear it (while some threads are still running). Change this by allocating the apr_thread_t on the thread's pool itself, which is safe in the implementations of all archs because none uses the apr_thread_t after the thread exits, and it's safe for the users provided they don't use the apr_thread_t for detached threads or for attached threads after the call to apr_thread_join(). These are hardly new requirements though. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897197 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: Follow up to r1884078: Unmanaged pools for attached threads too.Yann Ylavic2022-01-185-225/+155
| | | | | | | | | | | | | | | | | | | | | | | | r1884078 fixed lifetime issues with detached threads by using unmanaged pool destroyed by the thread itself on exit, with no binding to the parent pool. This commit makes use of unmanaged pools for attached threads too, they needed their own allocator anyway due to apr_thread_detach() being callable anytime later. apr__pool_unmanage() was a hack to detach a subpool from its parent, but if a subpool needs its own allocator for this to work correctly there is no point in creating a subpool for threads (no memory reuse on destroy for short living threads for instance). Since an attached thread has its own lifetime now, apr_thread_join() must be called to free its resources/pool, though it's no different than before when destroying the parent pool was UB if the thread was still running (i.e. not joined yet). Let's acknoledge that threads want no binding with the pool passed to them at creation time, besides the abort_fn which they can steal :) git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1897179 13f79535-47bb-0310-9956-ffa450edef68
* Stage 3 in dismantling _WIN32_WCE ... cleanup codeMladen Turk2021-12-021-13/+0
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1895508 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: use unmanaged pools for detached threads.Yann Ylavic2020-12-035-11/+165
| | | | | | | | | | | | | | | | A detached thread is by definition out of control, unjoinable, unmanaged, and it can terminate/exit after its parent pool is detroyed. To avoid use-after-free in this case, let's use an unmanaged pool for detached threads, either by creating an unmanaged pool from the start if the thread is created detached, or by "unmanaging" the pool if the thread is detached later with apr_thread_detach(). To "umanage" the pool, provide a new internal helper, apr__pool_unmanage() which takes care of removing the pool from its parent's list. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1884078 13f79535-47bb-0310-9956-ffa450edef68
* apr_thread: destroy the thread's pool at _join() time, unless _detach()ed.Yann Ylavic2020-12-035-28/+97
| | | | | | | | | | | | | | Destroying a joinable thread pool from apr_thread_exit() or when the thread function returns, i.e. from inside the thread itself, is racy or deadlocky with APR_POOL_DEBUG, with the parent pool being destroyed. This commit adds a ->detached flag in each arch's apr_thread_t struct to track whether a thread is detached (either at _create() or _detach() time). If detached, the pool is destroyed when the thread exits, otherwise when the thread is joined with apr_thread_join(). git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1884077 13f79535-47bb-0310-9956-ffa450edef68
* ucs2 is a legacy name, the correct encoding namesWilliam A. Rowe Jr2019-10-291-26/+19
| | | | | | | | | | | | | | | | are now utf-8, utf-16, and utf-32, so we rename; apr_conv_utf8_to_ucs2 -> apr_conv_utf8_to_utf16 apr_conv_ucs2_to_utf8 -> apr_conv_utf16_to_utf8 This patch notices an error message printing of an internal password, which will no longer be echoed to the error stream. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1869127 13f79535-47bb-0310-9956-ffa450edef68
* * threadproc/win32/thread.cIvan Zhakov2019-10-221-10/+1
| | | | | | | (apr_thread_yield): Remove Windows CE and Win9x compatibility code. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1868774 13f79535-47bb-0310-9956-ffa450edef68
* apr_proc_create(): Properly escape arguments containing whitespace charactersIvan Zhakov2019-10-151-6/+86
| | | | | | | | | | | | | | | | | | | | on Windows. * CMakeLists.txt (single_source_programs): Add test/echoargs.c. * test/echoargs.c: New test app for test_proc_args test. * test/testproc.c (test_proc_args): New test. (testproc): Add test_proc_args to test list. * threadproc/win32/proc.c (quote_arg): New. Helper for apr_proc_create(). (apr_proc_create): Use quote_arg() helper to escape arguments in command line. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1868477 13f79535-47bb-0310-9956-ffa450edef68
* Refactoring. No functional changes intended.Ivan Zhakov2019-10-151-15/+35
| | | | | | | | | * threadproc/win32/proc.c (apr_proc_create): Do not share code to build CMDLINE in different situations. SHELLCMD, .bat and regular executables have different rules for cmdline escaping. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1868469 13f79535-47bb-0310-9956-ffa450edef68
* * threadproc/win32/proc.cIvan Zhakov2019-09-091-7/+5
| | | | | | (apr_proc_create): Remove Windows 98 compatibility code. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1866714 13f79535-47bb-0310-9956-ffa450edef68
* * threadproc/win32/proc.cIvan Zhakov2019-09-091-35/+18
| | | | | | | (apr_proc_create): Remove compatibility code for command.com which is only available on Windows 98 and bellow. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1866713 13f79535-47bb-0310-9956-ffa450edef68
* * threadproc/win32/proc.c: Remove Windows CE and non-unicode code.Ivan Zhakov2019-07-101-217/+93
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1862856 13f79535-47bb-0310-9956-ffa450edef68
* API/ABI change, drop return value of apr_thread_exit() which hasJoe Orton2019-07-035-14/+6
| | | | | | | | | | | | no useful (nor documented) semantic: * include/apr_thread_proc.h (apr_thread_exit): Make void function; mark with gcc noreturn attribute. * threadproc/*/thread.c (apr_thread_exit): Update accordingly. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1862446 13f79535-47bb-0310-9956-ffa450edef68
* Use native one-time initialization [1] to implement apr_thread_once_t onIvan Zhakov2019-05-191-4/+24
| | | | | | | | | | | Windows. This also fixes problem that apr_thread_once() may return before the other read completes initialization on Windows. [1] https://docs.microsoft.com/en-gb/windows/desktop/Sync/one-time-initialization git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1859517 13f79535-47bb-0310-9956-ffa450edef68
* Use API constant instead of magic number.Ivan Zhakov2019-05-131-1/+1
| | | | | | | | * threadproc/win32/threadpriv.c (apr_threadkey_private_create): Use TLS_OUT_OF_INDEXES instead of hardcoded 0xFFFFFFFF. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1859171 13f79535-47bb-0310-9956-ffa450edef68
* Signals: Allow handling of SIGUSR2 in apr_signal_thread.Yann Ylavic2019-02-221-6/+0
| | | | | | | | It's not like users have so many free signals to play with, let's increase this number by 100% here, not so bad :) git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1854123 13f79535-47bb-0310-9956-ffa450edef68
* apr_crypto: follow up to r1833359: better cprng_stream_bytes() semantics.Yann Ylavic2018-06-281-2/+2
| | | | | | | | | | | | Make cprng_stream_ctx_bytes() rekey in any case, this is exactly what we need both when generating pooled random bytes and when handling fork() the parent and child key should not leak to each other. There is no use case for a keystream without setting the key first and burning it afterward, and there shouldn't be. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1834600 13f79535-47bb-0310-9956-ffa450edef68
* apr_crypto: follow up to r1833359: improve CPRNGs fork()ing.Yann Ylavic2018-06-271-2/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rework apr_crypto_prng_after_fork() which now handles rekeying of all the CPRNGs created within apr_crypto, by maintaining them in a global APR_RING, with the notable exception of per-thread ones (never forked). For each maintained CPRNG, apr_crypto_prng_after_fork() will now first rekey both the parent and child processes (determined by the 'in_child' argument provided by the caller), and for the parent only rekey a second time so that the initial states finally differ for both processes. Once these new keys are committed to their respective CPRNGs, thanks to and in continuity with the forward secrecy construct of apr_crypto_prng, there will be no in memory key material or stream that one process can inherit or infer from the other. The user can also rekey a CPRNG explicitely by calling the new function apr_crypto_prng_rekey(), and this is done by apr_fork() implicitely before forking any child, thus for the parent process. This safe guard ensures both the clearing of the pooled random bytes (buffered keystream) and the renewal of key material (cheap and preventive against _atfork() handlers or alike). Rekeying is done by using each CPRNG's keystream directly, there isn't anymore the use of a PID (or SHA256 thereof) for children processes nor any extra reads from the system RNG. All the apr_crypto_prng API is now self contained and can work entirely with a single stream cipher as primitive (Chacha20 or AES256-CTR, in that order of availability) and the initial entropy of 32 bytes gathered from the system. IOW, there is only one call issued to the system RNG for the global CPRNG's initial key, and if more CPRNGs are created their own initial key is produced by the global CPRNG. The KAT arrays in the tests suite needed adjustment too because the initial seed (if provided, like the zeros-input for the KAT) is no more used directly as the first key. Instead the first 32 bytes of the keystream generated from the seed are, and the seed (like any just used key) is then cleared immediatly from internal memory. Finally some private APR_CRYPTO_PRNG_* macros (in .c file only) are renamed to CPRNG_* to shorten colomns and avoid multilines in several cases. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1834551 13f79535-47bb-0310-9956-ffa450edef68
* Follow up to r1833359: apr_crypto_prng_after_fork() can now use a PID.Yann Ylavic2018-06-121-1/+1
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1833382 13f79535-47bb-0310-9956-ffa450edef68
* Cryptographic Pseudo Random Number Generator (CPRNG).Yann Ylavic2018-06-111-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | New apr_crypto_prng API and apr_crypto[_thread]_random_bytes() functions. Allows to generate cryptographically secure random bytes indefinitely given an initial seed of APR_CRYPTO_PRNG_SEED_SIZE bytes (32), which is either provided by the caller or automatically gathered from the system. The CPRNG can also be re-seeded at any time, or after a process is fork()ed. The internal key is renewed every APR_CRYPTO_PRNG_SEED_SIZE random bytes produced and those data once returned to the caller are cleared from the internal state, which ensures forward secrecy. This CPRNG is fast, based on a stream cipher, and will never block besides the initial seed or any reseed if it depends on the system entropy. Finally, it can be used either globally (locked in multithread environment), per-thread (a lock free instance is automatically created for each thread on first use), or created as standalone instance (manageable independently). For now it's only implemented with the OpenSSL library as underlying crypto, that is --with-crypto --with-openssl needs to be configured, and the latter links libcrypto with APR. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1833359 13f79535-47bb-0310-9956-ffa450edef68
* Use 'apr_pstrmemdup' instead of 'apr_pstrndup' when applicable in order to ↵Christophe Jaillet2015-10-241-3/+3
| | | | | | save a few cycles. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1710307 13f79535-47bb-0310-9956-ffa450edef68
* Fixed indent - no code change.Guenter Knauf2014-07-161-12/+11
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1611050 13f79535-47bb-0310-9956-ffa450edef68
* Fixed type; fixed comments.Guenter Knauf2014-07-161-4/+4
| | | | git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1611046 13f79535-47bb-0310-9956-ffa450edef68