Example #1
0
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) {

    uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
    uwsgi.workers[uwsgi.mywid].manage_next_request = 0;

    uwsgi_log_verbose("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
    PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL);
    PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL);

    uwsgi_log_verbose("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
    int i,count = uwsgi_count_sockets(uwsgi.sockets);
    for(i=0; i<count; i++) {
        PyObject_CallMethod(ugevent.watchers[i], "stop", NULL);
    }
    uwsgi_log_verbose("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);

    int running_cores = 0;
    for(i=0; i<uwsgi.async; i++) {
        if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) {
            struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[i].req;
            uwsgi_log_verbose("worker %d (pid: %d) core %d is managing \"%.*s %.*s\" for %.*s\n", uwsgi.mywid, uwsgi.mypid, i,
                              wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri,
                              wsgi_req->remote_addr_len, wsgi_req->remote_addr);
            running_cores++;
        }
    }

    if (running_cores > 0) {
        uwsgi_log_verbose("waiting for %d running requests on worker %d (pid: %d)...\n", running_cores, uwsgi.mywid, uwsgi.mypid);
    }

    Py_INCREF(Py_None);
    return Py_None;
}
Example #2
0
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) {

	int running_cores = 0;
	int rounds = 0;

	uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
        uwsgi.workers[uwsgi.mywid].manage_next_request = 0;

	uwsgi_log_verbose("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL);
	PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL);

	uwsgi_log_verbose("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	int i,count = uwsgi_count_sockets(uwsgi.sockets);
	for(i=0;i<count;i++) {
		PyObject_CallMethod(ugevent.watchers[i], "stop", NULL);
	}
	uwsgi_log_verbose("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);

retry:
	running_cores = 0;
	for(i=0;i<uwsgi.async;i++) {
		if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) {
			struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[i].req;
			if (!rounds) {
				uwsgi_log_verbose("worker %d (pid: %d) core %d is managing \"%.*s %.*s\" for %.*s\n", uwsgi.mywid, uwsgi.mypid, i, 
					wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri,
					wsgi_req->remote_addr_len, wsgi_req->remote_addr);
			}
			running_cores++;
		}
	}

	if (running_cores > 0) {
		uwsgi_log_verbose("waiting for %d running requests on worker %d (pid: %d)...\n", running_cores, uwsgi.mywid, uwsgi.mypid);
		PyObject *gevent_sleep_args = PyTuple_New(1);
		PyTuple_SetItem(gevent_sleep_args, 0, PyInt_FromLong(1));
		PyObject *gswitch = python_call(ugevent.greenlet_switch, gevent_sleep_args, 0, NULL);
		Py_DECREF(gswitch);
		Py_DECREF(gevent_sleep_args);
		rounds++;
		goto retry;
	}

	if (!ugevent.wait_for_hub) {
		PyObject_CallMethod(ugevent.ctrl_gl, "kill", NULL);
	}

	Py_INCREF(Py_None);
	return Py_None;
}
Example #3
0
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) {

	uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
        uwsgi.workers[uwsgi.mywid].manage_next_request = 0;

	uwsgi_log_verbose("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL);
	PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL);

	uwsgi_log_verbose("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	int i,count = uwsgi_count_sockets(uwsgi.sockets);
	for(i=0;i<count;i++) {
		PyObject_CallMethod(ugevent.watchers[i], "stop", NULL);
	}
	uwsgi_log_verbose("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);

	int running_cores = 0;
	for(i=0;i<uwsgi.async;i++) {
		if (uwsgi.workers[uwsgi.mywid].cores[i].in_request) {
			struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[i].req;
			uwsgi_log_verbose("worker %d (pid: %d) core %d is managing \"%.*s %.*s\" for %.*s\n", uwsgi.mywid, uwsgi.mypid, i, 
				wsgi_req->method_len, wsgi_req->method, wsgi_req->uri_len, wsgi_req->uri,
				wsgi_req->remote_addr_len, wsgi_req->remote_addr);
			running_cores++;
		}
	}

	if (running_cores > 0) {
		uwsgi_log_verbose("waiting for %d running requests on worker %d (pid: %d)...\n", running_cores, uwsgi.mywid, uwsgi.mypid);
	} else {
            // no need to worry about freeing memory
            PyObject *uwsgi_dict = get_uwsgi_pydict("uwsgi");
            if (uwsgi_dict) {
              PyObject *ae = PyDict_GetItemString(uwsgi_dict, "atexit");
              if (ae) {
                python_call(ae, PyTuple_New(0), 0, NULL);
              }
            }
        }

	Py_INCREF(Py_None);
	return Py_None;
}
Example #4
0
PyObject *py_uwsgi_gevent_int(PyObject *self, PyObject *args) {

        uwsgi_log("Brutally killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
        uwsgi.workers[uwsgi.mywid].manage_next_request = 0;

        uwsgi_log_verbose("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
        PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL);
        PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL);

        uwsgi_log_verbose("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
        int i,count = uwsgi_count_sockets(uwsgi.sockets);
        for(i=0;i<count;i++) {
                PyObject_CallMethod(ugevent.watchers[i], "stop", NULL);
        }
        uwsgi_log_verbose("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);

        if (!ugevent.wait_for_hub) {
                PyObject_CallMethod(ugevent.ctrl_gl, "kill", NULL);
        }

        Py_INCREF(Py_None);
        return Py_None;
}
Example #5
0
PyObject *py_uwsgi_gevent_graceful(PyObject *self, PyObject *args) {

	uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
        uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
	
	uwsgi_log("stopping gevent signals watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	PyObject_CallMethod(ugevent.my_signal_watcher, "stop", NULL);
	PyObject_CallMethod(ugevent.signal_watcher, "stop", NULL);

	uwsgi_log("stopping gevent sockets watchers for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
	int i,count = uwsgi_count_sockets(uwsgi.sockets);
	for(i=0;i<count;i++) {
		PyObject_CallMethod(ugevent.watchers[i], "stop", NULL);
	}
	uwsgi_log("main gevent watchers stopped for worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);

	if (args) {
		exit(UWSGI_RELOAD_CODE);
	}

	Py_INCREF(Py_None);
	return Py_None;
}
Example #6
0
static void gevent_loop() {

    if (!uwsgi.has_threads && uwsgi.mywid == 1) {
        uwsgi_log("!!! Running gevent without threads IS NOT recommended, enable them with --enable-threads !!!\n");
    }

    if (uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT] < 30) {
        uwsgi_log("!!! Running gevent with a socket-timeout lower than 30 seconds is not recommended, tune it with --socket-timeout !!!\n");
    }

    // get the GIL
    UWSGI_GET_GIL

    up.gil_get = gil_gevent_get;
    up.gil_release = gil_gevent_release;

    uwsgi.wait_write_hook = uwsgi_gevent_wait_write_hook;
    uwsgi.wait_read_hook = uwsgi_gevent_wait_read_hook;

    struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;

    if (uwsgi.async < 2) {
        uwsgi_log("the gevent loop engine requires async mode (--async <n>)\n");
        exit(1);
    }

    uwsgi.current_wsgi_req = uwsgi_gevent_current_wsgi_req;

    PyObject *gevent_dict = get_uwsgi_pydict("gevent");
    if (!gevent_dict) uwsgi_pyexit;

    PyObject *gevent_version = PyDict_GetItemString(gevent_dict, "version_info");
    if (!gevent_version) uwsgi_pyexit;

    if (PyInt_AsLong(PyTuple_GetItem(gevent_version, 0)) < 1) {
        uwsgi_log("uWSGI requires at least gevent 1.x version\n");
        exit(1);
    }

    ugevent.spawn = PyDict_GetItemString(gevent_dict, "spawn");
    if (!ugevent.spawn) uwsgi_pyexit;

    ugevent.signal = PyDict_GetItemString(gevent_dict, "signal");
    if (!ugevent.signal) uwsgi_pyexit;

    ugevent.greenlet_switch = PyDict_GetItemString(gevent_dict, "sleep");
    if (!ugevent.greenlet_switch) uwsgi_pyexit;

    ugevent.greenlet_switch_args = PyTuple_New(0);
    Py_INCREF(ugevent.greenlet_switch_args);


    PyObject *gevent_get_hub = PyDict_GetItemString(gevent_dict, "get_hub");

    ugevent.hub = python_call(gevent_get_hub, PyTuple_New(0), 0, NULL);
    if (!ugevent.hub) uwsgi_pyexit;

    ugevent.get_current = PyDict_GetItemString(gevent_dict, "getcurrent");
    if (!ugevent.get_current) uwsgi_pyexit;

    ugevent.get_current_args = PyTuple_New(0);
    Py_INCREF(ugevent.get_current_args);


    ugevent.hub_loop = PyObject_GetAttrString(ugevent.hub, "loop");
    if (!ugevent.hub_loop) uwsgi_pyexit;

    // main greenlet waiting for connection (one greenlet per-socket)
    PyObject *uwsgi_gevent_main = PyCFunction_New(uwsgi_gevent_main_def, NULL);
    Py_INCREF(uwsgi_gevent_main);

    // greenlet to run at each request
    PyObject *uwsgi_request_greenlet = PyCFunction_New(uwsgi_gevent_request_def, NULL);
    Py_INCREF(uwsgi_request_greenlet);

    // pre-fill the greenlet args
    ugevent.greenlet_args = PyTuple_New(2);
    PyTuple_SetItem(ugevent.greenlet_args, 0, uwsgi_request_greenlet);

    if (uwsgi.signal_socket > -1) {
        // and these are the watcher for signal sockets

        ugevent.signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.signal_socket, 1);
        if (!ugevent.signal_watcher) uwsgi_pyexit;

        ugevent.my_signal_watcher = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi.my_signal_socket, 1);
        if (!ugevent.my_signal_watcher) uwsgi_pyexit;

        PyObject *uwsgi_greenlet_signal = PyCFunction_New(uwsgi_gevent_signal_def, NULL);
        Py_INCREF(uwsgi_greenlet_signal);

        PyObject *uwsgi_greenlet_my_signal = PyCFunction_New(uwsgi_gevent_my_signal_def, NULL);
        Py_INCREF(uwsgi_greenlet_my_signal);

        PyObject *uwsgi_greenlet_signal_handler = PyCFunction_New(uwsgi_gevent_signal_handler_def, NULL);
        Py_INCREF(uwsgi_greenlet_signal_handler);

        ugevent.signal_args = PyTuple_New(2);
        PyTuple_SetItem(ugevent.signal_args, 0, uwsgi_greenlet_signal_handler);

        // start the two signal watchers
        if (!PyObject_CallMethod(ugevent.signal_watcher, "start", "O", uwsgi_greenlet_signal)) uwsgi_pyexit;
        if (!PyObject_CallMethod(ugevent.my_signal_watcher, "start", "O", uwsgi_greenlet_my_signal)) uwsgi_pyexit;

    }

    // start a greenlet for each socket
    ugevent.watchers = uwsgi_malloc(sizeof(PyObject *) * uwsgi_count_sockets(uwsgi.sockets));
    int i = 0;
    while(uwsgi_sock) {
        // this is the watcher for server socket
        ugevent.watchers[i] = PyObject_CallMethod(ugevent.hub_loop, "io", "ii", uwsgi_sock->fd, 1);
        if (!ugevent.watchers[i]) uwsgi_pyexit;

        // start the main greenlet
        PyObject_CallMethod(ugevent.watchers[i], "start", "Ol", uwsgi_gevent_main,(long)uwsgi_sock);
        uwsgi_sock = uwsgi_sock->next;
        i++;
    }

    // patch goodbye_cruel_world
    uwsgi.gbcw_hook = uwsgi_gevent_gbcw;

    // map SIGHUP with gevent.signal
    PyObject *ge_signal_tuple = PyTuple_New(2);
    PyTuple_SetItem(ge_signal_tuple, 0, PyInt_FromLong(SIGHUP));
    PyObject *uwsgi_gevent_unix_signal_handler = PyCFunction_New(uwsgi_gevent_unix_signal_handler_def, NULL);
    Py_INCREF(uwsgi_gevent_unix_signal_handler);
    PyTuple_SetItem(ge_signal_tuple, 1, uwsgi_gevent_unix_signal_handler);

    python_call(ugevent.signal, ge_signal_tuple, 0, NULL);

    for(;;) {
        if (!PyObject_CallMethod(ugevent.hub, "join", NULL)) {
            PyErr_Print();
        }
        else {
            break;
        }
    }

    if (uwsgi.workers[uwsgi.mywid].manage_next_request == 0) {
        uwsgi_log("goodbye to the gevent Hub on worker %d (pid: %d)\n", uwsgi.mywid, uwsgi.mypid);
        if (ugevent.destroy) {
            exit(0);
        }
        exit(UWSGI_RELOAD_CODE);
    }

    uwsgi_log("the gevent Hub is no more :(\n");

}
Example #7
0
void uwsgi_manage_zerg(int fd, int num_sockets, int *sockets) {
	struct sockaddr_un zsun;
	socklen_t zsun_len = sizeof(struct sockaddr_un);

	int zerg_client = accept(fd, (struct sockaddr *) &zsun, &zsun_len);
	if (zerg_client < 0) {
		uwsgi_error("zerg: accept()");
		return;
	}

	if (!num_sockets) {
		num_sockets = uwsgi_count_sockets(uwsgi.sockets);
	}

	struct msghdr zerg_msg;
	void *zerg_msg_control = uwsgi_malloc(CMSG_SPACE(sizeof(int) * num_sockets));
	struct iovec zerg_iov[2];
	struct cmsghdr *cmsg;

	zerg_iov[0].iov_base = "uwsgi-zerg";
	zerg_iov[0].iov_len = 10;
	zerg_iov[1].iov_base = &num_sockets;
	zerg_iov[1].iov_len = sizeof(int);

	zerg_msg.msg_name = NULL;
	zerg_msg.msg_namelen = 0;

	zerg_msg.msg_iov = zerg_iov;
	zerg_msg.msg_iovlen = 2;

	zerg_msg.msg_flags = 0;
	zerg_msg.msg_control = zerg_msg_control;
	zerg_msg.msg_controllen = CMSG_SPACE(sizeof(int) * num_sockets);

	cmsg = CMSG_FIRSTHDR(&zerg_msg);
	cmsg->cmsg_len = CMSG_LEN(sizeof(int) * num_sockets);
	cmsg->cmsg_level = SOL_SOCKET;
	cmsg->cmsg_type = SCM_RIGHTS;

	unsigned char *zerg_fd_ptr = CMSG_DATA(cmsg);

	if (!sockets) {
		struct uwsgi_socket *uwsgi_sock = uwsgi.sockets;
		int uniq_count = 0;
		while (uwsgi_sock) {
			if (uwsgi_sock->fd == -1)
				goto nextsock;
			if (!uwsgi_socket_uniq(uwsgi.sockets, uwsgi_sock)) {
				memcpy(zerg_fd_ptr, &uwsgi_sock->fd, sizeof(int));
				zerg_fd_ptr += sizeof(int);
				uniq_count++;
			}
nextsock:
			uwsgi_sock = uwsgi_sock->next;
		}
		zerg_iov[1].iov_base = &uniq_count;
		cmsg->cmsg_len = CMSG_LEN(sizeof(int) * uniq_count);
	}
	else {
		memcpy(zerg_fd_ptr, sockets, sizeof(int) * num_sockets);
	}

	if (sendmsg(zerg_client, &zerg_msg, 0) < 0) {
		uwsgi_error("sendmsg()");
	}

	free(zerg_msg_control);

	close(zerg_client);

}