Browse code

app_python: declare global vars extern in header file

Daniel-Constantin Mierla authored on 09/03/2020 07:27:15
Showing 1 changed files
... ...
@@ -54,6 +54,8 @@ static void mod_destroy(void);
54 54
 
55 55
 PyObject *_sr_apy_handler_obj = NULL;
56 56
 
57
+PyObject *format_exc_obj = NULL;
58
+
57 59
 char *dname = NULL, *bname = NULL;
58 60
 
59 61
 int _apy_process_rank = 0;
Browse code

app_python: exported exec function to KEMI also as execx

Daniel-Constantin Mierla authored on 25/02/2019 08:19:34
Showing 1 changed files
... ...
@@ -542,6 +542,11 @@ static sr_kemi_t sr_kemi_app_python_exports[] = {
542 542
 		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
543 543
 			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
544 544
 	},
545
+	{ str_init("app_python"), str_init("execx"),
546
+		SR_KEMIP_INT, ki_app_python_exec,
547
+		{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
548
+			SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
549
+	},
545 550
 	{ str_init("app_python"), str_init("exec_p1"),
546 551
 		SR_KEMIP_INT, ki_app_python_exec_p1,
547 552
 		{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
Browse code

app_python: print script name in error message

Daniel-Constantin Mierla authored on 25/01/2019 08:28:32
Showing 1 changed files
... ...
@@ -159,7 +159,7 @@ static int mod_init(void)
159 159
 	if(apy_load_script()<0) {
160 160
 		pkg_free(dname_src);
161 161
 		pkg_free(bname_src);
162
-		LM_ERR("failed to load python script\n");
162
+		LM_ERR("failed to load python script: %s\n", _sr_python_load_file.s);
163 163
 		return -1;
164 164
 	}
165 165
 
Browse code

app_python: updated to the new mod interface

Daniel-Constantin Mierla authored on 27/09/2018 21:38:43 • Victor Seva committed on 28/09/2018 11:03:26
Showing 1 changed files
... ...
@@ -82,18 +82,16 @@ static cmd_export_t cmds[] = {
82 82
 
83 83
 /** module exports */
84 84
 struct module_exports exports = {
85
-	"app_python",                   /* module name */
86
-	RTLD_NOW | RTLD_GLOBAL,         /* dlopen flags */
87
-	cmds,                           /* exported functions */
88
-	params,                         /* exported parameters */
89
-	0,                              /* exported statistics */
90
-	0,                              /* exported MI functions */
91
-	0,                              /* exported pseudo-variables */
92
-	0,                              /* extra processes */
93
-	mod_init,                       /* module initialization function */
94
-	(response_function) NULL,       /* response handling function */
95
-	(destroy_function) mod_destroy, /* destroy function */
96
-	child_init                      /* per-child init function */
85
+	"app_python",           /* module name */
86
+	RTLD_NOW | RTLD_GLOBAL, /* dlopen flags */
87
+	cmds,                   /* exported functions */
88
+	params,                 /* exported parameters */
89
+	0,                      /* exported rpc functions */
90
+	0,                      /* exported pseudo-variables */
91
+	0,                      /* response handling function */
92
+	mod_init,               /* module init function */
93
+	child_init,             /* per-child init function */
94
+	mod_destroy             /* destroy function */
97 95
 };
98 96
 
99 97
 
Browse code

app_python: init cfg vars framework only in child init

- apy init is executed in other parts as well

Daniel-Constantin Mierla authored on 20/08/2018 09:11:45
Showing 1 changed files
... ...
@@ -180,6 +180,9 @@ static int child_init(int rank)
180 180
 	}
181 181
 	_apy_process_rank = rank;
182 182
 	PyOS_AfterFork();
183
+	if (cfg_child_init()) {
184
+		return -1;
185
+	}
183 186
 	return apy_init_script(rank);
184 187
 }
185 188
 
... ...
@@ -436,10 +439,6 @@ int apy_init_script(int rank)
436 439
 		goto err;
437 440
 	}
438 441
 
439
-	if (cfg_child_init()) {
440
-		goto err;
441
-	}
442
-
443 442
 	pArgs = PyTuple_New(1);
444 443
 	if (pArgs == NULL) {
445 444
 		python_handle_exception("child_init");
Browse code

app_python: ensure cfg framework is initialized for child init callback

- reported by GH #1618

Daniel-Constantin Mierla authored on 14/08/2018 09:05:17
Showing 1 changed files
... ...
@@ -26,6 +26,7 @@
26 26
 #include "../../core/sr_module.h"
27 27
 #include "../../core/mod_fix.h"
28 28
 #include "../../core/kemi.h"
29
+#include "../../core/cfg/cfg_struct.h"
29 30
 
30 31
 #include "python_exec.h"
31 32
 #include "python_iface.h"
... ...
@@ -278,7 +279,7 @@ int apy_mod_init(PyObject *pModule)
278 279
 	Py_XDECREF(_sr_apy_handler_obj);
279 280
 	_sr_apy_handler_obj = pHandler;
280 281
 	rval = 0;
281
- err:
282
+err:
282 283
 	return rval;
283 284
 }
284 285
 
... ...
@@ -291,7 +292,7 @@ int apy_reload_script(void)
291 292
 	PY_GIL_ENSURE;
292 293
 	pModule = PyImport_ReloadModule(_sr_apy_module);
293 294
 	if (!pModule) {
294
-                // PyErr_PrintEx(0); - don't hide the real exception
295
+		// PyErr_PrintEx(0); - don't hide the real exception
295 296
 		if (!PyErr_Occurred())
296 297
 			PyErr_Format(PyExc_ImportError, "Reload module '%s'", bname);
297 298
 		python_handle_exception("mod_init");
... ...
@@ -306,15 +307,15 @@ int apy_reload_script(void)
306 307
 	Py_DECREF(_sr_apy_module);
307 308
 	_sr_apy_module = pModule;
308 309
 
309
-        if(apy_init_script(_apy_process_rank)<0) {
310
-                LM_ERR("failed to init script\n");
310
+	if(apy_init_script(_apy_process_rank)<0) {
311
+		LM_ERR("failed to init script\n");
311 312
 		goto err;
312
-        }
313
+	}
313 314
 
314 315
 	rval = 0;
315
- err:
316
+err:
316 317
 	PY_GIL_RELEASE;
317
-        return rval;
318
+	return rval;
318 319
 }
319 320
 
320 321
 int apy_load_script(void)
... ...
@@ -390,7 +391,7 @@ int apy_load_script(void)
390 391
 	_sr_apy_module = pModule;
391 392
 
392 393
 	rval = apy_mod_init(pModule);
393
- err:
394
+err:
394 395
 	PY_GIL_RELEASE;
395 396
 	return rval;
396 397
 }
