@@ -366,6 +366,65 @@ _Py_EnterRecursiveCallUnchecked(PyThreadState *tstate)
366
366
# define Py_C_STACK_SIZE 4000000
367
367
#endif
368
368
369
+ #if defined(__EMSCRIPTEN__ )
370
+
371
+ // Temporary workaround to make `pthread_getattr_np` work on Emscripten.
372
+ // Emscripten 4.0.6 will contain a fix:
373
+ // https://github.com/emscripten-core/emscripten/pull/23887
374
+
375
+ #include "emscripten/stack.h"
376
+
377
+ #define pthread_attr_t workaround_pthread_attr_t
378
+ #define pthread_getattr_np workaround_pthread_getattr_np
379
+ #define pthread_attr_getguardsize workaround_pthread_attr_getguardsize
380
+ #define pthread_attr_getstack workaround_pthread_attr_getstack
381
+ #define pthread_attr_destroy workaround_pthread_attr_destroy
382
+
383
+ typedef struct {
384
+ void * _a_stackaddr ;
385
+ size_t _a_stacksize , _a_guardsize ;
386
+ } pthread_attr_t ;
387
+
388
+ extern __attribute__((__visibility__ ("hidden" ))) unsigned __default_guardsize ;
389
+
390
+ // Modified version of pthread_getattr_np from the upstream PR.
391
+
392
+ int pthread_getattr_np (pthread_t thread , pthread_attr_t * attr ) {
393
+ attr -> _a_stackaddr = (void * )emscripten_stack_get_base ();
394
+ attr -> _a_stacksize = emscripten_stack_get_base () - emscripten_stack_get_end ();
395
+ attr -> _a_guardsize = __default_guardsize ;
396
+ return 0 ;
397
+ }
398
+
399
+ // These three functions copied without any changes from Emscripten libc.
400
+
401
+ int pthread_attr_getguardsize (const pthread_attr_t * restrict a , size_t * restrict size )
402
+ {
403
+ * size = a -> _a_guardsize ;
404
+ return 0 ;
405
+ }
406
+
407
+ int pthread_attr_getstack (const pthread_attr_t * restrict a , void * * restrict addr , size_t * restrict size )
408
+ {
409
+ /// XXX musl is not standard-conforming? It should not report EINVAL if _a_stackaddr is zero, and it should
410
+ /// report EINVAL if a is null: http://pubs.opengroup.org/onlinepubs/009695399/functions/pthread_attr_getstack.html
411
+ if (!a ) return EINVAL ;
412
+ // if (!a->_a_stackaddr)
413
+ // return EINVAL;
414
+
415
+ * size = a -> _a_stacksize ;
416
+ * addr = (void * )(a -> _a_stackaddr - * size );
417
+ return 0 ;
418
+ }
419
+
420
+ int pthread_attr_destroy (pthread_attr_t * a )
421
+ {
422
+ return 0 ;
423
+ }
424
+
425
+ #endif
426
+
427
+
369
428
void
370
429
_Py_InitializeRecursionLimits (PyThreadState * tstate )
371
430
{
0 commit comments