a „oeRã@sÄdZddlZddlZddlZddlZddlZddlZdd„Zdd„Z dd„Z d d „Z d d „Z d d„Z edkrÀe e ƒe d¡e ¡e ¡dksže ¡dkr¸ede ¡e ¡fƒnedƒdS)a™Testing pasing object between multiple COM threads Uses standard COM marshalling to pass objects between threads. Even though Python generally seems to work when you just pass COM objects between threads, it shouldnt. This shows the "correct" way to do it. It shows that although we create new threads to use the Python.Interpreter, COM marshalls back all calls to that object to the main Python thread, which must be running a message loop (as this sample does). When this test is run in "free threaded" mode (at this stage, you must manually mark the COM objects as "ThreadingModel=Free", or run from a service which has marked itself as free-threaded), then no marshalling is done, and the Python.Interpreter object start doing the "expected" thing - ie, it reports being on the same thread as its caller! Python.exe needs a good way to mark itself as FreeThreaded - at the moment this is a pain in the but! éNc Csv| d¡dkrtdƒ‚z| d¡tdƒ‚WnDtjyp}z*ddl}|d|jkr\tdƒ‚WYd}~n d}~00dS)Nz1+1éz*The interpreter returned the wrong result.z*The interpreter did not raise an exceptionrz?The interpreter exception was not winerror.DISP_E_TYPEMISMATCH.)ÚEvalÚ ValueErrorÚ pythoncomZ com_errorÚwinerrorZDISP_E_TYPEMISMATCH)ÚinterpZdetailsr©rú6C:\Program Files\Certbot\pkgs\win32com\test\testGIT.pyÚ TestInterp!s  ÿr c Cs(zt|ƒWt |¡n t |¡0dS©N)ÚDoTestInterpInThreadÚ win32eventZSetEvent)Z stopEventÚcookierrr ÚTestInterpInThread0s rcCst tjdtjtj¡Sr )rZCoCreateInstanceZCLSID_StdGlobalInterfaceTableZ CLSCTX_INPROCZIID_IGlobalInterfaceTablerrrr Ú CreateGIT7s ürcCs‚zht ¡t ¡}tƒ}| |tj¡}tj  |¡}t |ƒ|  d¡t d||  d¡fƒd}t ¡Wnt ¡Yn0dS)Nzimport win32apiz>The test thread id is %d, Python.Interpreter's thread ID is %dzwin32api.GetCurrentThreadId())rZ CoInitializeÚwin32apiÚGetCurrentThreadIdrZGetInterfaceFromGlobalÚ IID_IDispatchÚwin32comÚclientÚDispatchr ZExecÚprintrÚCoUninitializeÚ tracebackÚ print_exc)rZmyThreadÚGITrrrr r @s"   ÿÿ r cCs@g}t|ƒD].}t dddd¡}t t||f¡| |¡q |S)zÉCreates multiple threads using simple (but slower) marshalling. Single interpreter object, but a new stream is created per thread. Returns the handles the threads will set when complete. Nr)Úranger Z CreateEventÚ_threadÚ start_newrÚappend)Z numThreadsrÚretÚiZhEventrrr ÚBeginThreadsSimpleMarshalUs   r"cCsìtdt ¡ƒtƒ}tj d¡}| |jt j ¡}|d|ƒ}d}z€t   |ddt j ¡}|t jkrŠ|t jt|ƒkrŠ|d}|t|ƒkr¾WqÚn4|t jt|ƒkr¦t  ¡ntdt  ¡t  ¡fƒWq@tyÖYqÚYq@0q@| |¡~~dS)NzThe main thread is %dzPython.InterpreterériÐéz:Waiting for thread to stop with interfaces=%d, gateways=%d)rrrrrrrZRegisterInterfaceInGlobalZ_oleobj_rrr ZMsgWaitForMultipleObjectsZ QS_ALLINPUTZ WAIT_OBJECT_0ÚlenZPumpWaitingMessagesÚ_GetInterfaceCountÚ_GetGatewayCountÚKeyboardInterruptZRevokeInterfaceFromGlobal)ÚfnrrrZeventsZ numFinishedÚrcrrr Útestds8   ÿÿ  ÿÿ   r+Ú__main__iôz$Done with interfaces=%d, gateways=%dzDone.)Ú__doc__rrrrZwin32com.clientrr r rrr r"r+Ú__name__ZSleeprr&r'rrrrr Ús. " ÿÿ