... ...
@@ -435,6 +436,10 @@ int apy_init_script(int rank)
435 436
 		goto err;
436 437
 	}
437 438
 
439
+	if (cfg_child_init()) {
440
+		goto err;
441
+	}
442
+
438 443
 	pArgs = PyTuple_New(1);
439 444
 	if (pArgs == NULL) {
440 445
 		python_handle_exception("child_init");
... ...
@@ -485,7 +490,7 @@ int apy_init_script(int rank)
485 490
 	rval = PyInt_AsLong(pResult);
486 491
 	Py_DECREF(pResult);
487 492
 
488
- err:
493
+err:
489 494
 	PY_GIL_RELEASE;
490 495
 	return rval;
491 496
 }
Browse code

app_python: skip execution of child_init() for rank PROC_INIT

- this is a particular execution in main process after all modules were
initialized, not in a forked child process

Daniel-Constantin Mierla authored on 10/03/2018 07:21:20
Showing 1 changed files
... ...
@@ -174,6 +174,9 @@ static int mod_init(void)
174 174
  */
175 175
 static int child_init(int rank)
176 176
 {
177
+	if(rank==PROC_INIT) {
178
+		return 0;
179
+	}
177 180
 	_apy_process_rank = rank;
178 181
 	PyOS_AfterFork();
179 182
 	return apy_init_script(rank);
Browse code

app_python: call PyOS_AfterFork() in child

AntonyA authored on 05/03/2018 08:23:59
Showing 1 changed files
... ...
@@ -175,6 +175,7 @@ static int mod_init(void)
175 175
 static int child_init(int rank)
176 176
 {
177 177
 	_apy_process_rank = rank;
178
+	PyOS_AfterFork();
178 179
 	return apy_init_script(rank);
179 180
 }
180 181
 
Browse code

app_python: don't hide the real exception on load failure

- don't call PyErr_PrintEx() as this clears the error indicator

AnthonyA authored on 02/03/2018 16:46:05 • Daniel-Constantin Mierla committed on 02/03/2018 20:00:00
Showing 1 changed files
... ...
@@ -287,7 +287,7 @@ int apy_reload_script(void)
287 287
 	PY_GIL_ENSURE;
288 288
 	pModule = PyImport_ReloadModule(_sr_apy_module);
289 289
 	if (!pModule) {
290
-                PyErr_PrintEx(0);
290
+                // PyErr_PrintEx(0); - don't hide the real exception
291 291
 		if (!PyErr_Occurred())
292 292
 			PyErr_Format(PyExc_ImportError, "Reload module '%s'", bname);
293 293
 		python_handle_exception("mod_init");
Browse code

app_python: implement reloading of script

- implements reloading of script
- the version is incremented by RPC and the version check
is performed in each worker on the next invocation of a
Python method

AntonyA authored on 01/03/2018 05:45:21 • Daniel-Constantin Mierla committed on 01/03/2018 09:24:44
Showing 1 changed files
... ...
@@ -51,7 +51,7 @@ static int mod_init(void);
51 51
 static int child_init(int rank);
52 52
 static void mod_destroy(void);
53 53
 
54
-PyObject *_sr_apy_handler_obj;
54
+PyObject *_sr_apy_handler_obj = NULL;
55 55
 
56 56
 char *dname = NULL, *bname = NULL;
57 57
 
... ...
@@ -194,82 +194,16 @@ static void mod_destroy(void)
194 194
 	destroy_mod_Router();
195 195
 }
196 196
 
197
-int apy_load_script(void)
198
-{
199
-	PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs;
200
-	PyThreadState *mainThreadState;
201
-
202
-	Py_Initialize();
203
-	PyEval_InitThreads();
204
-	mainThreadState = PyThreadState_Get();
205
-
206
-	format_exc_obj = InitTracebackModule();
207
-
208
-	if (format_exc_obj == NULL || !PyCallable_Check(format_exc_obj))
209
-	{
210
-		Py_XDECREF(format_exc_obj);
211
-		PyEval_ReleaseLock();
212
-		return -1;
213
-	}
214
-
215
-	sys_path = PySys_GetObject("path");
216
-	/* PySys_GetObject doesn't pass reference! No need to DEREF */
217
-	if (sys_path == NULL) {
218
-		if (!PyErr_Occurred())
219
-			PyErr_Format(PyExc_AttributeError,
220
-					"'module' object 'sys' has no attribute 'path'");
221
-		python_handle_exception("mod_init");
222
-		Py_DECREF(format_exc_obj);
223
-		PyEval_ReleaseLock();
224
-		return -1;
225
-	}
226
-
227
-	pDir = PyString_FromString(dname);
228
-	if (pDir == NULL) {
229
-		if (!PyErr_Occurred())
230
-			PyErr_Format(PyExc_AttributeError,
231
-					"PyString_FromString() has failed");
232
-		python_handle_exception("mod_init");
233
-		Py_DECREF(format_exc_obj);
234
-		PyEval_ReleaseLock();
235
-		return -1;
236
-	}
237
-
238
-	PyList_Insert(sys_path, 0, pDir);
239
-	Py_DECREF(pDir);
240
-
241
-	if (ap_init_modules() != 0) {
242
-		if (!PyErr_Occurred())
243
-			PyErr_SetString(PyExc_AttributeError, "init_modules() has failed");
244
-		python_handle_exception("mod_init");
245
-		Py_DECREF(format_exc_obj);
246
-		PyEval_ReleaseLock();
247
-		return -1;
248
-	}
249
-
250
-	if (python_msgobj_init() != 0) {
251
-		if (!PyErr_Occurred())
252
-			PyErr_SetString(PyExc_AttributeError,
253
-					"python_msgobj_init() has failed");
254
-		python_handle_exception("mod_init");
255
-		Py_DECREF(format_exc_obj);
256
-		PyEval_ReleaseLock();
257
-		return -1;
258
-	}
259
-
260
-	pModule = PyImport_ImportModule(bname);
261
-	if (pModule == NULL) {
262
-		if (!PyErr_Occurred())
263
-			PyErr_Format(PyExc_ImportError, "No module named '%s'", bname);
264
-		python_handle_exception("mod_init");
265
-		Py_DECREF(format_exc_obj);
266
-		PyEval_ReleaseLock();
197
+#define PY_GIL_ENSURE gstate = PyGILState_Ensure()
198
+#define PY_GIL_RELEASE PyGILState_Release(gstate)
199
+static PyObject * _sr_apy_module;
267 200
 
268
-		return -1;
269
-	}
201
+int apy_mod_init(PyObject *pModule)
202
+{
203
+	PyObject *pFunc, *pArgs, *pHandler;
204
+	int rval = -1;
270 205
 
271 206
 	pFunc = PyObject_GetAttrString(pModule, mod_init_fname.s);
272
-	Py_DECREF(pModule);
273 207
 
274 208
 	/* pFunc is a new reference */
275 209
 
... ...
@@ -281,8 +215,7 @@ int apy_load_script(void)
281 215
 		python_handle_exception("mod_init");
282 216
 		Py_DECREF(format_exc_obj);
283 217
 		Py_XDECREF(pFunc);
284
-		PyEval_ReleaseLock();
285
-		return -1;
218
+		goto err;
286 219
 	}
287 220
 
288 221
 	if (!PyCallable_Check(pFunc)) {
... ...
@@ -293,8 +226,7 @@ int apy_load_script(void)
293 226
 		python_handle_exception("mod_init");
294 227
 		Py_DECREF(format_exc_obj);
295 228
 		Py_XDECREF(pFunc);
296
-		PyEval_ReleaseLock();
297
-		return -1;
229
+		goto err;
298 230
 	}
299 231
 
300 232
 
... ...
@@ -303,35 +235,32 @@ int apy_load_script(void)
303 235
 		python_handle_exception("mod_init");
304 236
 		Py_DECREF(format_exc_obj);
305 237
 		Py_DECREF(pFunc);
306
-		PyEval_ReleaseLock();
307
-		return -1;
238
+		goto err;
308 239
 	}
309 240
 
310
-	_sr_apy_handler_obj = PyObject_CallObject(pFunc, pArgs);
241
+	pHandler = PyObject_CallObject(pFunc, pArgs);
311 242
 
312 243
 	Py_XDECREF(pFunc);
313 244
 	Py_XDECREF(pArgs);
314 245
 
315
-	if (_sr_apy_handler_obj == Py_None) {
246
+	if (pHandler == Py_None) {
316 247
 		if (!PyErr_Occurred())
317 248
 			PyErr_Format(PyExc_TypeError,
318 249
 					"Function '%s' of module '%s' has returned None."
319 250
 					" Should be a class instance.", mod_init_fname.s, bname);
320 251
 		python_handle_exception("mod_init");
321 252
 		Py_DECREF(format_exc_obj);
322
-		PyEval_ReleaseLock();
323
-		return -1;
253
+		goto err;
324 254
 	}
325 255
 
326 256
 	if (PyErr_Occurred()) {
327 257
 		python_handle_exception("mod_init");
328
-		Py_XDECREF(_sr_apy_handler_obj);
258
+		Py_XDECREF(pHandler);
329 259
 		Py_DECREF(format_exc_obj);
330
-		PyEval_ReleaseLock();
331
-		return -1;
260
+		goto err;
332 261
 	}
333 262
 
334
-	if (_sr_apy_handler_obj == NULL) {
263
+	if (pHandler == NULL) {
335 264
 		LM_ERR("PyObject_CallObject() returned NULL but no exception!\n");
336 265
 		if (!PyErr_Occurred())
337 266
 			PyErr_Format(PyExc_TypeError,
... ...
@@ -340,25 +269,136 @@ int apy_load_script(void)
340 269
 					mod_init_fname.s, bname);
341 270
 		python_handle_exception("mod_init");
342 271
 		Py_DECREF(format_exc_obj);
343
-		PyEval_ReleaseLock();
344
-		return -1;
272
+		goto err;
345 273
 	}
274
+	Py_XDECREF(_sr_apy_handler_obj);
275
+	_sr_apy_handler_obj = pHandler;
276
+	rval = 0;
277
+ err:
278
+	return rval;
279
+}
346 280
 
347
-	myThreadState = PyThreadState_New(mainThreadState->interp);
348
-	PyEval_ReleaseLock();
281
+int apy_reload_script(void)
282
+{
283
+	PyObject *pModule;
284
+	PyGILState_STATE gstate;
285
+	int rval = -1;
286
+
287
+	PY_GIL_ENSURE;
288
+	pModule = PyImport_ReloadModule(_sr_apy_module);
289
+	if (!pModule) {
290
+                PyErr_PrintEx(0);
291
+		if (!PyErr_Occurred())
292
+			PyErr_Format(PyExc_ImportError, "Reload module '%s'", bname);
293
+		python_handle_exception("mod_init");
294
+		Py_DECREF(format_exc_obj);
295
+		goto err;
296
+	}
297
+	if (apy_mod_init(pModule)) {
298
+		LM_ERR("Error calling mod_init on reload\n");
299
+		Py_DECREF(pModule);
300
+		goto err;
301
+	}
302
+	Py_DECREF(_sr_apy_module);
303
+	_sr_apy_module = pModule;
349 304
 
350
-	return 0;
305
+        if(apy_init_script(_apy_process_rank)<0) {
306
+                LM_ERR("failed to init script\n");
307
+		goto err;
308
+        }
309
+
310
+	rval = 0;
311
+ err:
312
+	PY_GIL_RELEASE;
313
+        return rval;
314
+}
315
+
316
+int apy_load_script(void)
317
+{
318
+	PyObject *sys_path, *pDir, *pModule;
319
+	PyGILState_STATE gstate;
320
+	int rval = -1;
321
+
322
+	Py_Initialize();
323
+	PyEval_InitThreads();
324
+	myThreadState = PyThreadState_Get();
325
+	PY_GIL_ENSURE;
326
+
327
+	format_exc_obj = InitTracebackModule();
328
+
329
+	if (format_exc_obj == NULL || !PyCallable_Check(format_exc_obj))
330
+	{
331
+		Py_XDECREF(format_exc_obj);
332
+		goto err;
333
+	}
334
+
335
+	sys_path = PySys_GetObject("path");
336
+	/* PySys_GetObject doesn't pass reference! No need to DEREF */
337
+	if (sys_path == NULL) {
338
+		if (!PyErr_Occurred())
339
+			PyErr_Format(PyExc_AttributeError,
340
+					"'module' object 'sys' has no attribute 'path'");
341
+		python_handle_exception("mod_init");
342
+		Py_DECREF(format_exc_obj);
343
+		goto err;
344
+	}
345
+
346
+	pDir = PyString_FromString(dname);
347
+	if (pDir == NULL) {
348
+		if (!PyErr_Occurred())
349
+			PyErr_Format(PyExc_AttributeError,
350
+					"PyString_FromString() has failed");
351
+		python_handle_exception("mod_init");
352
+		Py_DECREF(format_exc_obj);
353
+		goto err;
354
+	}
355
+
356
+	PyList_Insert(sys_path, 0, pDir);
357
+	Py_DECREF(pDir);
358
+
359
+	if (ap_init_modules() != 0) {
360
+		if (!PyErr_Occurred())
361
+			PyErr_SetString(PyExc_AttributeError, "init_modules() has failed");
362
+		python_handle_exception("mod_init");
363
+		Py_DECREF(format_exc_obj);
364
+		goto err;
365
+	}
366
+
367
+	if (python_msgobj_init() != 0) {
368
+		if (!PyErr_Occurred())
369
+			PyErr_SetString(PyExc_AttributeError,
370
+					"python_msgobj_init() has failed");
371
+		python_handle_exception("mod_init");
372
+		Py_DECREF(format_exc_obj);
373
+		goto err;
374
+	}
375
+
376
+	pModule = PyImport_ImportModule(bname);
377
+	if (pModule == NULL) {
378
+		if (!PyErr_Occurred())
379
+			PyErr_Format(PyExc_ImportError, "No module named '%s'", bname);
380
+		python_handle_exception("mod_init");
381
+		Py_DECREF(format_exc_obj);
382
+		goto err;
383
+	}
384
+
385
+	/* keep reference to module for reload */
386
+	_sr_apy_module = pModule;
387
+
388
+	rval = apy_mod_init(pModule);
389
+ err:
390
+	PY_GIL_RELEASE;
391
+	return rval;
351 392
 }
352 393
 
353 394
 int apy_init_script(int rank)
354 395
 {
355 396
 	PyObject *pFunc, *pArgs, *pValue, *pResult;
356
-	int rval;
397
+	int rval = -1;
357 398
 	char *classname;
399
+	PyGILState_STATE gstate;
358 400
 
359
-	PyEval_AcquireLock();
360
-	PyThreadState_Swap(myThreadState);
361
-
401
+	PY_GIL_ENSURE;
362 402
 	// get instance class name
363 403
 	classname = get_instance_class_name(_sr_apy_handler_obj);
364 404
 	if (classname == NULL)
... ...
@@ -368,9 +408,7 @@ int apy_init_script(int rank)
368 408
 					"'module' instance has no class name");
369 409
 		python_handle_exception("child_init");
370 410
 		Py_DECREF(format_exc_obj);
371
-		PyThreadState_Swap(NULL);
372
-		PyEval_ReleaseLock();
373
-		return -1;
411
+		goto err;
374 412
 	}
375 413
 
376 414
 	pFunc = PyObject_GetAttrString(_sr_apy_handler_obj, child_init_mname.s);
... ...
@@ -379,9 +417,7 @@ int apy_init_script(int rank)
379 417
 		python_handle_exception("child_init");
380 418
 		Py_XDECREF(pFunc);
381 419
 		Py_DECREF(format_exc_obj);
382
-		PyThreadState_Swap(NULL);
383
-		PyEval_ReleaseLock();
384
-		return -1;
420
+		goto err;
385 421
 	}
