idZddlZddlZddlZddlZddlZddlZddlm Z dZ Gdde Z e dkrej ddSdS) aTesting 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 shouldn't. 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! N) InterpCasec:eZdZdZdZdZdZd dZdZdZ d S) ThreadInterpCasec ||tj|dS#tj|wxYwN)_doTestInThread win32eventSetEvent)self stopEventinterps GC:\PYTHON\_runtimes\venv\Lib\site-packages\win32com/test/testMarshal.py_testInterpInThreadz$ThreadInterpCase._testInterpInThread&sI +   ( ( (   * * * * *J  * * * *s -Ac,tjtj}tr>tj|tj}tj |}| dtj dS)Nzimport win32api) pythoncom CoInitializewin32apiGetCurrentThreadId freeThreadedCoGetInterfaceAndReleaseStream IID_IDispatchwin32comclientDispatchExecCoUninitialize)r rmyThreads rr z ThreadInterpCase._doTestInThread,s   .00  6= /F_--f55F %&&& """""ctjd}g}g}t|D]}t jdddd}||tjtj |j }tj |j ||fd}|||d}||fS)zCreates 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. Python.InterpreterNrTtargetargsdaemon)rrrranger CreateEventappendr%CoMarshalInterThreadInterfaceInStreamr_oleobj_ threadingThreadrstart) r numThreadsreventsthreadsihEvent interpStreamts rBeginThreadsSimpleMarshalz*ThreadInterpCase.BeginThreadsSimpleMarshal:s))*>??z""  A+D!Q==F MM& ! ! !$J'L /l+A GGIII NN1    rctjd}tr$t jtj|j}g}g}t|D]u}tj dddd}tj |j ||fd}|||||v||fS)zCreates multiple threads using fast (but complex) marshalling. The marshal stream is created once, and each thread uses the same stream Returns the handles the threads will set when complete. r!NrTr")rrrrrr)rr*r&r r'r+r,rr-r()r r.rr/r0r1r2r4s rBeginThreadsFastMarshalz(ThreadInterpCase.BeginThreadsFastMarshalXs))*>??  D'Fz""  A+D!Q==F /f%A GGIII MM& ! ! ! NN1    rrc|d\}}d} |rtjdd|}n!tj|ddtj}|tjkr:|tjt |zkr|dz }|t |krn~nj|tjt |zkrtjn6tdtj tj fzn#t$rYnwxYw|D]?}| d| |d@d}dS)Nrriz:Waiting for thread to stop with interfaces=%d, gateways=%dzthread failed to stop!?)rCoWaitForMultipleHandlesr MsgWaitForMultipleObjects QS_ALLINPUT WAIT_OBJECT_0lenPumpWaitingMessagesprint_GetInterfaceCount_GetGatewayCountKeyboardInterruptjoin assertFalseis_alive)r fnbCoWaitr0r/ numFinishedrcr4s r_DoTestMarshalzThreadInterpCase._DoTestMarshalrs"Q%%   ";AtVLLBB$=4)?B*222Z5F CCC1$K"c&kk112:3c&kkAAA13333T$7999;U;W;WXY%    3 6 F FA FF1III   QZZ\\+D E E E EsBDA+D DDc:||jdSrrKr5r s rtestSimpleMarshalz"ThreadInterpCase.testSimpleMarshals D:;;;;;rc<||jddS)NrrMrNs rtestSimpleMarshalCoWaitz(ThreadInterpCase.testSimpleMarshalCoWaits! D:A>>>>>rN)r) __name__ __module__ __qualname__rr r5r7rKrOrQrrrr%s+++ # # #<4""""N<<<?????rr__main__ testMarshal)__doc__r+unittestrrwin32com.clientrr testServersrrrrRmainrUrrr]s.###### x?x?x?x?x?zx?x?x?| zHM-     r