Skip to content

Commit 3575cac

Browse files
Michiel Jan Laurens de HoonMichiel Jan Laurens de Hoon
authored andcommitted
Check if Tcl is threaded when creating a tkapp
1 parent 8fb5271 commit 3575cac

1 file changed

Lines changed: 21 additions & 30 deletions

File tree

‎Modules/_tkinter.c‎

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Copyright (C) 1994 Steen Lumholt.
4343
/* As we require that Tcl is compiled for threads, we must also define
4444
TCL_THREADS. We define it always; if Tcl is not threaded, the thread
4545
functions in Tcl are empty. We check if Tcl is actually compiled for
46-
threads when importing this module. */
46+
threads when creating a tkapp. */
4747
#define TCL_THREADS
4848

4949
#ifdef TK_FRAMEWORK
@@ -225,23 +225,6 @@ _get_tcl_lib_path(void)
225225
226226
*/
227227

228-
#if TCL_MAJOR_VERSION < 9 /* Tcl 9.x is always threaded */
229-
static int
230-
_check_tcl_threaded(void)
231-
{
232-
Tcl_Interp* interp;
233-
Tcl_Obj* threaded;
234-
interp = Tcl_CreateInterp();
235-
threaded = Tcl_GetVar2Ex(interp,
236-
"tcl_platform",
237-
"threaded",
238-
TCL_GLOBAL_ONLY);
239-
Tcl_DeleteInterp(interp);
240-
if (threaded == NULL) return 0;
241-
else return 1;
242-
}
243-
#endif
244-
245228
static Tcl_ThreadDataKey state_key;
246229
typedef PyThreadState *ThreadSpecificData;
247230
#define tcl_tstate \
@@ -567,12 +550,29 @@ Tkapp_New(const char *screenName, const char *className,
567550
{
568551
TkappObject *v;
569552
char *argv0;
553+
#if TCL_MAJOR_VERSION < 9 /* Tcl 9.x is always threaded */
554+
static Tcl_Obj* threaded = NULL;
555+
#endif
570556

571557
v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type);
572558
if (v == NULL)
573559
return NULL;
574560

575561
v->interp = Tcl_CreateInterp();
562+
#if TCL_MAJOR_VERSION < 9 /* Tcl 9.x is always threaded */
563+
if (threaded == NULL) {
564+
threaded = Tcl_GetVar2Ex(v->interp,
565+
"tcl_platform",
566+
"threaded",
567+
TCL_GLOBAL_ONLY);
568+
if (threaded == NULL) {
569+
PyErr_SetString(PyExc_RuntimeError,
570+
"Tcl must be compiled with thread support");
571+
Py_DECREF(v);
572+
return NULL;
573+
}
574+
}
575+
#endif
576576
v->wantobjects = wantobjects;
577577
v->thread_id = Tcl_GetCurrentThread();
578578
v->dispatching = 0;
@@ -1426,10 +1426,9 @@ Tkapp_CallProc(Tcl_Event *evPtr, int flags)
14261426

14271427
/* This is the main entry point for calling a Tcl command.
14281428
It supports two cases, with regard to threading:
1429-
2. Caller of the command is in the interpreter thread:
1430-
Execute the command in the calling thread. Since the Tcl lock will
1431-
not be used, we can merge that with case 1.
1432-
3. Caller is in a different thread: Must queue an event to
1429+
1. Caller of the command is in the interpreter thread:
1430+
Execute the command in the calling thread.
1431+
2. Caller is in a different thread: Must queue an event to
14331432
the interpreter thread. Allocation of Tcl objects needs to occur in the
14341433
interpreter thread, so we ship the PyObject* args to the target thread,
14351434
and perform processing there. */
@@ -3416,14 +3415,6 @@ PyInit__tkinter(void)
34163415
{
34173416
PyObject *m, *uexe, *cexe;
34183417

3419-
#if TCL_MAJOR_VERSION < 9 /* Tcl 9.x is always threaded */
3420-
if (_check_tcl_threaded() == 0) {
3421-
PyErr_SetString(PyExc_ImportError,
3422-
"Tcl must be compiled with thread support");
3423-
return 0;
3424-
}
3425-
#endif
3426-
34273418
m = PyModule_Create(&_tkintermodule);
34283419
if (m == NULL)
34293420
return NULL;

0 commit comments

Comments
 (0)