386 422
 
387 423
 	if (!PyCallable_Check(pFunc)) {
... ...
@@ -392,9 +428,7 @@ int apy_init_script(int rank)
392 428
 		python_handle_exception("child_init");
393 429
 		Py_DECREF(format_exc_obj);
394 430
 		Py_XDECREF(pFunc);
395
-		PyThreadState_Swap(NULL);
396
-		PyEval_ReleaseLock();
397
-		return -1;
431
+		goto err;
398 432
 	}
399 433
 
400 434
 	pArgs = PyTuple_New(1);
... ...
@@ -402,9 +436,7 @@ int apy_init_script(int rank)
402 436
 		python_handle_exception("child_init");
403 437
 		Py_DECREF(format_exc_obj);
404 438
 		Py_DECREF(pFunc);
405
-		PyThreadState_Swap(NULL);
406
-		PyEval_ReleaseLock();
407
-		return -1;
439
+		goto err;
408 440
 	}
409 441
 
410 442
 	pValue = PyInt_FromLong((long)rank);
... ...
@@ -413,9 +445,7 @@ int apy_init_script(int rank)
413 445
 		Py_DECREF(format_exc_obj);
414 446
 		Py_DECREF(pArgs);
415 447
 		Py_DECREF(pFunc);
416
-		PyThreadState_Swap(NULL);
417
-		PyEval_ReleaseLock();
418
-		return -1;
448
+		goto err;
419 449
 	}
