§
    ¥	Êj  ã                   ó8  — d Z ddlZddlZddlZddlZddlZ eej                             dd¦  «        ¦  «        Z	 e
ej                             dd¦  «        ¦  «        Zd„ Z G d„ d	¦  «        Zd
„ Zd„ Zd„ Zedk    r e¦   «           ej        d¦  «         dS dS )aT  Reproducer for the free-threaded GC crash in issue #515.

https://github.com/python-greenlet/greenlet/issues/515

Before the fix, ``set_initial_state`` copied the parent thread state's
``_PyCStackRef`` list head into each new greenlet. Those nodes sit on the
parent greenlet's C stack, so once the child starts running on its own stack
and overwrites that region their ``next`` pointers dangle. The free-threaded
collector walks ``c_stack_refs`` for every thread, so a GC on any thread ends
up chasing those dangling nodes (inside ``gc_collect_main`` ->
``gc_visit_thread_stacks``) while such a child is active, and segfaults.

The fiddly part is getting a *non-empty* list to inherit at all. The
interpreter only holds a ``_PyCStackRef`` transiently, while it is resolving an
attribute -- ``_Py_LoadAttr_StackRefSteal`` pins ``self`` across ``obj.attr()``
-- so the greenlet has to be primed from inside that window. Priming it from a
property getter does exactly that; it is also the same deep-attribute context
Playwright's sync bridge happens to start its fiber from. A churn thread then
keeps the collector busy while the dispatcher runs on its stale list.

