summaryrefslogtreecommitdiffhomepage
path: root/src/python/nxt_python.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/python/nxt_python.c')
-rw-r--r--src/python/nxt_python.c133
1 files changed, 126 insertions, 7 deletions
diff --git a/src/python/nxt_python.c b/src/python/nxt_python.c
index 188c4920..bdb04579 100644
--- a/src/python/nxt_python.c
+++ b/src/python/nxt_python.c
@@ -22,10 +22,16 @@ typedef struct {
} nxt_py_thread_info_t;
+#if PY_MAJOR_VERSION == 3
+static nxt_int_t nxt_python3_init_config(nxt_int_t pep405);
+#endif
+
static nxt_int_t nxt_python_start(nxt_task_t *task,
nxt_process_data_t *data);
static nxt_int_t nxt_python_set_target(nxt_task_t *task,
nxt_python_target_t *target, nxt_conf_value_t *conf);
+nxt_inline nxt_int_t nxt_python_set_prefix(nxt_task_t *task,
+ nxt_python_target_t *target, nxt_conf_value_t *value);
static nxt_int_t nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value);
static int nxt_python_init_threads(nxt_python_app_conf_t *c);
static int nxt_python_ready_handler(nxt_unit_ctx_t *ctx);
@@ -64,13 +70,70 @@ static nxt_py_thread_info_t *nxt_py_threads;
static nxt_python_proto_t nxt_py_proto;
+#if PY_VERSION_HEX >= NXT_PYTHON_VER(3, 8)
+
+static nxt_int_t
+nxt_python3_init_config(nxt_int_t pep405)
+{
+ PyStatus status;
+ PyConfig config;
+
+ PyConfig_InitIsolatedConfig(&config);
+
+ if (pep405) {
+ status = PyConfig_SetString(&config, &config.program_name,
+ nxt_py_home);
+ if (PyStatus_Exception(status)) {
+ goto pyinit_exception;
+ }
+
+ } else {
+ status =PyConfig_SetString(&config, &config.home, nxt_py_home);
+ if (PyStatus_Exception(status)) {
+ goto pyinit_exception;
+ }
+ }
+
+ status = Py_InitializeFromConfig(&config);
+ if (PyStatus_Exception(status)) {
+ goto pyinit_exception;
+ }
+ PyConfig_Clear(&config);
+
+ return NXT_OK;
+
+pyinit_exception:
+
+ PyConfig_Clear(&config);
+
+ return NXT_ERROR;
+}
+
+#elif PY_MAJOR_VERSION == 3
+
+static nxt_int_t
+nxt_python3_init_config(nxt_int_t pep405)
+{
+ if (pep405) {
+ Py_SetProgramName(nxt_py_home);
+
+ } else {
+ Py_SetPythonHome(nxt_py_home);
+ }
+
+ return NXT_OK;
+}
+
+#endif
+
+
static nxt_int_t
nxt_python_start(nxt_task_t *task, nxt_process_data_t *data)
{
int rc;
size_t len, size;
uint32_t next;
- PyObject *obj, *module;
+ PyObject *obj;
nxt_str_t proto, probe_proto, name;
nxt_int_t ret, n, i;
nxt_unit_ctx_t *unit_ctx;
@@ -127,11 +190,15 @@ nxt_python_start(nxt_task_t *task, nxt_process_data_t *data)
if (pep405) {
mbstowcs(nxt_py_home, c->home, len);
mbstowcs(nxt_py_home + len, bin_python, sizeof(bin_python));
- Py_SetProgramName(nxt_py_home);
} else {
mbstowcs(nxt_py_home, c->home, len + 1);
- Py_SetPythonHome(nxt_py_home);
+ }
+
+ ret = nxt_python3_init_config(pep405);
+ if (nxt_slow_path(ret == NXT_ERROR)) {
+ nxt_alert(task, "Failed to initialise config");
+ return NXT_ERROR;
}
#else
@@ -154,7 +221,6 @@ nxt_python_start(nxt_task_t *task, nxt_process_data_t *data)
}
#endif
- module = NULL;
obj = NULL;
python_init.ctx_data = NULL;
@@ -307,7 +373,6 @@ fail:
}
Py_XDECREF(obj);
- Py_XDECREF(module);
nxt_python_atexit();
@@ -326,6 +391,7 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target,
static nxt_str_t module_str = nxt_string("module");
static nxt_str_t callable_str = nxt_string("callable");
+ static nxt_str_t prefix_str = nxt_string("prefix");
module = obj = NULL;
@@ -373,6 +439,11 @@ nxt_python_set_target(nxt_task_t *task, nxt_python_target_t *target,
goto fail;
}
+ value = nxt_conf_get_object_member(conf, &prefix_str, NULL);
+ if (nxt_slow_path(nxt_python_set_prefix(task, target, value) != NXT_OK)) {
+ goto fail;
+ }
+
target->application = obj;
obj = NULL;
@@ -390,6 +461,48 @@ fail:
}
+nxt_inline nxt_int_t
+nxt_python_set_prefix(nxt_task_t *task, nxt_python_target_t *target,
+ nxt_conf_value_t *value)
+{
+ u_char *prefix;
+ nxt_str_t str;
+
+ if (value == NULL) {
+ return NXT_OK;
+ }
+
+ nxt_conf_get_string(value, &str);
+
+ if (str.length == 0) {
+ return NXT_OK;
+ }
+
+ if (str.start[str.length - 1] == '/') {
+ str.length--;
+ }
+ target->prefix.length = str.length;
+ prefix = nxt_malloc(str.length);
+ if (nxt_slow_path(prefix == NULL)) {
+ nxt_alert(task, "Failed to allocate target prefix string");
+ return NXT_ERROR;
+ }
+
+ target->py_prefix = PyString_FromStringAndSize((char *)str.start,
+ str.length);
+ if (nxt_slow_path(target->py_prefix == NULL)) {
+ nxt_free(prefix);
+ nxt_alert(task, "Python failed to allocate target prefix "
+ "string");
+ return NXT_ERROR;
+ }
+ nxt_memcpy(prefix, str.start, str.length);
+ target->prefix.start = prefix;
+
+ return NXT_OK;
+}
+
+
static nxt_int_t
nxt_python_set_path(nxt_task_t *task, nxt_conf_value_t *value)
{
@@ -667,7 +780,8 @@ nxt_python_done_strings(nxt_python_string_t *pstr)
static void
nxt_python_atexit(void)
{
- nxt_int_t i;
+ nxt_int_t i;
+ nxt_python_target_t *target;
if (nxt_py_proto.done != NULL) {
nxt_py_proto.done();
@@ -677,7 +791,12 @@ nxt_python_atexit(void)
if (nxt_py_targets != NULL) {
for (i = 0; i < nxt_py_targets->count; i++) {
- Py_XDECREF(nxt_py_targets->target[i].application);
+ target = &nxt_py_targets->target[i];
+
+ Py_XDECREF(target->application);
+ Py_XDECREF(target->py_prefix);
+
+ nxt_free(target->prefix.start);
}
nxt_unit_free(NULL, nxt_py_targets);