420 450
 	PyTuple_SetItem(pArgs, 0, pValue);
421 451
 	/* pValue has been stolen */
... ...
@@ -428,16 +458,12 @@ int apy_init_script(int rank)
428 458
 		python_handle_exception("child_init");
429 459
 		Py_DECREF(format_exc_obj);
430 460
 		Py_XDECREF(pResult);
431
-		PyThreadState_Swap(NULL);
432
-		PyEval_ReleaseLock();
433
-		return -1;
461
+		goto err;
434 462
 	}
435 463
 
436 464
 	if (pResult == NULL) {
437 465
 		LM_ERR("PyObject_CallObject() returned NULL but no exception!\n");
438
-		PyThreadState_Swap(NULL);
439
-		PyEval_ReleaseLock();
440
-		return -1;
466
+		goto err;
441 467
 	}
442 468
 
443 469
 	if (!PyInt_Check(pResult))
... ...
@@ -449,16 +475,14 @@ int apy_init_script(int rank)
449 475
 		python_handle_exception("child_init");
450 476
 		Py_DECREF(format_exc_obj);
451 477
 		Py_XDECREF(pResult);
452
-		PyThreadState_Swap(NULL);
453
-		PyEval_ReleaseLock();
454
-		return -1;
478
+		goto err;
455 479
 	}