A fixed build prints "ISSUE 515 OK"; a regressed one segfaults in about a
second. With-GIL builds are unaffected -- ordinary refcounting keeps the nodes
alive -- so there it simply prints the OK line.
é    NÚREPRO_SECONDSÚ4ÚREPRO_THREADSÚ6c                  ó–   — d                      ¦   «                              ¦   «                              ¦   «                              ¦   «         S )NÚabc)ÚupperÚlowerÚstripÚtitle© ó    ú[C:\Projects\Muse2API\.venv\Lib\site-packages\greenlet/tests/fail_issue_515_freethread_gc.pyÚ_busyr   &   s6   € ð �;Š;‰=Œ=×ÒÑ Ô ×&Ò&Ñ(Ô(×.Ò.Ñ0Ô0Ð0r   c                   ó<   — e Zd Zd„ Zd„ Zed„ ¦   «         Zd„ Zd„ ZdS )ÚBridgec                 ó€   — || _         t          j        ¦   «         | _        t          j        | j        ¦  «        | _        d S ©N)ÚstopÚgreenletÚ
getcurrentÚmainÚ_loopÚdisp)Úselfr   s     r   Ú__init__zBridge.__init__-   s1   € ØˆŒ	ÝÔ'Ñ)Ô)ˆŒ	ÝÔ% d¤jÑ1Ô1ˆŒ	ˆ	ˆ	r   c                 ó°   — | j         d         sHt          d¦  «        D ]}t          ¦   «          Œ| j                             ¦   «          | j         d         ¯Fd S d S )Nr   é2   )r   Úranger   r   Úswitch)r   Ú_s     r   r   zBridge._loop2   sh   € Ø”)˜A”,ð 	Ý˜2‘Y”Yð ð �Ý‘”��ØŒI×ÒÑÔÐð ”)˜A”,ð 	ð 	ð 	ð 	ð 	r   c                 ó8   — | j                              ¦   «          d S r   ©r   r    ©r   s    r   Ú_primezBridge._prime8   s   € ð
 	Œ	×ÒÑÔÐØˆtr   c                 ó   — | j         S r   )r%   r$   s    r   ÚstartzBridge.start@   s   € ð
 Œ{Ðr   c                 ó8   — | j                              ¦   «          d S r   r#   r$   s    r   ÚresumezBridge.resumeG   s   € ØŒ	×ÒÑÔÐÐÐr   N)	Ú__name__Ú
__module__Ú__qualname__r   r   Úpropertyr%   r'   r)   r   r   r   r   r   ,   sk   € € € € € ð2ð 2ð 2ð
ð ð ð ðð ñ „Xððð ð ðð ð ð ð r   r   c                 ó˜   — t          | ¦  «        }|                     ¦   «          | d         s|                     ¦   «          | d         ¯d S d S )Nr   )r   r'   r)   )r   Úbridges     r   Úworkerr0   K   sW   € Ý�D‰\Œ\€FØ
‡L‚L�N„N€Nð �1Œgð Ø�Š‰Œˆð �1Œgð ð ð ð ð r   c                 óì   — | d         skd„ t          d¦  «        D ¦   «         }t          ||dd …         ¦  «        D ]
\  }}||d<   Œ|d         |d         d<   ~t          j        ¦   «          | d         ¯id S d S )Nr   c                 ó   — g | ]}|d dœ‘ŒS )N)ÚiÚnextr   )Ú.0r3   s     r   ú
<listcomp>zchurn.<locals>.<listcomp>X   s    € Ð<Ð<Ð<¨A�q $Ð'Ð'Ð<Ð<Ð<r   iô  é   r4   éÿÿÿÿ)r   ÚzipÚgcÚcollect)r   ÚnodesÚaÚbs       r   Úchurnr?   T   s›   € Ø�1Œgð ð =Ð<µ°s±´Ð<Ñ<Ô<ˆÝ˜˜u Q R RœyÑ)Ô)ð 	ð 	‰DˆAˆqØˆAˆf‰IˆIØ! !œHˆˆbŒ	�&ÑØÝ
Œ
‰Œˆð �1Œgð ð ð ð ð r   c                  óv  ‡— dgŠt          j        t          ‰fd¬¦  «        g} | ˆfd„t          t          ¦  «        D ¦   «         z  } | D ]}|                     ¦   «          Œt          j        ¦   «                              t          ¦  «         d‰d<   | D ]}| 	                    d¬¦  «         Œt          d¦  «         d S )	NFT©ÚtargetÚargsÚdaemonc                 óJ   •— g | ]}t          j        t          ‰fd ¬¦  «        ‘Œ S )TrA   )Ú	threadingÚThreadr0   )r5   r!   r   s     €r   r6   zmain.<locals>.<listcomp>c   s=   ø€ ð *ð *ð *Øõ Ô ­°d°WÀTÐJÑJÔJð *ð *ð *r   r   é   )ÚtimeoutzISSUE 515 OK)rF   rG   r?   r   ÚNWORKERSr'   ÚEventÚwaitÚDURATIONÚjoinÚprint)ÚthreadsÚtr   s     @r   r   r   `   sÙ   ø€ Øˆ7€DÝÔ¥u°D°7À4ÐHÑHÔHÐI€GØð *ð *ð *ð *Ý�x™œð*ñ *ô *ñ *€Gàð ð ˆØ	�Š‰	Œ	ˆ	ˆ	Ý„OÑÔ×Ò�8Ñ$Ô$Ð$Ø€Dˆ�GØð ð ˆØ	�Š�qˆÑÔÐÐÝ	ˆ.ÑÔÐÐÐr   Ú__main__)Ú__doc__r:   ÚosÚsysrF   r   ÚfloatÚenvironÚgetrM   ÚintrJ   r   r   r0   r?   r   r*   Úexitr   r   r   ú<module>r[      s  ððð ð0 
€	€	€	Ø 	€	€	€	Ø 
€
€
€
Ø Ð Ð Ð à €€€ð ˆ5�”—’ °Ñ5Ô5Ñ6Ô6€Øˆ3ˆrŒz�~Š~˜o¨sÑ3Ô3Ñ4Ô4€ð1ð 1ð 1ðð ð ð ð ñ ô ð ð>ð ð ð	ð 	ð 	ðð ð ð ˆzÒÐØ€D�F„F€FØ€C„HˆQ�K„K€K€K€Kð Ðr   