introduce timeout system
This adds a concept of timeouts for operations enforced by
connection closure if the timeout is reached.
Once a second all sockets are checked for timing out, every time
there is a service call it checks to see if a second has passed since
the last check and checks if so.
You can also call libwebsocket_service_fd() with a NULL fd to give
the timeouts a chance to be detected; if it's less than a second since
the last check it returns immediately.
Signed-off-by: Andy Green <andy@warmcat.com>
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index c6477ce..a35193d 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -276,7 +276,7 @@
{
unsigned char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_BROADCAST_PAYLOAD +
LWS_SEND_BUFFER_POST_PADDING];
- struct libwebsocket *wsi = wsi_from_fd(this, pollfd->fd);
+ struct libwebsocket *wsi;
struct libwebsocket *new_wsi;
int n;
int m;
@@ -284,6 +284,44 @@
int accept_fd;
unsigned int clilen;
struct sockaddr_in cli_addr;
+ struct timeval tv;
+
+ /*
+ * you can call us with pollfd = NULL to just allow the once-per-second
+ * global timeout checks; if less than a second since the last check
+ * it returns immediately then.
+ */
+
+ gettimeofday(&tv, NULL);
+
+ if (this->last_timeout_check_s != tv.tv_sec) {
+ this->last_timeout_check_s = tv.tv_sec;
+
+ /* global timeout check once per second */
+
+ for (n = 0; n < this->fds_count; n++) {
+ wsi = wsi_from_fd(this, this->fds[n].fd);
+ if (!wsi->pending_timeout)
+ continue;
+
+ /*
+ * if we went beyond the allowed time, kill the
+ * connection
+ */
+
+ if (tv.tv_sec > wsi->pending_timeout_limit)
+ libwebsocket_close_and_free_session(this, wsi);
+ }
+ }
+
+ /* just here for timeout management? */
+
+ if (pollfd == NULL)
+ return 0;
+
+ /* no, here to service a socket descriptor */
+
+ wsi = wsi_from_fd(this, pollfd->fd);
if (wsi == NULL)
return 1;
@@ -336,6 +374,7 @@
memset(new_wsi, 0, sizeof (struct libwebsocket));
new_wsi->sock = accept_fd;
+ new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
#ifdef LWS_OPENSSL_SUPPORT
new_wsi->ssl = NULL;