456 480
 
457 481
 	rval = PyInt_AsLong(pResult);
458 482
 	Py_DECREF(pResult);
459
-	PyThreadState_Swap(NULL);
460
-	PyEval_ReleaseLock();
461 483
 
484
+ err:
485
+	PY_GIL_RELEASE;
462 486
 	return rval;
463 487
 }
464 488
 /**
Browse code

app_python: enabled rpc command to reload the script

- reload command performs the mod_init and child_init operations
- not tested yet

Daniel-Constantin Mierla authored on 08/12/2017 11:17:07
Showing 1 changed files
... ...
@@ -55,6 +55,8 @@ PyObject *_sr_apy_handler_obj;
55 55
 
56 56
 char *dname = NULL, *bname = NULL;
57 57
 
58
+int _apy_process_rank = 0;
59
+
58 60
 PyThreadState *myThreadState;
59 61
 
60 62
 /** module parameters */
... ...
@@ -93,16 +95,14 @@ struct module_exports exports = {
93 95
 	child_init                      /* per-child init function */
94 96
 };
95 97
 
98
+
96 99
 /**
97 100
  *
98 101
  */
99 102
 static int mod_init(void)
100 103
 {
101 104
 	char *dname_src, *bname_src;
102
-
103 105
 	int i;
104
-	PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs;
105
-	PyThreadState *mainThreadState;
106 106
 
107 107
 	if(apy_sr_init_mod()<0) {
108 108
 		LM_ERR("failed to init the sr mod\n");
... ...
@@ -157,6 +157,48 @@ static int mod_init(void)
157 157
 		return -1;
158 158
 	}
159 159
 
160
+	if(apy_load_script()<0) {
161
+		pkg_free(dname_src);
162
+		pkg_free(bname_src);
163
+		LM_ERR("failed to load python script\n");
164
+		return -1;
165
+	}
166
+
167
+	pkg_free(dname_src);
168
+	pkg_free(bname_src);
169
+	return 0;
170
+}
171
+
172
+/**
173
+ *
174
+ */
175
+static int child_init(int rank)
176
+{
177
+	_apy_process_rank = rank;
178
+	return apy_init_script(rank);
179
+}
180
+
181
+/**
182
+ *
183
+ */
184
+static void mod_destroy(void)
185
+{
186
+	if (dname)
187
+		free(dname);	// dname was strdup'ed
188
+	if (bname)
189
+		free(bname);	// bname was strdup'ed
190
+
191
+	destroy_mod_Core();
192
+	destroy_mod_Ranks();
193
+	destroy_mod_Logger();
194
+	destroy_mod_Router();
195
+}
196
+
197
+int apy_load_script(void)
198
+{
199
+	PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs;
200
+	PyThreadState *mainThreadState;
201
+
160 202
 	Py_Initialize();
161 203
 	PyEval_InitThreads();
162 204
 	mainThreadState = PyThreadState_Get();
... ...
@@ -167,8 +209,6 @@ static int mod_init(void)
167 209
 	{
168 210
 		Py_XDECREF(format_exc_obj);
169 211
 		PyEval_ReleaseLock();
170
-		pkg_free(dname_src);
171
-		pkg_free(bname_src);
172 212
 		return -1;
173 213
 	}
174 214
 
... ...
@@ -181,8 +221,6 @@ static int mod_init(void)
181 221
 		python_handle_exception("mod_init");
182 222
 		Py_DECREF(format_exc_obj);
183 223
 		PyEval_ReleaseLock();
184
-		pkg_free(dname_src);
185
-		pkg_free(bname_src);
186 224
 		return -1;
187 225
 	}
