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:
parent
b86d64eaa9
commit
a71eafce5a
3 changed files with 50 additions and 1 deletions
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue