Index: PC/pyconfig.h =================================================================== --- PC/pyconfig.h (revision 68445) +++ PC/pyconfig.h (working copy) @@ -82,7 +82,11 @@ #ifndef PYTHONPATH # define PYTHONPATH ".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk" #endif -#define NT_THREADS +#ifdef MS_WINCE +# define WINCE_THREADS +#else +# define NT_THREADS +#endif #define WITH_THREAD #ifndef NETSCAPE_PI #define USE_SOCKET Index: Python/thread_wince.h =================================================================== --- Python/thread_wince.h (revision 68445) +++ Python/thread_wince.h (working copy) @@ -8,42 +8,72 @@ long PyThread_get_thread_ident(void); /* - * Change all headers to pure ANSI as no one will use K&R style on an - * NT + * Initialization hook for the threads module, not needed by the CE variant. */ - -/* - * Initialization of the C package, should not be needed. - */ static void PyThread__init_thread(void) { } +/* The interface expected by CreateThread doesn't match the one expected by +the Python interface, so we use a proxy function to adapt between the two. */ +struct thread_context +{ + void (*func)(void*); + void* arg; +}; + +static DWORD WINAPI thread_entry(PVOID p) +{ + /* copy context information and free allocated structure. */ + struct thread_context* c = p; + void (*func)(void *) = c->func; + void *arg = c->arg; + free(p); + /* call real startup function */ + (*func)(arg); + free(p); + + return 0; +} + /* * Thread support. */ long PyThread_start_new_thread(void (*func)(void *), void *arg) { - long rv; - int success = -1; + DWORD thread_id; + HANDLE thread; + struct thread_context* context; - dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident())); - if (!initialized) - PyThread_init_thread(); + dprintf(("%ld: PyThread_start_new_thread called\n", PyThread_get_thread_ident())); + if (!initialized) + PyThread_init_thread(); - rv = _beginthread(func, 0, arg); /* use default stack size */ - - if (rv != -1) { - success = 0; - dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident())); - } + /* allocate and fill thread context */ + context = malloc(sizeof(struct thread_context)); + if(!context) + return -1; + context->func = func; + context->arg = arg; - return success; + /* start thread */ + thread = CreateThread( NULL, 0, thread_entry, context, 0, &thread_id); + if(thread==NULL) { + /* TODO: PyErr_Set ... from GetLastError()? */ + free(context); + return -1; + } + dprintf(("%ld: PyThread_start_new_thread succeeded:\n", PyThread_get_thread_ident())); + /* Release the thread object, we don't need it to e.g. retrieve the + exit code. */ + CloseHandle(thread); + + return thread_id; } /* - * Return the thread Id instead of an handle. The Id is said to uniquely identify the - * thread in the system + * Return the ID instead of the current thread. The ID is said to uniquely + * identify the thread in the system */ long PyThread_get_thread_ident(void) { @@ -53,6 +83,9 @@ return GetCurrentThreadId(); } +/* TODO: What exactly is the meaning of the 'no_cleanup' parameter? Also, +is this function allowed/supposed to never return? Further, why does this +check the 'initialized' flag? */ static void do_PyThread_exit_thread(int no_cleanup) { dprintf(("%ld: do_PyThread_exit_thread called\n", PyThread_get_thread_ident())); @@ -61,7 +94,7 @@ exit(0); /* XXX - was _exit()!! */ else exit(0); - _endthread(); + ExitThread(-1); } void PyThread_exit_thread(void)