188 226
 
... ...
@@ -194,8 +232,6 @@ static int mod_init(void)
194 232
 		python_handle_exception("mod_init");
195 233
 		Py_DECREF(format_exc_obj);
196 234
 		PyEval_ReleaseLock();
197
-		pkg_free(dname_src);
198
-		pkg_free(bname_src);
199 235
 		return -1;
200 236
 	}
201 237
 
... ...
@@ -208,8 +244,6 @@ static int mod_init(void)
208 244
 		python_handle_exception("mod_init");
209 245
 		Py_DECREF(format_exc_obj);
210 246
 		PyEval_ReleaseLock();
211
-		pkg_free(dname_src);
212
-		pkg_free(bname_src);
213 247
 		return -1;
214 248
 	}
215 249
 
... ...
@@ -220,8 +254,6 @@ static int mod_init(void)
220 254
 		python_handle_exception("mod_init");
221 255
 		Py_DECREF(format_exc_obj);
222 256
 		PyEval_ReleaseLock();
223
-		pkg_free(dname_src);
224
-		pkg_free(bname_src);
225 257
 		return -1;
226 258
 	}
227 259
 
... ...
@@ -232,14 +264,10 @@ static int mod_init(void)
232 264
 		python_handle_exception("mod_init");
233 265
 		Py_DECREF(format_exc_obj);
