File: fifo.c

package info (click to toggle)
uwsgi 2.0.31-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 6,564 kB
  • sloc: ansic: 87,066; python: 7,004; cpp: 1,133; java: 708; perl: 678; sh: 585; ruby: 555; makefile: 148; xml: 130; cs: 121; objc: 37; php: 28; erlang: 20; javascript: 11
file content (149 lines) | stat: -rw-r--r-- 4,722 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include "uwsgi.h"

extern struct uwsgi_server uwsgi;

/*

	the --master-fifo option create a unix named pipe (fifo) you can use to send management
	commands to the master:

	echo r > myfifo

*/

// this var can be accessed by plugins and hooks
void (*uwsgi_fifo_table[256])(int);

static char *uwsgi_fifo_by_slot() {
	int count = 0;
	struct uwsgi_string_list *usl;
	uwsgi_foreach(usl, uwsgi.master_fifo) {
		if (count == uwsgi.master_fifo_slot) return usl->value;
		count++;
	}
	return uwsgi.master_fifo->value;
}

#define announce_fifo uwsgi_log_verbose("active master fifo is now %s\n", uwsgi_fifo_by_slot())

static void uwsgi_fifo_set_slot_zero(int signum) { uwsgi.master_fifo_slot = 0; announce_fifo; }
static void uwsgi_fifo_set_slot_one(int signum) { uwsgi.master_fifo_slot = 1; announce_fifo; }
static void uwsgi_fifo_set_slot_two(int signum) { uwsgi.master_fifo_slot = 2; announce_fifo; }
static void uwsgi_fifo_set_slot_three(int signum) { uwsgi.master_fifo_slot = 3; announce_fifo; }
static void uwsgi_fifo_set_slot_four(int signum) { uwsgi.master_fifo_slot = 4; announce_fifo; }
static void uwsgi_fifo_set_slot_five(int signum) { uwsgi.master_fifo_slot = 5; announce_fifo; }
static void uwsgi_fifo_set_slot_six(int signum) { uwsgi.master_fifo_slot = 6; announce_fifo; }
static void uwsgi_fifo_set_slot_seven(int signum) { uwsgi.master_fifo_slot = 7; announce_fifo; }
static void uwsgi_fifo_set_slot_eight(int signum) { uwsgi.master_fifo_slot = 8; announce_fifo; }
static void uwsgi_fifo_set_slot_nine(int signum) { uwsgi.master_fifo_slot = 9; announce_fifo; }

static void subscriptions_blocker(int signum) {
	if (uwsgi.subscriptions_blocked) {
		uwsgi_log_verbose("subscriptions re-enabled\n");
		uwsgi.subscriptions_blocked = 0;
	}
	else {
		uwsgi.subscriptions_blocked = 1;
		uwsgi_log_verbose("subscriptions blocked\n");
	}
}

static void emperor_rescan(int signum) {
	if (uwsgi.emperor_pid > 0) {
		if (kill(uwsgi.emperor_pid, SIGWINCH)) {
			uwsgi_error("emperor_rescan()/kill()");
		}
	}
}

/*

this is called as soon as possibile allowing plugins (or hooks) to override it

*/
void uwsgi_master_fifo_prepare() {
	int i;
	for(i=0;i<256;i++) {
		uwsgi_fifo_table[i] = NULL;
	}

	uwsgi_fifo_table['0'] = uwsgi_fifo_set_slot_zero;
	uwsgi_fifo_table['1'] = uwsgi_fifo_set_slot_one;
	uwsgi_fifo_table['2'] = uwsgi_fifo_set_slot_two;
	uwsgi_fifo_table['3'] = uwsgi_fifo_set_slot_three;
	uwsgi_fifo_table['4'] = uwsgi_fifo_set_slot_four;
	uwsgi_fifo_table['5'] = uwsgi_fifo_set_slot_five;
	uwsgi_fifo_table['6'] = uwsgi_fifo_set_slot_six;
	uwsgi_fifo_table['7'] = uwsgi_fifo_set_slot_seven;
	uwsgi_fifo_table['8'] = uwsgi_fifo_set_slot_eight;
	uwsgi_fifo_table['9'] = uwsgi_fifo_set_slot_nine;

	uwsgi_fifo_table['-'] = (void (*)(int))uwsgi_cheaper_decrease;
	uwsgi_fifo_table['+'] = (void (*)(int))uwsgi_cheaper_increase;
	uwsgi_fifo_table['B'] = (void (*)(int))vassal_sos;
	uwsgi_fifo_table['c'] = (void (*)(int))uwsgi_chain_reload;
	uwsgi_fifo_table['C'] = (void (*)(int))uwsgi_go_cheap;
	uwsgi_fifo_table['E'] = emperor_rescan;
	uwsgi_fifo_table['f'] = (void (*)(int))uwsgi_refork_master;
	uwsgi_fifo_table['l'] = (void (*)(int))uwsgi_log_reopen;
	uwsgi_fifo_table['L'] = (void (*)(int))uwsgi_log_rotate;
	uwsgi_fifo_table['p'] = suspend_resume_them_all;
	uwsgi_fifo_table['P'] = (void (*)(int))uwsgi_update_pidfiles;
	uwsgi_fifo_table['q'] = gracefully_kill_them_all;
	uwsgi_fifo_table['Q'] = kill_them_all;
	uwsgi_fifo_table['r'] = grace_them_all;
	uwsgi_fifo_table['R'] = reap_them_all;
	uwsgi_fifo_table['s'] = stats;
	uwsgi_fifo_table['S'] = subscriptions_blocker;
	uwsgi_fifo_table['w'] = (void (*)(int))uwsgi_reload_workers;
	uwsgi_fifo_table['W'] = (void (*)(int))uwsgi_brutally_reload_workers;

}

int uwsgi_master_fifo() {

	char *path = uwsgi_fifo_by_slot();

	if (unlink(path) != 0 && errno != ENOENT) {
		uwsgi_error("uwsgi_master_fifo()/unlink()");
	}

	if (mkfifo(path, S_IRUSR|S_IWUSR)) {
		uwsgi_error("uwsgi_master_fifo()/mkfifo()");
		exit(1);
	}

	int fd = open(path, O_RDONLY|O_NONBLOCK);
	if (fd < 0) {
		uwsgi_error("uwsgi_master_fifo()/open()");
		exit(1);
	}

	uwsgi_socket_nb(fd);

	return fd;
}

int uwsgi_master_fifo_manage(int fd) {
	unsigned char cmd;
	ssize_t rlen = read(fd, &cmd, 1);
	if (rlen < 0) {
		if (uwsgi_is_again()) return 0;
		uwsgi_error("uwsgi_master_fifo_manage()/read()");
		exit(1);
	}
	// fifo destroyed, recreate it
	else if (rlen == 0) {
		event_queue_del_fd(uwsgi.master_queue, uwsgi.master_fifo_fd, event_queue_read());
		close(fd);
		uwsgi.master_fifo_fd = uwsgi_master_fifo();
		event_queue_add_fd_read(uwsgi.master_queue, uwsgi.master_fifo_fd);
		return 0;
	}

	if (uwsgi_fifo_table[(int) cmd]) {
		uwsgi_fifo_table[(int) cmd](0);
	}
	
	return 0;
}