static int Adapter_run(AdapterObject *self, PyObject *object)
{
    PyObject *vars = NULL;
    PyObject *start = NULL;
    PyObject *args = NULL;
    PyObject *iterator = NULL;
    PyObject *close = NULL;

    const char *msg = NULL;
    int length = 0;

#if defined(MOD_WSGI_WITH_DAEMONS)
    if (wsgi_inactivity_timeout) {
        apr_thread_mutex_lock(wsgi_shutdown_lock);
        wsgi_inactivity_shutdown_time = apr_time_now();
        wsgi_inactivity_shutdown_time += wsgi_inactivity_timeout;
        apr_thread_mutex_unlock(wsgi_shutdown_lock);
    }
#endif

    vars = Adapter_environ(self);

    start = PyObject_GetAttrString((PyObject *)self, "start_response");

    args = Py_BuildValue("(OO)", vars, start);

    self->sequence = PyEval_CallObject(object, args);

    if (self->sequence != NULL) {
        if (!Adapter_process_file_wrapper(self)) {
            int aborted = 0;

            iterator = PyObject_GetIter(self->sequence);

            if (iterator != NULL) {
                PyObject *item = NULL;

                while ((item = PyIter_Next(iterator))) {
#if PY_MAJOR_VERSION >= 3
                    if (PyUnicode_Check(item)) {
                        PyObject *latin_item;
                        latin_item = PyUnicode_AsLatin1String(item);
                        if (!latin_item) {
                            PyErr_Format(PyExc_TypeError, "sequence of "
                                         "byte string values expected, value "
                                         "containing non 'latin-1' characters "
                                         "found");
                            Py_DECREF(item);
                            break;
                        }

                        Py_DECREF(item);
                        item = latin_item;
                    }
#endif

                    if (!PyString_Check(item)) {
                        PyErr_Format(PyExc_TypeError, "sequence of byte "
                                     "string values expected, value of "
                                     "type %.200s found",
                                     item->ob_type->tp_name);
                        Py_DECREF(item);
                        break;
                    }

                    msg = PyString_AsString(item);
                    length = PyString_Size(item);

                    if (!msg) {
                        Py_DECREF(item);
                        break;
                    }

                    if (length && !Adapter_output(self, msg, length, 0)) {
                        if (!PyErr_Occurred())
                            aborted = 1;
                        Py_DECREF(item);
                        break;
                    }

                    Py_DECREF(item);
                }
            }

            if (!PyErr_Occurred() && !aborted) {
                if (Adapter_output(self, "", 0, 0))
                    self->result = OK;
            }

            Py_XDECREF(iterator);
        }

        /*
         * Log warning if more response content generated than was
         * indicated, or less if there was no errors generated by
         * the application.
         */

        if (self->content_length_set && ((!PyErr_Occurred() &&
            self->output_length != self->content_length) ||
            (self->output_length > self->content_length))) {
            ap_log_rerror(APLOG_MARK, WSGI_LOG_DEBUG(0), self->r,
                          "mod_wsgi (pid=%d): Content length mismatch, "
                          "expected %s, response generated %s: %s", getpid(),
                          apr_off_t_toa(self->r->pool, self->content_length),
                          apr_off_t_toa(self->r->pool, self->output_length),
                          self->r->filename);
        }

        if (PyErr_Occurred()) {
            /*
             * Response content has already been sent, so cannot
             * return an internal server error as Apache will
             * append its own error page. Thus need to return OK
             * and just truncate the response.
             */

            if (self->status_line && !self->headers)
                self->result = OK;

            wsgi_log_python_error(self->r, self->log, self->r->filename);
        }

        if (PyObject_HasAttrString(self->sequence, "close")) {
            PyObject *args = NULL;
            PyObject *data = NULL;

            close = PyObject_GetAttrString(self->sequence, "close");

            args = Py_BuildValue("()");
            data = PyEval_CallObject(close, args);

            Py_DECREF(args);
            Py_XDECREF(data);
            Py_DECREF(close);
        }

        if (PyErr_Occurred())
            wsgi_log_python_error(self->r, self->log, self->r->filename);

        Py_DECREF(self->sequence);

        self->sequence = NULL;
    }

    Py_DECREF(args);
    Py_DECREF(start);
    Py_DECREF(vars);

    /* Log details of any final Python exceptions. */

    if (PyErr_Occurred())
        wsgi_log_python_error(self->r, self->log, self->r->filename);

    /*
     * If result indicates an internal server error, then
     * replace the status line in the request object else
     * that provided by the application will be what is used
     * in any error page automatically generated by Apache.
     */

    if (self->result == HTTP_INTERNAL_SERVER_ERROR)
        self->r->status_line = "500 Internal Server Error";

    return self->result;
}
Unknown