234 266
 		PyEval_ReleaseLock();
235
-		pkg_free(dname_src);
236
-		pkg_free(bname_src);
267
+
237 268
 		return -1;
238 269
 	}
239 270
 
240
-	pkg_free(dname_src);
241
-	pkg_free(bname_src);
242
-
243 271
 	pFunc = PyObject_GetAttrString(pModule, mod_init_fname.s);
244 272
 	Py_DECREF(pModule);
245 273
 
... ...
@@ -322,10 +350,7 @@ static int mod_init(void)
322 350
 	return 0;
323 351
 }
324 352
 
325
-/**
326
- *
327
- */
328
-static int child_init(int rank)
353
+int apy_init_script(int rank)
329 354
 {
330 355
 	PyObject *pFunc, *pArgs, *pValue, *pResult;
331 356
 	int rval;
... ...
@@ -436,23 +461,6 @@ static int child_init(int rank)
436 461
 
437 462
 	return rval;
438 463
 }
439
-
440
-/**
441
- *
442
- */
443
-static void mod_destroy(void)
444
-{
445
-	if (dname)
446
-		free(dname);	// dname was strdup'ed
447
-	if (bname)
448
-		free(bname);	// bname was strdup'ed
449
-
450
-	destroy_mod_Core();
451
-	destroy_mod_Ranks();
452
-	destroy_mod_Logger();
453
-	destroy_mod_Router();
454
-}
455
-
456 464
 /**
457 465
  *
458 466
  */
Browse code

app_python: implemented rpc command to list kemi functions

- kamctl rpc app_python.api_list

Daniel-Constantin Mierla authored on 23/11/2017 11:40:19
Showing 1 changed files
... ...
@@ -43,7 +43,7 @@
43 43
 MODULE_VERSION
44 44
 
45 45
 
46
-static str script_name = str_init("/usr/local/etc/" NAME "/handler.py");
46
+str _sr_python_load_file = str_init("/usr/local/etc/" NAME "/handler.py");
47 47
 static str mod_init_fname = str_init("mod_init");
48 48
 static str child_init_mname = str_init("child_init");
49 49
 
... ...
@@ -59,8 +59,8 @@ PyThreadState *myThreadState;
59 59
 
60 60
 /** module parameters */
61 61
 static param_export_t params[]={
62
-	{"script_name",        PARAM_STR, &script_name },
63
-	{"load",               PARAM_STR, &script_name },
62
+	{"script_name",        PARAM_STR, &_sr_python_load_file },
63
+	{"load",               PARAM_STR, &_sr_python_load_file },
64 64
 	{"mod_init_function",  PARAM_STR, &mod_init_fname },
65 65
 	{"child_init_method",  PARAM_STR, &child_init_mname },
66 66
 	{0,0,0}
... ...
@@ -104,8 +104,17 @@ static int mod_init(void)
104 104
 	PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs;
105 105
 	PyThreadState *mainThreadState;
106 106
 
107
-	dname_src = as_asciiz(&script_name);
108
-	bname_src = as_asciiz(&script_name);
107
+	if(apy_sr_init_mod()<0) {
108
+		LM_ERR("failed to init the sr mod\n");
109
+		return -1;
110
+	}
111
+	if(app_python_init_rpc()<0) {
112
+		LM_ERR("failed to register RPC commands\n");
113
+		return -1;
114
+	}
115
+
116
+	dname_src = as_asciiz(&_sr_python_load_file);
117
+	bname_src = as_asciiz(&_sr_python_load_file);
109 118
 
110 119
 	if(dname_src==NULL || bname_src==NULL)
111 120
 	{
... ...
@@ -142,7 +151,7 @@ static int mod_init(void)
142 151
 		bname[i - 3] = '\0';
143 152
 	} else {
144 153
 		LM_ERR("%s: script_name doesn't look like a python script\n",
145
-				script_name.s);
154
+				_sr_python_load_file.s);
146 155
 		pkg_free(dname_src);
147 156
 		pkg_free(bname_src);
148 157
 		return -1;
Browse code

app_python: aliased load to script_name parameter

- load is used to specify what scripts needs to be loaded among the
modules implementing kemi

Daniel-Constantin Mierla authored on 20/11/2017 16:21:50
Showing 1 changed files
... ...
@@ -60,6 +60,7 @@ PyThreadState *myThreadState;
60 60
 /** module parameters */
61 61
 static param_export_t params[]={
62 62
 	{"script_name",        PARAM_STR, &script_name },
63
+	{"load",               PARAM_STR, &script_name },
63 64
 	{"mod_init_function",  PARAM_STR, &mod_init_fname },
64 65
 	{"child_init_method",  PARAM_STR, &child_init_mname },
65 66
 	{0,0,0}
Browse code

app_python: removed condition on classname, it cannot be null

Daniel-Constantin Mierla authored on 27/07/2017 16:26:28
Showing 1 changed files
... ...
@@ -410,7 +410,7 @@ static int child_init(int rank)
410 410
 		if (!PyErr_Occurred())
411 411
 			PyErr_Format(PyExc_TypeError,
412 412
 					"method '%s' of class '%s' should return 'int' type",
413
-					child_init_mname.s, !classname ? "None" : classname);
413
+					child_init_mname.s, classname);
414 414
 		python_handle_exception("child_init");
415 415
 		Py_DECREF(format_exc_obj);
416 416
 		Py_XDECREF(pResult);
Browse code

app_python: remove condition on classname, being set to non-null

Daniel-Constantin Mierla authored on 27/07/2017 07:09:26
Showing 1 changed files
... ...
@@ -353,7 +353,7 @@ static int child_init(int rank)
353 353
 		if (!PyErr_Occurred())
354 354
 			PyErr_Format(PyExc_AttributeError,
355 355
 					"class object '%s' has is not callable attribute '%s'",
356
-					!classname ? "None" : classname, mod_init_fname.s);
356
+					classname, mod_init_fname.s);
357 357
 		python_handle_exception("child_init");
