Skip to content
Snippets Groups Projects
Commit 0d338337 authored by Andy Green's avatar Andy Green Committed by Andy Green
Browse files

decouple-service-from-fd-array-index.patch


This patch removes the relationship between position in the
pollfd[] array and any meaning about the type of socket.

It also refactors the service loop so there is a per-fd
function that detects the mode of the connection and services
it accordingly.

The context wsi * array is removed and a hashtable introduced
allowing fast wsi lookup from just the fd that it is
associated with

Signed-off-by: default avatarAndy Green <andy@warmcat.com>
parent 44eee688
No related branches found
No related tags found
No related merge requests found
...@@ -50,11 +50,10 @@ libwebsocket_client_close(struct libwebsocket *wsi) ...@@ -50,11 +50,10 @@ libwebsocket_client_close(struct libwebsocket *wsi)
clients = wsi->protocol->owning_server; clients = wsi->protocol->owning_server;
if (clients) if (clients)
for (n = 0; n < clients->fds_count; n++) { for (n = 0; n < clients->fds_count; n++) {
if (clients->wsi[n] != wsi) if (clients->fds[n].fd != wsi->sock)
continue; continue;
while (n < clients->fds_count - 1) { while (n < clients->fds_count - 1) {
clients->fds[n] = clients->fds[n + 1]; clients->fds[n] = clients->fds[n + 1];
clients->wsi[n] = clients->wsi[n + 1];
n++; n++;
} }
/* we only have to deal with one */ /* we only have to deal with one */
...@@ -150,8 +149,6 @@ libwebsocket_client_connect(struct libwebsocket_context *this, ...@@ -150,8 +149,6 @@ libwebsocket_client_connect(struct libwebsocket_context *this,
return NULL; return NULL;
} }
this->wsi[this->fds_count] = wsi;
/* -1 means just use latest supported */ /* -1 means just use latest supported */
if (ietf_version_or_minus_one == -1) if (ietf_version_or_minus_one == -1)
...@@ -225,6 +222,7 @@ libwebsocket_client_connect(struct libwebsocket_context *this, ...@@ -225,6 +222,7 @@ libwebsocket_client_connect(struct libwebsocket_context *this,
goto bail1; goto bail1;
} }
insert_wsi(this, wsi);
server_addr.sin_family = AF_INET; server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port); server_addr.sin_port = htons(port);
......
This diff is collapsed.
...@@ -1143,6 +1143,8 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf, ...@@ -1143,6 +1143,8 @@ int libwebsocket_write(struct libwebsocket *wsi, unsigned char *buf,
*/ */
buf[0] = 'C'; buf[0] = 'C';
break; break;
default:
break;
} }
} }
break; break;
......
...@@ -68,7 +68,7 @@ static inline void debug(const char *format, ...) ...@@ -68,7 +68,7 @@ static inline void debug(const char *format, ...)
} }
#endif #endif
#define FD_HASHTABLE_MODULUS 32
#define MAX_CLIENTS 100 #define MAX_CLIENTS 100
#define LWS_MAX_HEADER_NAME_LENGTH 64 #define LWS_MAX_HEADER_NAME_LENGTH 64
#define LWS_MAX_HEADER_LEN 4096 #define LWS_MAX_HEADER_LEN 4096
...@@ -166,11 +166,29 @@ struct lws_tokens { ...@@ -166,11 +166,29 @@ struct lws_tokens {
int token_len; int token_len;
}; };
enum connection_mode {
LWS_CONNMODE_WS_SERVING,
LWS_CONNMODE_WS_CLIENT,
/* special internal types */
LWS_CONNMODE_SERVER_LISTENER,
LWS_CONNMODE_BROADCAST_PROXY_LISTENER,
LWS_CONNMODE_BROADCAST_PROXY
};
#define LWS_FD_HASH(fd) ((fd ^ (fd >> 8) ^ (fd >> 16)) % FD_HASHTABLE_MODULUS)
struct libwebsocket_fd_hashtable {
struct libwebsocket *wsi[MAX_CLIENTS + 1];
int length;
};
struct libwebsocket_protocols; struct libwebsocket_protocols;
struct libwebsocket_context { struct libwebsocket_context {
struct libwebsocket *wsi[MAX_CLIENTS + 1]; struct libwebsocket_fd_hashtable fd_hashtable[FD_HASHTABLE_MODULUS];
struct pollfd fds[MAX_CLIENTS + 1]; struct pollfd fds[MAX_CLIENTS * FD_HASHTABLE_MODULUS + 1];
int fds_count; int fds_count;
int listen_port; int listen_port;
char http_proxy_address[256]; char http_proxy_address[256];
...@@ -189,10 +207,6 @@ struct libwebsocket_context { ...@@ -189,10 +207,6 @@ struct libwebsocket_context {
int count_protocols; int count_protocols;
}; };
enum connection_mode {
LWS_CONNMODE_WS_SERVING,
LWS_CONNMODE_WS_CLIENT,
};
/* /*
...@@ -215,6 +229,7 @@ struct libwebsocket { ...@@ -215,6 +229,7 @@ struct libwebsocket {
char rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + MAX_USER_RX_BUFFER + char rx_user_buffer[LWS_SEND_BUFFER_PRE_PADDING + MAX_USER_RX_BUFFER +
LWS_SEND_BUFFER_POST_PADDING]; LWS_SEND_BUFFER_POST_PADDING];
int rx_user_buffer_head; int rx_user_buffer_head;
int protocol_index_for_broadcast_proxy;
int sock; int sock;
...@@ -279,3 +294,12 @@ xor_mask_04(struct libwebsocket *wsi, unsigned char c); ...@@ -279,3 +294,12 @@ xor_mask_04(struct libwebsocket *wsi, unsigned char c);
extern unsigned char extern unsigned char
xor_mask_05(struct libwebsocket *wsi, unsigned char c); xor_mask_05(struct libwebsocket *wsi, unsigned char c);
extern struct libwebsocket *
wsi_from_fd(struct libwebsocket_context *this, int fd);
extern int
insert_wsi(struct libwebsocket_context *this, struct libwebsocket *wsi);
extern int
delete_from_fd(struct libwebsocket_context *this, int fd);
...@@ -67,6 +67,13 @@ nothing is pending, or as soon as it services whatever was pending. ...@@ -67,6 +67,13 @@ nothing is pending, or as soon as it services whatever was pending.
<dt><b>wsi</b> <dt><b>wsi</b>
<dd>Websocket connection instance to get callback for <dd>Websocket connection instance to get callback for
</dl> </dl>
<h3>Description</h3>
<blockquote>
<p>
This only works for internal <b>poll</b> management, (ie, calling the libwebsocket
service loop, you will have to make your own arrangements if your <b>poll</b>
loop is managed externally.
</blockquote>
<hr> <hr>
<h2>libwebsocket_callback_on_writable_all_protocol - Request a callback for all connections using the given protocol when it becomes possible to write to each socket without blocking in turn.</h2> <h2>libwebsocket_callback_on_writable_all_protocol - Request a callback for all connections using the given protocol when it becomes possible to write to each socket without blocking in turn.</h2>
<i>int</i> <i>int</i>
...@@ -77,6 +84,13 @@ nothing is pending, or as soon as it services whatever was pending. ...@@ -77,6 +84,13 @@ nothing is pending, or as soon as it services whatever was pending.
<dt><b>protocol</b> <dt><b>protocol</b>
<dd>Protocol whose connections will get callbacks <dd>Protocol whose connections will get callbacks
</dl> </dl>
<h3>Description</h3>
<blockquote>
<p>
This only works for internal <b>poll</b> management, (ie, calling the libwebsocket
service loop, you will have to make your own arrangements if your <b>poll</b>
loop is managed externally.
</blockquote>
<hr> <hr>
<h2>libwebsocket_get_socket_fd - returns the socket file descriptor</h2> <h2>libwebsocket_get_socket_fd - returns the socket file descriptor</h2>
<i>int</i> <i>int</i>
...@@ -110,6 +124,10 @@ You will not need this unless you are doing something special ...@@ -110,6 +124,10 @@ You will not need this unless you are doing something special
<p> <p>
If the output side of a server process becomes choked, this allows flow If the output side of a server process becomes choked, this allows flow
control for the input side. control for the input side.
<p>
This only works for internal <b>poll</b> management, (ie, calling the libwebsocket
service loop, you will have to make your own arrangements if your <b>poll</b>
loop is managed externally.
</blockquote> </blockquote>
<hr> <hr>
<h2>libwebsocket_canonical_hostname - returns this host's hostname</h2> <h2>libwebsocket_canonical_hostname - returns this host's hostname</h2>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment