implemented simple idle timeout on the server.
added --shutwr to the sample client code
This commit is contained in:
		| @ -666,10 +666,11 @@ static int feed_reply_data (hcl_client_t* client, const hcl_bch_t* data, hcl_oow | |||||||
| 			} | 			} | ||||||
|  |  | ||||||
| 			ptr += taken; | 			ptr += taken; | ||||||
| 			client->rep.u.length_bounded_data.tally = taken; | 			client->rep.u.length_bounded_data.tally += taken; | ||||||
| 			if (taken == capa) | 			if (taken == capa) | ||||||
| 			{ | 			{ | ||||||
| 				/* read all data. no more */ | 				/* read all data. no more */ | ||||||
|  | 				HCL_ASSERT (client->dummy_hcl, client->rep.u.length_bounded_data.max == client->rep.u.length_bounded_data.tally); | ||||||
| 				client->state = HCL_CLIENT_STATE_START; | 				client->state = HCL_CLIENT_STATE_START; | ||||||
| 				if (client->prim.end_reply(client, HCL_CLIENT_END_REPLY_STATE_OK) <= -1) goto oops; | 				if (client->prim.end_reply(client, HCL_CLIENT_END_REPLY_STATE_OK) <= -1) goto oops; | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -456,30 +456,40 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg) | |||||||
| 	worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl); | 	worker_hcl_xtn_t* xtn = (worker_hcl_xtn_t*)hcl_getxtn(hcl); | ||||||
| 	bb_t* bb; | 	bb_t* bb; | ||||||
| 	hcl_oow_t bcslen, ucslen, remlen; | 	hcl_oow_t bcslen, ucslen, remlen; | ||||||
|  | 	hcl_server_worker_t* worker; | ||||||
| 	int x; | 	int x; | ||||||
|  |  | ||||||
| 	bb = (bb_t*)arg->handle; | 	bb = (bb_t*)arg->handle; | ||||||
| 	HCL_ASSERT (hcl, bb != HCL_NULL && bb->fd >= 0); | 	HCL_ASSERT (hcl, bb != HCL_NULL && bb->fd >= 0); | ||||||
|  |  | ||||||
| 	if (bb->fd == xtn->proto->worker->sck) | 	worker = xtn->proto->worker; | ||||||
|  |  | ||||||
|  | 	if (bb->fd == worker->sck) | ||||||
| 	{ | 	{ | ||||||
| 		ssize_t x; | 		ssize_t x; | ||||||
|  | 		hcl_server_t* server; | ||||||
|  |  | ||||||
|  | 		server = worker->server; | ||||||
|  |  | ||||||
| 	start_over: | 	start_over: | ||||||
| 		while (1) | 		while (1) | ||||||
| 		{ | 		{ | ||||||
| 			int n; | 			int n; | ||||||
| 			struct pollfd pfd; | 			struct pollfd pfd; | ||||||
|  | 			int tmout, actual_tmout; | ||||||
|  |  | ||||||
| 			if (xtn->proto->worker->server->stopreq) | 			if (server->stopreq) | ||||||
| 			{ | 			{ | ||||||
| 				hcl_seterrbfmt (hcl, HCL_EGENERIC, "stop requested"); | 				hcl_seterrbfmt (hcl, HCL_EGENERIC, "stop requested"); | ||||||
| 				return -1; | 				return -1; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
|  | 			tmout = HCL_SECNSEC_TO_MSEC(server->cfg.worker_idle_timeout.sec, server->cfg.worker_idle_timeout.nsec); | ||||||
|  | 			actual_tmout = (tmout <= 0)? 10000: tmout; | ||||||
|  |  | ||||||
| 			pfd.fd = bb->fd; | 			pfd.fd = bb->fd; | ||||||
| 			pfd.events = POLLIN | POLLERR; | 			pfd.events = POLLIN | POLLERR; | ||||||
| 			n = poll(&pfd, 1, 10000); /* TOOD: adjust this interval base on the worker_idle_timeout? */ | 			n = poll(&pfd, 1, actual_tmout); | ||||||
| 			if (n <= -1) | 			if (n <= -1) | ||||||
| 			{ | 			{ | ||||||
| 				if (errno == EINTR) goto start_over; | 				if (errno == EINTR) goto start_over; | ||||||
| @ -488,7 +498,12 @@ static HCL_INLINE int read_input (hcl_t* hcl, hcl_ioinarg_t* arg) | |||||||
| 			} | 			} | ||||||
| 			else if (n >= 1) break; | 			else if (n >= 1) break; | ||||||
|  |  | ||||||
| /* TOOD: idle timeout check - compute idling time and check it against server->cfg.worker_idle_timeout */ | 			/* timed out - no activity on the pfd */ | ||||||
|  | 			if (tmout > 0) | ||||||
|  | 			{ | ||||||
|  | 				hcl_seterrbfmt (hcl, HCL_EGENERIC, "no activity on the worker socket %d", worker->sck); | ||||||
|  | 				return -1; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 		 | 		 | ||||||
| 		x = recv(bb->fd, &bb->buf[bb->len], HCL_COUNTOF(bb->buf) - bb->len, 0); | 		x = recv(bb->fd, &bb->buf[bb->len], HCL_COUNTOF(bb->buf) - bb->len, 0); | ||||||
|  | |||||||
| @ -501,7 +501,7 @@ static int feed_data (hcl_client_t* client, const void* ptr, hcl_oow_t len) | |||||||
|  |  | ||||||
| /* ========================================================================= */ | /* ========================================================================= */ | ||||||
|  |  | ||||||
| static int handle_request (hcl_client_t* client, const char* ipaddr, const char* script) | static int handle_request (hcl_client_t* client, const char* ipaddr, const char* script, int shut_wr_after_req) | ||||||
| { | { | ||||||
| 	hcl_sckaddr_t sckaddr; | 	hcl_sckaddr_t sckaddr; | ||||||
| 	hcl_scklen_t scklen; | 	hcl_scklen_t scklen; | ||||||
| @ -576,6 +576,8 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char* | |||||||
| 		iov[index].iov_len -= nwritten; | 		iov[index].iov_len -= nwritten; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	if (shut_wr_after_req) shutdown (sck, SHUT_WR); | ||||||
|  |  | ||||||
| 	client_xtn->data_length = 0; | 	client_xtn->data_length = 0; | ||||||
| 	client_xtn->reply_count = 0; | 	client_xtn->reply_count = 0; | ||||||
|  |  | ||||||
| @ -583,7 +585,7 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char* | |||||||
| 	avail = 0; | 	avail = 0; | ||||||
| 	while (client_xtn->reply_count == 0) | 	while (client_xtn->reply_count == 0) | ||||||
| 	{ | 	{ | ||||||
| 		n = read(sck, &buf[avail], HCL_SIZEOF(buf) - avail); /* switch to recv  */ | 		n = recv(sck, &buf[avail], HCL_SIZEOF(buf) - avail, 0); | ||||||
| 		if (n <= -1)  | 		if (n <= -1)  | ||||||
| 		{ | 		{ | ||||||
| 			fprintf (stderr, "Unable to read from %d - %s\n", sck, strerror(n)); | 			fprintf (stderr, "Unable to read from %d - %s\n", sck, strerror(n)); | ||||||
| @ -601,7 +603,11 @@ static int handle_request (hcl_client_t* client, const char* ipaddr, const char* | |||||||
|  |  | ||||||
| 		avail += n;; | 		avail += n;; | ||||||
| 		x = hcl_client_feed(client, buf, avail, &used); | 		x = hcl_client_feed(client, buf, avail, &used); | ||||||
| 		if (x <= -1) goto oops; | 		if (x <= -1)  | ||||||
|  | 		{ | ||||||
|  | 			fprintf (stderr, "Client error [%d]\n", hcl_client_geterrnum(client)); | ||||||
|  | 			goto oops; | ||||||
|  | 		} | ||||||
|  |  | ||||||
| 		avail -= used; | 		avail -= used; | ||||||
| 		if (avail > 0) memmove (&buf[0], &buf[used], avail); | 		if (avail > 0) memmove (&buf[0], &buf[used], avail); | ||||||
| @ -622,6 +628,7 @@ int main (int argc, char* argv[]) | |||||||
| 	static hcl_bopt_lng_t lopt[] = | 	static hcl_bopt_lng_t lopt[] = | ||||||
| 	{ | 	{ | ||||||
| 		{ ":log",                  'l'  }, | 		{ ":log",                  'l'  }, | ||||||
|  | 		{ "shutwr",                '\0' }, | ||||||
| 		{ HCL_NULL,                '\0' } | 		{ HCL_NULL,                '\0' } | ||||||
| 	}; | 	}; | ||||||
| 	static hcl_bopt_t opt = | 	static hcl_bopt_t opt = | ||||||
| @ -635,14 +642,14 @@ int main (int argc, char* argv[]) | |||||||
| 	hcl_client_prim_t client_prim; | 	hcl_client_prim_t client_prim; | ||||||
| 	int n; | 	int n; | ||||||
| 	const char* logopt = HCL_NULL; | 	const char* logopt = HCL_NULL; | ||||||
|  | 	int shut_wr_after_req = 0; | ||||||
|  |  | ||||||
| 	setlocale (LC_ALL, ""); | 	setlocale (LC_ALL, ""); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if (argc < 2) | 	if (argc < 2) | ||||||
| 	{ | 	{ | ||||||
| 	print_usage: | 	print_usage: | ||||||
| 		fprintf (stderr, "Usage: %s bind-address:port script-to-run\n", argv[0]); | 		fprintf (stderr, "Usage: %s [-l/--log log-options] [--shutwr] bind-address:port script-to-run\n", argv[0]); | ||||||
| 		return -1; | 		return -1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @ -655,7 +662,14 @@ int main (int argc, char* argv[]) | |||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case '\0': | 			case '\0': | ||||||
| 				goto print_usage; | 				if (hcl_compbcstr(opt.lngopt, "shutwr") == 0) | ||||||
|  | 				{ | ||||||
|  | 					shut_wr_after_req = 1; | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
|  | 					goto print_usage; | ||||||
|  | 				} | ||||||
| 				break; | 				break; | ||||||
|  |  | ||||||
| 			case ':': | 			case ':': | ||||||
| @ -706,18 +720,12 @@ int main (int argc, char* argv[]) | |||||||
| 	set_signal (SIGINT, handle_sigint); | 	set_signal (SIGINT, handle_sigint); | ||||||
| 	set_signal_to_ignore (SIGPIPE); | 	set_signal_to_ignore (SIGPIPE); | ||||||
|  |  | ||||||
|  | 	n = handle_request (client, argv[opt.ind], argv[opt.ind + 1], shut_wr_after_req); | ||||||
| 	n = handle_request (client, argv[opt.ind], argv[opt.ind + 1]); |  | ||||||
|  |  | ||||||
| 	set_signal_to_default (SIGINT); | 	set_signal_to_default (SIGINT); | ||||||
| 	set_signal_to_default (SIGPIPE); | 	set_signal_to_default (SIGPIPE); | ||||||
| 	g_client = NULL; | 	g_client = NULL; | ||||||
|  |  | ||||||
| 	if (n <= -1) |  | ||||||
| 	{ |  | ||||||
| 		hcl_client_logbfmt (client, HCL_LOG_APP | HCL_LOG_FATAL, "client error[%d] - %js\n", hcl_client_geterrnum(client), hcl_client_geterrmsg(client)); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if (xtn->logfd >= 0) | 	if (xtn->logfd >= 0) | ||||||
| 	{ | 	{ | ||||||
| 		close (xtn->logfd); | 		close (xtn->logfd); | ||||||
|  | |||||||
		Reference in New Issue
	
	Block a user