358 358
 		Py_DECREF(format_exc_obj);
359 359
 		Py_XDECREF(pFunc);
... ...
@@ -389,9 +389,6 @@ static int child_init(int rank)
389 389
 	Py_DECREF(pFunc);
390 390
 	Py_DECREF(pArgs);
391 391
 
392
-
393
-
394
-
395 392
 	if (PyErr_Occurred()) {
396 393
 		python_handle_exception("child_init");
397 394
 		Py_DECREF(format_exc_obj);
... ...
@@ -422,7 +419,6 @@ static int child_init(int rank)
422 419
 		return -1;
423 420
 	}
424 421
 
425
-
426 422
 	rval = PyInt_AsLong(pResult);
427 423
 	Py_DECREF(pResult);
428 424
 	PyThreadState_Swap(NULL);
Browse code

app_python: several free of allocated vars in case of errors

Daniel-Constantin Mierla authored on 15/07/2017 06:41:09
Showing 1 changed files
... ...
@@ -109,12 +109,16 @@ static int mod_init(void)
109 109
 	if(dname_src==NULL || bname_src==NULL)
110 110
 	{
111 111
 		LM_ERR("no more pkg memory\n");
112
+		if(dname_src) pkg_free(dname_src);
113
+		if(bname_src) pkg_free(bname_src);
112 114
 		return -1;
113 115
 	}
114 116
 
115 117
 	dname = strdup(dirname(dname_src));
116 118
 	if(dname==NULL) {
117 119
 		LM_ERR("no more system memory\n");
120
+		pkg_free(dname_src);
121
+		pkg_free(bname_src);
118 122
 		return -1;
119 123
 	}
120 124
 	if (strlen(dname) == 0) {
... ...
@@ -122,6 +126,8 @@ static int mod_init(void)
122 126
 		dname = malloc(2);
123 127
 		if(dname==NULL) {
124 128
 			LM_ERR("no more system memory\n");
129
+			pkg_free(dname_src);
130
+			pkg_free(bname_src);
125 131
 			return -1;
126 132
 		}
127 133
 		dname[0] = '.';
... ...
@@ -136,6 +142,8 @@ static int mod_init(void)
136 142
 	} else {
137 143
 		LM_ERR("%s: script_name doesn't look like a python script\n",
138 144
 				script_name.s);
145
+		pkg_free(dname_src);
146
+		pkg_free(bname_src);
139 147
 		return -1;
140 148
 	}
141 149
 
... ...
@@ -149,6 +157,8 @@ static int mod_init(void)
149 157
 	{
150 158
 		Py_XDECREF(format_exc_obj);
151 159
 		PyEval_ReleaseLock();
160
+		pkg_free(dname_src);
161
+		pkg_free(bname_src);
152 162
 		return -1;
153 163
 	}
154 164
 
... ...
@@ -156,20 +166,26 @@ static int mod_init(void)
156 166
 	/* PySys_GetObject doesn't pass reference! No need to DEREF */
157 167
 	if (sys_path == NULL) {
158 168
 		if (!PyErr_Occurred())
159
-			PyErr_Format(PyExc_AttributeError, "'module' object 'sys' has no attribute 'path'");
169
+			PyErr_Format(PyExc_AttributeError,
170
+					"'module' object 'sys' has no attribute 'path'");
160 171
 		python_handle_exception("mod_init");
161 172
 		Py_DECREF(format_exc_obj);
162 173
 		PyEval_ReleaseLock();
174
+		pkg_free(dname_src);
175
+		pkg_free(bname_src);
163