1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-09 00:00:04 +01:00

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>
This commit is contained in:
Andy Green 2011-02-14 17:59:43 +00:00
parent b86d64eaa9
commit a71eafce5a
3 changed files with 50 additions and 1 deletions

View file

@ -92,6 +92,7 @@ libwebsocket_client_connect(struct libwebsocket_context *this,
wsi->state = WSI_STATE_CLIENT_UNCONNECTED;
wsi->pings_vs_pongs = 0;
wsi->protocol = NULL;
wsi->pending_timeout = NO_PENDING_TIMEOUT;
/* set up appropriate masking */

View file

@ -276,7 +276,7 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
{
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 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
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 @@ libwebsocket_service_fd(struct libwebsocket_context *this,
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;

View file

@ -166,6 +166,7 @@ struct libwebsocket_context {
char canonical_hostname[1024];
unsigned int http_proxy_port;
unsigned int options;
unsigned long last_timeout_check_s;
int fd_random;
@ -179,6 +180,12 @@ struct libwebsocket_context {
};
enum pending_timeout {
NO_PENDING_TIMEOUT = 0,
PENDING_TIMEOUT_ESTABLISH_WITH_SERVER,
PENDING_TIMEOUT_AWAITING_PING,
};
/*
* This is totally opaque to code using the library. It's exported as a
@ -201,6 +208,8 @@ struct libwebsocket {
LWS_SEND_BUFFER_POST_PADDING];
int rx_user_buffer_head;
int protocol_index_for_broadcast_proxy;
enum pending_timeout pending_timeout;
unsigned long pending_timeout_limit;
int sock;