コード例 #1
0
ファイル: web_server.c プロジェクト: Lxg1582/netdata
void *socket_listen_main_single_threaded(void *ptr) {
	(void)ptr;

	web_server_mode = WEB_SERVER_MODE_SINGLE_THREADED;

	info("Single threaded WEB SERVER thread created with task id %d", gettid());

	struct web_client *w;
	int retval, failures = 0;

	if(ptr) { ; }

	if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
		error("Cannot set pthread cancel type to DEFERRED.");

	if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
		error("Cannot set pthread cancel state to ENABLE.");

	if(listen_fd < 0 || listen_fd >= FD_SETSIZE)
		fatal("LISTENER: Listen socket %d is not ready, or invalid.", listen_fd);

	int i;
	for(i = 0; i < FD_SETSIZE ; i++)
		single_threaded_clients[i] = NULL;

	fd_set ifds, ofds, efds, rifds, rofds, refds;
	FD_ZERO (&ifds);
	FD_ZERO (&ofds);
	FD_ZERO (&efds);
	FD_SET(listen_fd, &ifds);
	FD_SET(listen_fd, &efds);
	int fdmax = listen_fd;

	for(;;) {
		debug(D_WEB_CLIENT_ACCESS, "LISTENER: single threaded web server waiting (listen fd = %d, fdmax = %d)...", listen_fd, fdmax);

		struct timeval tv = { .tv_sec = 1, .tv_usec = 0 };
		rifds = ifds;
		rofds = ofds;
		refds = efds;
		retval = select(fdmax+1, &rifds, &rofds, &refds, &tv);

		if(unlikely(retval == -1)) {
			debug(D_WEB_CLIENT, "LISTENER: select() failed.");
			failures++;
			if(failures > 10) {
				if(global_statistics.connected_clients) {
					error("REMOVING ALL %lu WEB CLIENTS !", global_statistics.connected_clients);
					while (web_clients) {
						single_threaded_unlink_client(web_clients, &ifds, &ofds, &efds);
						web_client_free(web_clients);
					}
				}

				error("LISTENER: our listen port %d seems dead. Re-opening it.", listen_fd);

				close(listen_fd);
				listen_fd = -1;
				sleep(5);

				create_listen_socket();
				if(listen_fd < 0 || listen_fd >= FD_SETSIZE)
					fatal("Cannot listen for web clients (connected clients %llu).", global_statistics.connected_clients);

				FD_ZERO (&ifds);
				FD_ZERO (&ofds);
				FD_ZERO (&efds);
				FD_SET(listen_fd, &ifds);
				FD_SET(listen_fd, &efds);
				failures = 0;
			}
		}
		else if(likely(retval)) {
			failures = 0;
			debug(D_WEB_CLIENT_ACCESS, "LISTENER: got something.");

			if(FD_ISSET(listen_fd, &rifds)) {
				debug(D_WEB_CLIENT_ACCESS, "LISTENER: new connection.");
				w = web_client_create(listen_fd);
				if(single_threaded_link_client(w, &ifds, &ofds, &ifds, &fdmax) != 0) {
					web_client_free(w);
				}
			}

			for(i = 0 ; i <= fdmax ; i++) {
				if(likely(!FD_ISSET(i, &rifds) && !FD_ISSET(i, &rofds) && !FD_ISSET(i, &refds)))
					continue;

				w = single_threaded_clients[i];
				if(unlikely(!w))
					continue;

				if(unlikely(single_threaded_unlink_client(w, &ifds, &ofds, &efds) != 0)) {
					web_client_free(w);
					continue;
				}

				if (unlikely(FD_ISSET(w->ifd, &refds) || FD_ISSET(w->ofd, &refds))) {
					web_client_free(w);
					continue;
				}

				if (unlikely(w->wait_receive && FD_ISSET(w->ifd, &rifds))) {
					if (unlikely(web_client_receive(w) < 0)) {
						web_client_free(w);
						continue;
					}

					if (w->mode != WEB_CLIENT_MODE_FILECOPY) {
						debug(D_WEB_CLIENT, "%llu: Processing received data.", w->id);
						web_client_process(w);
					}
				}

				if (unlikely(w->wait_send && FD_ISSET(w->ofd, &rofds))) {
					if (unlikely(web_client_send(w) < 0)) {
						debug(D_WEB_CLIENT, "%llu: Cannot send data to client. Closing client.", w->id);
						web_client_free(w);
						continue;
					}
				}

				if(unlikely(single_threaded_link_client(w, &ifds, &ofds, &efds, &fdmax) != 0)) {
					web_client_free(w);
				}
			}
		}
		else {
			debug(D_WEB_CLIENT_ACCESS, "LISTENER: single threaded web server timeout.");
#ifdef NETDATA_INTERNAL_CHECKS
			log_allocations();
#endif
		}
	}

	debug(D_WEB_CLIENT, "LISTENER: exit!");
	close(listen_fd);
	listen_fd = -1;
	return NULL;
}
コード例 #2
0
ファイル: web_server.c プロジェクト: 4224657/netdata
void *socket_listen_main_single_threaded(void *ptr) {
	(void)ptr;

	web_server_mode = WEB_SERVER_MODE_SINGLE_THREADED;

	info("Single-threaded WEB SERVER thread created with task id %d", gettid());

	struct web_client *w;
	int retval;

	if(ptr) { ; }

	if(pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL) != 0)
		error("Cannot set pthread cancel type to DEFERRED.");

	if(pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0)
		error("Cannot set pthread cancel state to ENABLE.");

	int i;

	if(!listen_fds_count)
		fatal("LISTENER: no listen sockets available.");

	for(i = 0; i < FD_SETSIZE ; i++)
		single_threaded_clients[i] = NULL;

	fd_set ifds, ofds, efds, rifds, rofds, refds;
	FD_ZERO (&ifds);
	FD_ZERO (&ofds);
	FD_ZERO (&efds);
	int fdmax = 0;

	for(i = 0; i < listen_fds_count ; i++) {
		if (listen_fds[i] < 0 || listen_fds[i] >= FD_SETSIZE)
			fatal("LISTENER: Listen socket %d is not ready, or invalid.", listen_fds[i]);

        info("Listening on '%s'", (listen_fds_names[i])?listen_fds_names[i]:"UNKNOWN");

		FD_SET(listen_fds[i], &ifds);
		FD_SET(listen_fds[i], &efds);
		if(fdmax < listen_fds[i])
            fdmax = listen_fds[i];
	}

	for(;;) {
		debug(D_WEB_CLIENT_ACCESS, "LISTENER: single threaded web server waiting (fdmax = %d)...", fdmax);

		struct timeval tv = { .tv_sec = 1, .tv_usec = 0 };
		rifds = ifds;
		rofds = ofds;
		refds = efds;
		retval = select(fdmax+1, &rifds, &rofds, &refds, &tv);

		if(unlikely(retval == -1)) {
			error("LISTENER: select() failed.");
			continue;
		}
		else if(likely(retval)) {
			debug(D_WEB_CLIENT_ACCESS, "LISTENER: got something.");

			for(i = 0; i < listen_fds_count ; i++) {
				if (FD_ISSET(listen_fds[i], &rifds)) {
					debug(D_WEB_CLIENT_ACCESS, "LISTENER: new connection.");
					w = web_client_create(listen_fds[i]);
					if (single_threaded_link_client(w, &ifds, &ofds, &ifds, &fdmax) != 0) {
						web_client_free(w);
					}
				}
			}

			for(i = 0 ; i <= fdmax ; i++) {
				if(likely(!FD_ISSET(i, &rifds) && !FD_ISSET(i, &rofds) && !FD_ISSET(i, &refds)))
					continue;

				w = single_threaded_clients[i];
				if(unlikely(!w))
					continue;

				if(unlikely(single_threaded_unlink_client(w, &ifds, &ofds, &efds) != 0)) {
					web_client_free(w);
					continue;
				}

				if (unlikely(FD_ISSET(w->ifd, &refds) || FD_ISSET(w->ofd, &refds))) {
					web_client_free(w);
					continue;
				}

				if (unlikely(w->wait_receive && FD_ISSET(w->ifd, &rifds))) {
					if (unlikely(web_client_receive(w) < 0)) {
						web_client_free(w);
						continue;
					}

					if (w->mode != WEB_CLIENT_MODE_FILECOPY) {
						debug(D_WEB_CLIENT, "%llu: Processing received data.", w->id);
						web_client_process(w);
					}
				}

				if (unlikely(w->wait_send && FD_ISSET(w->ofd, &rofds))) {
					if (unlikely(web_client_send(w) < 0)) {
						debug(D_WEB_CLIENT, "%llu: Cannot send data to client. Closing client.", w->id);
						web_client_free(w);
						continue;
					}
				}

				if(unlikely(single_threaded_link_client(w, &ifds, &ofds, &efds, &fdmax) != 0)) {
					web_client_free(w);
				}
			}
		}
		else {
			debug(D_WEB_CLIENT_ACCESS, "LISTENER: single threaded web server timeout.");
#ifdef NETDATA_INTERNAL_CHECKS
			log_allocations();
#endif
		}
	}

	debug(D_WEB_CLIENT, "LISTENER: exit!");
    close_listen_sockets();
	return NULL;
}