Deleted
Added
nxt_python.c (1759:196b4d90c8cc) | nxt_python.c (1872:9f8df8b810e0) |
---|---|
1 2/* 3 * Copyright (C) NGINX, Inc. 4 */ 5 6 7#include <Python.h> 8 --- 10 unchanged lines hidden (view full) --- 19 pthread_t thread; 20 nxt_unit_ctx_t *ctx; 21 void *ctx_data; 22} nxt_py_thread_info_t; 23 24 25static nxt_int_t nxt_python_start(nxt_task_t *task, 26 nxt_process_data_t *data); | 1 2/* 3 * Copyright (C) NGINX, Inc. 4 */ 5 6 7#include <Python.h> 8 --- 10 unchanged lines hidden (view full) --- 19 pthread_t thread; 20 nxt_unit_ctx_t *ctx; 21 void *ctx_data; 22} nxt_py_thread_info_t; 23 24 25static nxt_int_t nxt_python_start(nxt_task_t *task, 26 nxt_process_data_t *data); |
27static nxt_int_t nxt_python_set_target(nxt_task_t *task, 28 nxt_python_target_t *target, nxt_conf_value_t *conf); |
|
27static nxt_int_t nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value); 28static int nxt_python_init_threads(nxt_python_app_conf_t *c); 29static int nxt_python_ready_handler(nxt_unit_ctx_t *ctx); 30static void *nxt_python_thread_func(void *main_ctx); 31static void nxt_python_join_threads(nxt_unit_ctx_t *ctx, 32 nxt_python_app_conf_t *c); 33static void nxt_python_atexit(void); 34 --- 9 unchanged lines hidden (view full) --- 44 PY_VERSION, 45 nxt_python_mounts, 46 nxt_nitems(nxt_python_mounts), 47 NULL, 48 nxt_python_start, 49}; 50 51static PyObject *nxt_py_stderr_flush; | 29static nxt_int_t nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value); 30static int nxt_python_init_threads(nxt_python_app_conf_t *c); 31static int nxt_python_ready_handler(nxt_unit_ctx_t *ctx); 32static void *nxt_python_thread_func(void *main_ctx); 33static void nxt_python_join_threads(nxt_unit_ctx_t *ctx, 34 nxt_python_app_conf_t *c); 35static void nxt_python_atexit(void); 36 --- 9 unchanged lines hidden (view full) --- 46 PY_VERSION, 47 nxt_python_mounts, 48 nxt_nitems(nxt_python_mounts), 49 NULL, 50 nxt_python_start, 51}; 52 53static PyObject *nxt_py_stderr_flush; |
52PyObject *nxt_py_application; | 54nxt_python_targets_t *nxt_py_targets; |
53 54#if PY_MAJOR_VERSION == 3 55static wchar_t *nxt_py_home; 56#else 57static char *nxt_py_home; 58#endif 59 60static pthread_attr_t *nxt_py_thread_attr; 61static nxt_py_thread_info_t *nxt_py_threads; 62static nxt_python_proto_t nxt_py_proto; 63 64 65static nxt_int_t 66nxt_python_start(nxt_task_t *task, nxt_process_data_t *data) 67{ 68 int rc; | 55 56#if PY_MAJOR_VERSION == 3 57static wchar_t *nxt_py_home; 58#else 59static char *nxt_py_home; 60#endif 61 62static pthread_attr_t *nxt_py_thread_attr; 63static nxt_py_thread_info_t *nxt_py_threads; 64static nxt_python_proto_t nxt_py_proto; 65 66 67static nxt_int_t 68nxt_python_start(nxt_task_t *task, nxt_process_data_t *data) 69{ 70 int rc; |
69 char *nxt_py_module; 70 size_t len; | 71 size_t len, size; 72 uint32_t next; |
71 PyObject *obj, *module; | 73 PyObject *obj, *module; |
72 nxt_str_t proto; 73 const char *callable; | 74 nxt_str_t proto, probe_proto, name; 75 nxt_int_t ret, n, i; |
74 nxt_unit_ctx_t *unit_ctx; 75 nxt_unit_init_t python_init; | 76 nxt_unit_ctx_t *unit_ctx; 77 nxt_unit_init_t python_init; |
78 nxt_conf_value_t *cv; 79 nxt_python_targets_t *targets; |
|
76 nxt_common_app_conf_t *app_conf; 77 nxt_python_app_conf_t *c; 78#if PY_MAJOR_VERSION == 3 79 char *path; | 80 nxt_common_app_conf_t *app_conf; 81 nxt_python_app_conf_t *c; 82#if PY_MAJOR_VERSION == 3 83 char *path; |
80 size_t size; | |
81 nxt_int_t pep405; 82 83 static const char pyvenv[] = "/pyvenv.cfg"; 84 static const char bin_python[] = "/bin/python"; 85#endif 86 87 static const nxt_str_t wsgi = nxt_string("wsgi"); 88 static const nxt_str_t asgi = nxt_string("asgi"); --- 96 unchanged lines hidden (view full) --- 185 186 if (nxt_slow_path(PySys_SetObject((char *) "argv", obj) != 0)) { 187 nxt_alert(task, "Python failed to set the \"sys.argv\" list"); 188 goto fail; 189 } 190 191 Py_CLEAR(obj); 192 | 84 nxt_int_t pep405; 85 86 static const char pyvenv[] = "/pyvenv.cfg"; 87 static const char bin_python[] = "/bin/python"; 88#endif 89 90 static const nxt_str_t wsgi = nxt_string("wsgi"); 91 static const nxt_str_t asgi = nxt_string("asgi"); --- 96 unchanged lines hidden (view full) --- 188 189 if (nxt_slow_path(PySys_SetObject((char *) "argv", obj) != 0)) { 190 nxt_alert(task, "Python failed to set the \"sys.argv\" list"); 191 goto fail; 192 } 193 194 Py_CLEAR(obj); 195 |
193 nxt_py_module = nxt_alloca(c->module.length + 1); 194 nxt_memcpy(nxt_py_module, c->module.start, c->module.length); 195 nxt_py_module[c->module.length] = '\0'; | 196 n = (c->targets != NULL ? nxt_conf_object_members_count(c->targets) : 1); |
196 | 197 |
197 module = PyImport_ImportModule(nxt_py_module); 198 if (nxt_slow_path(module == NULL)) { 199 nxt_alert(task, "Python failed to import module \"%s\"", nxt_py_module); 200 nxt_python_print_exception(); | 198 size = sizeof(nxt_python_targets_t) + n * sizeof(nxt_python_target_t); 199 200 targets = nxt_unit_malloc(NULL, size); 201 if (nxt_slow_path(targets == NULL)) { 202 nxt_alert(task, "Could not allocate targets"); |
201 goto fail; 202 } 203 | 203 goto fail; 204 } 205 |
204 callable = (c->callable != NULL) ? c->callable : "application"; | 206 memset(targets, 0, size); |
205 | 207 |
206 obj = PyDict_GetItemString(PyModule_GetDict(module), callable); 207 if (nxt_slow_path(obj == NULL)) { 208 nxt_alert(task, "Python failed to get \"%s\" " 209 "from module \"%s\"", callable, nxt_py_module); 210 goto fail; 211 } | 208 targets->count = n; 209 nxt_py_targets = targets; |
212 | 210 |
213 if (nxt_slow_path(PyCallable_Check(obj) == 0)) { 214 nxt_alert(task, "\"%s\" in module \"%s\" " 215 "is not a callable object", callable, nxt_py_module); 216 goto fail; 217 } | 211 if (c->targets != NULL) { 212 next = 0; |
218 | 213 |
219 nxt_py_application = obj; 220 obj = NULL; | 214 for (i = 0; /* void */; i++) { 215 cv = nxt_conf_next_object_member(c->targets, &name, &next); 216 if (cv == NULL) { 217 break; 218 } |
221 | 219 |
222 Py_INCREF(nxt_py_application); | 220 ret = nxt_python_set_target(task, &targets->target[i], cv); 221 if (nxt_slow_path(ret != NXT_OK)) { 222 goto fail; 223 } 224 } |
223 | 225 |
224 Py_CLEAR(module); | 226 } else { 227 ret = nxt_python_set_target(task, &targets->target[0], app_conf->self); 228 if (nxt_slow_path(ret != NXT_OK)) { 229 goto fail; 230 } 231 } |
225 226 nxt_unit_default_init(task, &python_init); 227 228 python_init.data = c; 229 python_init.shm_limit = data->app->shm_limit; 230 python_init.callbacks.ready_handler = nxt_python_ready_handler; 231 232 proto = c->protocol; 233 234 if (proto.length == 0) { | 232 233 nxt_unit_default_init(task, &python_init); 234 235 python_init.data = c; 236 python_init.shm_limit = data->app->shm_limit; 237 python_init.callbacks.ready_handler = nxt_python_ready_handler; 238 239 proto = c->protocol; 240 241 if (proto.length == 0) { |
235 proto = nxt_python_asgi_check(nxt_py_application) ? asgi : wsgi; | 242 proto = nxt_python_asgi_check(targets->target[0].application) 243 ? asgi : wsgi; 244 245 for (i = 1; i < targets->count; i++) { 246 probe_proto = nxt_python_asgi_check(targets->target[i].application) 247 ? asgi : wsgi; 248 if (probe_proto.start != proto.start) { 249 nxt_alert(task, "A mix of ASGI & WSGI targets is forbidden, " 250 "specify protocol in config if incorrect"); 251 goto fail; 252 } 253 } |
236 } 237 238 if (nxt_strstr_eq(&proto, &asgi)) { 239 rc = nxt_python_asgi_init(&python_init, &nxt_py_proto); 240 241 } else { 242 rc = nxt_python_wsgi_init(&python_init, &nxt_py_proto); 243 } --- 50 unchanged lines hidden (view full) --- 294 295 nxt_python_atexit(); 296 297 return NXT_ERROR; 298} 299 300 301static nxt_int_t | 254 } 255 256 if (nxt_strstr_eq(&proto, &asgi)) { 257 rc = nxt_python_asgi_init(&python_init, &nxt_py_proto); 258 259 } else { 260 rc = nxt_python_wsgi_init(&python_init, &nxt_py_proto); 261 } --- 50 unchanged lines hidden (view full) --- 312 313 nxt_python_atexit(); 314 315 return NXT_ERROR; 316} 317 318 319static nxt_int_t |
320nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target, 321 nxt_conf_value_t *conf) 322{ 323 char *callable, *module_name; 324 PyObject *module, *obj; 325 nxt_str_t str; 326 nxt_conf_value_t *value; 327 328 static nxt_str_t module_str = nxt_string("module"); 329 static nxt_str_t callable_str = nxt_string("callable"); 330 331 module = obj = NULL; 332 333 value = nxt_conf_get_object_member(conf, &module_str, NULL); 334 if (nxt_slow_path(value == NULL)) { 335 goto fail; 336 } 337 338 nxt_conf_get_string(value, &str); 339 340 module_name = nxt_alloca(str.length + 1); 341 nxt_memcpy(module_name, str.start, str.length); 342 module_name[str.length] = '\0'; 343 344 module = PyImport_ImportModule(module_name); 345 if (nxt_slow_path(module == NULL)) { 346 nxt_alert(task, "Python failed to import module \"%s\"", module_name); 347 nxt_python_print_exception(); 348 goto fail; 349 } 350 351 value = nxt_conf_get_object_member(conf, &callable_str, NULL); 352 if (value == NULL) { 353 callable = nxt_alloca(12); 354 nxt_memcpy(callable, "application", 12); 355 356 } else { 357 nxt_conf_get_string(value, &str); 358 359 callable = nxt_alloca(str.length + 1); 360 nxt_memcpy(callable, str.start, str.length); 361 callable[str.length] = '\0'; 362 } 363 364 obj = PyDict_GetItemString(PyModule_GetDict(module), callable); 365 if (nxt_slow_path(obj == NULL)) { 366 nxt_alert(task, "Python failed to get \"%s\" from module \"%s\"", 367 callable, module); 368 goto fail; 369 } 370 371 if (nxt_slow_path(PyCallable_Check(obj) == 0)) { 372 nxt_alert(task, "\"%s\" in module \"%s\" is not a callable object", 373 callable, module); 374 goto fail; 375 } 376 377 target->application = obj; 378 obj = NULL; 379 380 Py_INCREF(target->application); 381 Py_CLEAR(module); 382 383 return NXT_OK; 384 385fail: 386 387 Py_XDECREF(obj); 388 Py_XDECREF(module); 389 390 return NXT_ERROR; 391} 392 393 394static nxt_int_t |
|
302nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value) 303{ 304 int ret; 305 PyObject *path, *sys; 306 nxt_str_t str; 307 nxt_uint_t n; 308 nxt_conf_value_t *array; 309 --- 281 unchanged lines hidden (view full) --- 591 pstr++; 592 } 593} 594 595 596static void 597nxt_python_atexit(void) 598{ | 395nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value) 396{ 397 int ret; 398 PyObject *path, *sys; 399 nxt_str_t str; 400 nxt_uint_t n; 401 nxt_conf_value_t *array; 402 --- 281 unchanged lines hidden (view full) --- 684 pstr++; 685 } 686} 687 688 689static void 690nxt_python_atexit(void) 691{ |
692 nxt_int_t i; 693 |
|
599 if (nxt_py_proto.done != NULL) { 600 nxt_py_proto.done(); 601 } 602 603 Py_XDECREF(nxt_py_stderr_flush); | 694 if (nxt_py_proto.done != NULL) { 695 nxt_py_proto.done(); 696 } 697 698 Py_XDECREF(nxt_py_stderr_flush); |
604 Py_XDECREF(nxt_py_application); | |
605 | 699 |
700 if (nxt_py_targets != NULL) { 701 for (i = 0; i < nxt_py_targets->count; i++) { 702 Py_XDECREF(nxt_py_targets->target[i].application); 703 } 704 705 nxt_unit_free(NULL, nxt_py_targets); 706 } 707 |
|
606 Py_Finalize(); 607 608 if (nxt_py_home != NULL) { 609 nxt_free(nxt_py_home); 610 } 611} 612 613 --- 20 unchanged lines hidden --- | 708 Py_Finalize(); 709 710 if (nxt_py_home != NULL) { 711 nxt_free(nxt_py_home); 712 } 713} 714 715 --- 20 unchanged lines hidden --- |