Embedded python: how to force a break to endless looping Pyt hon script?

Stefan Migowsky smigowsky at dspace.de
Wed Aug 23 03:53:15 EDT 2000


-----Ursprüngliche Nachricht-----
>"David Bolen" <db3l at fitlinxx.com> wrote:
> >"Warren Postma" <embed at NOSPAM.geocities.com> writes:
> > Has anyone done anything like this?

For windows system I made a patch version of the python 1.5.2 dll
which allows me to send a KeyboardInterrupt Exception to all
threads running inside the embedded Interpreter. This gives
all python code a chance to handle this properly by handling the exception.
 
It is based on the fact that a one thread is running the embedded 
interpreter and one other thread is just waiting for user 
input to shutdown the threads. So this thread will always be 
alive even if the main thread go mad.

This patch only works in windows environment since I don't know 
enough about threading in other environments. 
Improvements could be stopping specific threads and not all and
the code which suits all environments.

  Stefan

here is the patch :

*****************************************
ceval.c: 

line 54:
++ // code changed by smi on 09.06.00
++ #ifdef WITH_THREAD
++ extern unsigned int GetShutDownValue();
++ extern unsigned int GetStopAllThreads();
++ #endif
++ // end of code changed by smi on 09.06.00

line 276:
   int
   Py_MakePendingCalls()
   {
   	static int busy = 0;
   #ifdef WITH_THREAD
   	if (main_thread && PyThread_get_thread_ident() != main_thread)
++ // code changed by smi on 09.06.00
++     {
++         if(GetStopAllThreads() && GetShutDownValue())
++         {
++             PyErr_SetNone(PyExc_KeyboardInterrupt);
++             things_to_do = 1;
++            	return -1;
++         }
++         return 0;
++     }
++ //            return 0;        
++ // end of code changed by smi on 09.06.00
   #endif

*****************************************
thread_nt.h:
line 38:
   long PyThread_get_thread_ident(void);
   
   /*
    * Change all headers to pure ANSI as no one will use K&R style on an
    * NT
    */
++ // code changed by smi on 18.08.99
++ 
++ static volatile unsigned int guiThreadCount = 0;
++ static volatile unsigned int guiStopAllThreads = 0;
++ static unsigned int          guiTlsInShutDown = 0;
++ 
++ void SetStopAllThreads(void);
++ unsigned int GetStopAllThreads(void);
++ unsigned int GetShutDownValue(void);
++ BOOL AllocateProcessTls(void);
++ void DeAllocateProcessTls(void);
++ void AllocateThreadTls(void);
++ void DeAllocateThreadTls(void);
++ 
++ BOOL AllocateProcessTls(void)
++ {
++     guiTlsInShutDown = TlsAlloc();
++     if (0xFFFFFFFF == guiTlsInShutDown)
++           return FALSE;
++     return TRUE;
++ }
++ 
++ void DeAllocateProcessTls(void)
++ {
++    TlsFree(guiTlsInShutDown);
++ }
++ 
++ void AllocateThreadTls(void)
++ {
++    // Create the per thread storage shutdown structure
++    unsigned int *puiData;
++    puiData = (unsigned int *)LocalAlloc(LPTR, sizeof(unsigned int));
++    if (NULL != puiData)
++    {
++        *puiData = 0;
++        TlsSetValue(guiTlsInShutDown, puiData);
++    }
++ }
++  
++ void DeAllocateThreadTls(void)
++ {
++     // Release the per thread storage
++     unsigned int *puiData;
++     puiData = (unsigned int *)TlsGetValue(guiTlsInShutDown);
++     if (NULL != puiData)
++     {
++          LocalFree((HLOCAL)puiData);
++     }
++ }
++ 
++ void SetStopAllThreads(void)
++ {
++     _asm 
++     {
++         cmp guiThreadCount, 0
++         jne JNE_NotNull
++         mov guiStopAllThreads, 0
++ JNE_NotNull:
++         mov guiStopAllThreads, 1
++     }
++ }
++ 
++ unsigned int GetStopAllThreads(void)
++ {
++     return guiStopAllThreads;
++ }
++ 
++ unsigned int GetShutDownValue(void)
++ {
++     unsigned int *puiShutDownValue;
++     puiShutDownValue = (unsigned int
*)TlsGetValue((DWORD)guiTlsInShutDown);
++     if(1 == guiStopAllThreads && NULL != puiShutDownValue && 0 ==
*puiShutDownValue)
++     {
++         *puiShutDownValue = 1;
++         return 1;
++     }
++     return 0;
++ }
++ // end of code changed by smi on 18.08.99

line 148:
		dprintf(("%ld: PyThread_start_new_thread succeeded: %ld\n",
PyThread_get_thread_ident(), aThreadId));
++ // code changed by smi on 09.06.00
++         _asm inc guiThreadCount;
++ // end of code changed by smi on 09.06.00

line 168:
   static void do_PyThread_exit_thread(int no_cleanup)
   {
++ // code changed by smi on 18.08.99
++     _asm 
++     {
++         dec guiThreadCount
++         cmp guiThreadCount, 0
++         jne JNE_NotNull
++         mov guiStopAllThreads, 0
++ JNE_NotNull:        
++     }
++ // end of code changed by smi on 18.08.99

*****************************************************************
dl_nt.c:

line 14:
   #include "Python.h"

++ // code changed by smi on 09.06.00
++ extern BOOL AllocateProcessTls(void);
++ extern void DeAllocateProcessTls(void);
++ extern void AllocateThreadTls(void);
++ extern void DeAllocateThreadTls(void);
++ // end of code changed by smi on 09.06.00

line 40:
   			//initall();
++ // code changed by smi on 09.06.00
++             AllocateProcessTls();
++ // end of code changed by smi on 09.06.00
			break;
		case DLL_PROCESS_DETACH:
++ // code changed by smi on 09.06.00
++             DeAllocateProcessTls();
++ // end of code changed by smi on 09.06.00
    		break;
++ // code changed by smi on 09.06.00
++         case DLL_THREAD_ATTACH:
++             AllocateThreadTls();
++             break;
++         case DLL_THREAD_DETACH:
++             DeAllocateThreadTls();
++             break;
++ // end of code changed by smi on 09.06.00
   	}
   	return TRUE;

*********************************************************
signalmodule.c : 

line 98:
   static pid_t main_pid;
   #endif

++ // code changed by smi on 09.06.00
++ extern void SetStopAllThreads(void);
++ // end of code changed by smi on 09.06.00

line 658:
   PyErr_SetInterrupt()
   {
++ // code changed by smi on 09.06.00
++     SetStopAllThreads();
++ // end of code changed by smi on 09.06.00







More information about the Python-list mailing list