@@ -77,7 +77,9 @@ static int file_exists(const char *filename) {
7777 return 0 ;
7878}
7979
80- static int run_python (int argc , char * argv [], bool call_exit ) {
80+ static int gil_init = 0 ; /* 1 when Python has been initialied/GIL created */
81+
82+ static int run_python (int argc , char * argv [], bool call_exit , char * argument_name , char * argument_value ) {
8183
8284 char * env_argument = NULL ;
8385 char * env_entrypoint = NULL ;
@@ -194,17 +196,26 @@ static int run_python(int argc, char *argv[], bool call_exit) {
194196 " recipes should have this folder, should we expect a crash soon?" );
195197 }
196198
197- Py_Initialize ();
198- LOGP ("Initialized python" );
199+ if (!gil_init ) {
200+ gil_init = 1 ;
201+ Py_Initialize ();
202+ LOGP ("Initialized python" );
203+ /* ensure threads will work.
204+ */
205+ LOGP ("Calling init threads (unneeded for Python 3.7+)" );
206+ PyEval_InitThreads ();
207+ PyEval_SaveThread ();
208+ } else {
209+ LOGP ("Python already initialized in this process" );
210+ }
199211
200212 /* Ensure that we are registering this thread against the GIL */
201213 PyGILState_STATE gstate ;
214+ LOGP ("Attempting to register against the Global Interpreter Lock" );
215+
202216 gstate = PyGILState_Ensure ();
203217
204- /* ensure threads will work.
205- */
206- LOGP ("AND: Init threads" );
207- PyEval_InitThreads ();
218+ LOGP ("Registered against the Global Interpreter Lock" );
208219
209220#if PY_MAJOR_VERSION < 3
210221 initandroidembed ();
@@ -314,6 +325,30 @@ static int run_python(int argc, char *argv[], bool call_exit) {
314325 return -1 ;
315326 }
316327
328+ if (argument_name != NULL && argument_value != NULL ) {
329+ LOGP ("Setting argument name and value in __main__ namespace" );
330+ // Calculate the size of the string
331+ int size = snprintf (NULL , 0 , "%s = '%s'" , argument_name , argument_value );
332+
333+ // Allocate enough memory (plus one for the null terminator)
334+ char * command = malloc (size + 1 );
335+ if (command == NULL ) {
336+ LOGP ("Memory allocation failed\n" );
337+ exit (EXIT_FAILURE );
338+ }
339+
340+ // Now format the string
341+ snprintf (command , size + 1 , "%s = '%s'" , argument_name , argument_value );
342+
343+ // Running the command in the __main__ module context
344+ PyRun_SimpleString (command );
345+
346+ // Free the memory
347+ free (command );
348+ } else {
349+ LOGP ("No argument name and value provided" );
350+ }
351+
317352 /* run python !
318353 */
319354 ret = PyRun_SimpleFile (fd , entrypoint );
@@ -347,7 +382,9 @@ static int run_python(int argc, char *argv[], bool call_exit) {
347382 }
348383
349384 /* Release the thread. No Python API allowed beyond this point. */
385+ LOGP ("Attempting to release Global Interpreter Lock" );
350386 PyGILState_Release (gstate );
387+ LOGP ("Released Global Interpreter Lock" );
351388
352389 /* This should never actually be reached with call_exit.
353390 */
@@ -373,6 +410,8 @@ static int native_service_start(
373410 jstring j_python_name ,
374411 jstring j_python_home ,
375412 jstring j_python_path ,
413+ char * argument_name ,
414+ char * argument_value ,
376415 bool call_exit ) {
377416 jboolean iscopy ;
378417 const char * android_private =
@@ -402,7 +441,7 @@ static int native_service_start(
402441 /* ANDROID_ARGUMENT points to service subdir,
403442 * so run_python() will run main.py from this dir
404443 */
405- return run_python (1 , argv , call_exit );
444+ return run_python (1 , argv , call_exit , argument_name , argument_value );
406445}
407446
408447JNIEXPORT int JNICALL Java_org_kivy_android_PythonService_nativeStart (
@@ -427,6 +466,8 @@ JNIEXPORT int JNICALL Java_org_kivy_android_PythonService_nativeStart(
427466 j_python_name ,
428467 j_python_home ,
429468 j_python_path ,
469+ "PYTHON_SERVICE_ARGUMENT" ,
470+ arg ,
430471 true);
431472}
432473
@@ -452,6 +493,8 @@ JNIEXPORT int JNICALL Java_org_kivy_android_PythonWorker_nativeStart(
452493 j_python_name ,
453494 j_python_home ,
454495 j_python_path ,
496+ "PYTHON_WORKER_ARGUMENT" ,
497+ arg ,
455498 false);
456499}
457500
@@ -495,7 +538,7 @@ int Java_org_kivy_android_PythonActivity_nativeInit(JNIEnv* env, jclass cls, job
495538 argv [1 ] = NULL ;
496539 /* status = SDL_main(1, argv); */
497540
498- return run_python (1 , argv , true);
541+ return run_python (1 , argv , true, NULL , NULL );
499542
500543 /* Do not issue an exit or the whole application will terminate instead of just the SDL thread */
501544 /* exit(status); */
0 commit comments