mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-08-18 11:39:05 +00:00
158 lines
3.6 KiB
C
158 lines
3.6 KiB
C
/*
|
|
|
|
uWSGI zergpool
|
|
|
|
*/
|
|
|
|
#include "../../uwsgi.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
|
|
struct uwsgi_string_list *zergpool_socket_names;
|
|
|
|
#define ZERGPOOL_EVENTS 64
|
|
|
|
struct uwsgi_option zergpool_options[] = {
|
|
{ "zergpool", required_argument, 0, "start a zergpool on specified address for specified address", uwsgi_opt_add_string_list, &zergpool_socket_names, 0},
|
|
{ "zerg-pool", required_argument, 0, "start a zergpool on specified address for specified address", uwsgi_opt_add_string_list, &zergpool_socket_names, 0},
|
|
{0, 0, 0, 0, 0, 0, 0},
|
|
};
|
|
|
|
struct zergpool_socket {
|
|
int fd;
|
|
int *sockets;
|
|
int num_sockets;
|
|
|
|
struct zergpool_socket *next;
|
|
};
|
|
|
|
struct zergpool_socket *zergpool_sockets;
|
|
|
|
void zergpool_loop(int id, void *foobar) {
|
|
|
|
int i;
|
|
|
|
int zergpool_queue = event_queue_init();
|
|
|
|
void *events = event_queue_alloc(ZERGPOOL_EVENTS);
|
|
|
|
struct zergpool_socket *zps = zergpool_sockets;
|
|
while(zps) {
|
|
event_queue_add_fd_read(zergpool_queue, zps->fd);
|
|
zps = zps->next;
|
|
}
|
|
|
|
for(;;) {
|
|
int nevents = event_queue_wait_multi(zergpool_queue, -1, events, ZERGPOOL_EVENTS);
|
|
|
|
for(i=0;i<nevents;i++) {
|
|
|
|
int interesting_fd = event_queue_interesting_fd(events, i);
|
|
|
|
zps = zergpool_sockets;
|
|
while(zps) {
|
|
if (zps->fd == interesting_fd) {
|
|
uwsgi_manage_zerg(zps->fd, zps->num_sockets, zps->sockets);
|
|
}
|
|
zps = zps->next;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct zergpool_socket *add_zergpool_socket(char *name, char *sockets) {
|
|
|
|
struct zergpool_socket *z_sock,*zps = zergpool_sockets;
|
|
|
|
if (!zps) {
|
|
z_sock = uwsgi_calloc(sizeof(struct zergpool_socket));
|
|
zergpool_sockets = z_sock;
|
|
}
|
|
else {
|
|
while(zps) {
|
|
if (!zps->next) {
|
|
z_sock= uwsgi_calloc(sizeof(struct zergpool_socket));
|
|
zps->next = z_sock;
|
|
break;
|
|
}
|
|
zps = zps->next;
|
|
}
|
|
}
|
|
|
|
|
|
// do not defer accept for zergpools
|
|
if (uwsgi.no_defer_accept) {
|
|
uwsgi.no_defer_accept = 0;
|
|
z_sock->fd = bind_to_unix(name, uwsgi.listen_queue, uwsgi.chmod_socket, 0);
|
|
uwsgi.no_defer_accept = 1;
|
|
}
|
|
else {
|
|
z_sock->fd = bind_to_unix(name, uwsgi.listen_queue, uwsgi.chmod_socket, 0);
|
|
}
|
|
|
|
char *sock_list = uwsgi_str(sockets);
|
|
char *p, *ctx = NULL;
|
|
uwsgi_foreach_token(sock_list, ",", p, ctx) {
|
|
z_sock->num_sockets++;
|
|
}
|
|
free(sock_list);
|
|
z_sock->sockets = uwsgi_calloc(sizeof(int) * (z_sock->num_sockets + 1));
|
|
|
|
sock_list = uwsgi_str(sockets);
|
|
int pos = 0;
|
|
ctx = NULL;
|
|
uwsgi_foreach_token(sock_list, ",", p, ctx) {
|
|
char *port = strchr(p, ':');
|
|
char *sockname;
|
|
if (!port) {
|
|
z_sock->sockets[pos] = bind_to_unix(p, uwsgi.listen_queue, uwsgi.chmod_socket, uwsgi.abstract_socket);
|
|
sockname = uwsgi_getsockname(z_sock->sockets[pos]);
|
|
uwsgi_log("zergpool %s bound to UNIX socket %s (fd: %d)\n", name, sockname, z_sock->sockets[pos]);
|
|
}
|
|
else {
|
|
char *gsn = generate_socket_name(p);
|
|
z_sock->sockets[pos] = bind_to_tcp(gsn, uwsgi.listen_queue, strchr(gsn, ':'));
|
|
sockname = uwsgi_getsockname(z_sock->sockets[pos]);
|
|
uwsgi_log("zergpool %s bound to TCP socket %s (fd: %d)\n", name, sockname, z_sock->sockets[pos]);
|
|
}
|
|
pos++;
|
|
free(sockname);
|
|
}
|
|
free(sock_list);
|
|
|
|
return z_sock;
|
|
}
|
|
|
|
int zergpool_init() {
|
|
|
|
if (!zergpool_socket_names) return 0;
|
|
|
|
struct uwsgi_string_list *zpsn = zergpool_socket_names;
|
|
while(zpsn) {
|
|
char *colon = strchr(zpsn->value, ':');
|
|
if (!colon) {
|
|
uwsgi_log("invalid zergpool syntax: %s\n", zpsn->value);
|
|
exit(1);
|
|
}
|
|
*colon = 0;
|
|
add_zergpool_socket(zpsn->value, colon+1);
|
|
*colon = ':';
|
|
zpsn = zpsn->next;
|
|
}
|
|
|
|
if (register_gateway("uWSGI zergpool", zergpool_loop, NULL) == NULL) {
|
|
uwsgi_log("unable to register the zergpool gateway\n");
|
|
exit(1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
struct uwsgi_plugin zergpool_plugin = {
|
|
|
|
.name = "zergpool",
|
|
.options = zergpool_options,
|
|
.init = zergpool_init,
|
|
};
|