introduce-external-poll-callbacks.patch
Signed-off-by: Andy Green <andy.green@linaro.org>
diff --git a/lib/client-handshake.c b/lib/client-handshake.c
index e3a6efc..fd786cd 100644
--- a/lib/client-handshake.c
+++ b/lib/client-handshake.c
@@ -567,6 +567,12 @@
this->fds[this->fds_count].revents = 0;
this->fds[this->fds_count++].events = POLLIN;
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_ADD_POLL_FD,
+ (void *)(long)wsi->sock, NULL, POLLIN);
+
+
wsi->state = WSI_STATE_ESTABLISHED;
wsi->mode = LWS_CONNMODE_WS_CLIENT;
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index 83505c8..49913b7 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -182,7 +182,7 @@
}
if (this->fds_count >= MAX_CLIENTS) {
- fprintf(stderr, "too busy");
+ fprintf(stderr, "too busy to accept new client\n");
close(accept_fd);
break;
}
@@ -271,7 +271,6 @@
insert_wsi(this, new_wsi);
-
/*
* make sure NO events are seen yet on this new socket
* (otherwise we inherit old fds[client].revents from
@@ -282,6 +281,11 @@
this->fds[this->fds_count].events = POLLIN;
this->fds[this->fds_count++].fd = accept_fd;
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(new_wsi,
+ LWS_CALLBACK_ADD_POLL_FD,
+ (void *)(long)accept_fd, NULL, POLLIN);
+
break;
case LWS_CONNMODE_BROADCAST_PROXY_LISTENER:
@@ -302,7 +306,8 @@
}
if (this->fds_count >= MAX_CLIENTS) {
- fprintf(stderr, "too busy");
+ fprintf(stderr, "too busy to accept new broadcast "
+ "proxy client\n");
close(accept_fd);
break;
}
@@ -325,6 +330,11 @@
this->fds[this->fds_count].events = POLLIN;
this->fds[this->fds_count++].fd = accept_fd;
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(new_wsi,
+ LWS_CALLBACK_ADD_POLL_FD,
+ (void *)(long)accept_fd, NULL, POLLIN);
+
break;
case LWS_CONNMODE_BROADCAST_PROXY:
@@ -348,6 +358,11 @@
pollfd->events &= ~POLLOUT;
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_CLEAR_MODE_POLL_FD,
+ (void *)(long)wsi->sock, NULL, POLLOUT);
+
wsi->protocol->callback(wsi,
LWS_CALLBACK_CLIENT_WRITEABLE,
wsi->user_space,
@@ -428,6 +443,11 @@
pollfd->events &= ~POLLOUT;
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_CLEAR_MODE_POLL_FD,
+ (void *)(long)wsi->sock, NULL, POLLOUT);
+
wsi->protocol->callback(wsi,
LWS_CALLBACK_CLIENT_WRITEABLE,
wsi->user_space,
@@ -481,6 +501,12 @@
n = this->fds_count;
}
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_DEL_POLL_FD,
+ (void *)(long)pollfd->fd, NULL, 0);
+
+
break;
}
@@ -583,6 +609,8 @@
/* wait for something to need service */
n = poll(this->fds, this->fds_count, timeout_ms);
+ if (n == 0) /* poll timeout */
+ return 0;
if (n < 0 || this->fds[0].revents & (POLLERR | POLLHUP)) {
/*
@@ -590,8 +618,6 @@
*/
return 1;
}
- if (n == 0) /* poll timeout */
- return 0;
/* handle accept on listening socket? */
@@ -606,11 +632,7 @@
* libwebsocket_callback_on_writable() - Request a callback when this socket
* becomes able to be written to without
* blocking
- *
- * This only works for internal poll() management, (ie, calling the libwebsocket
- * service loop, you will have to make your own arrangements if your poll()
- * loop is managed externally.
- *
+ * *
* @wsi: Websocket connection instance to get callback for
*/
@@ -623,11 +645,14 @@
for (n = 0; n < this->fds_count; n++)
if (this->fds[n].fd == wsi->sock) {
this->fds[n].events |= POLLOUT;
- return 0;
+ n = this->fds_count;
}
- fprintf(stderr, "libwebsocket_callback_on_writable "
- "didn't find socket\n");
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_SET_MODE_POLL_FD,
+ (void *)(long)wsi->sock, NULL, POLLOUT);
+
return 1;
}
@@ -637,10 +662,6 @@
* becomes possible to write to each socket without
* blocking in turn.
*
- * This only works for internal poll() management, (ie, calling the libwebsocket
- * service loop, you will have to make your own arrangements if your poll()
- * loop is managed externally.
- *
* @protocol: Protocol whose connections will get callbacks
*/
@@ -689,10 +710,6 @@
* If the output side of a server process becomes choked, this allows flow
* control for the input side.
*
- * This only works for internal poll() management, (ie, calling the libwebsocket
- * service loop, you will have to make your own arrangements if your poll()
- * loop is managed externally.
- *
* @wsi: Websocket connection instance to get callback for
* @enable: 0 = disable read servicing for this connection, 1 = enable
*/
@@ -713,6 +730,18 @@
return 0;
}
+ if (enable)
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_SET_MODE_POLL_FD,
+ (void *)(long)wsi->sock, NULL, POLLIN);
+ else
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_CLEAR_MODE_POLL_FD,
+ (void *)(long)wsi->sock, NULL, POLLIN);
+
+
fprintf(stderr, "libwebsocket_callback_on_writable "
"unable to find socket\n");
return 1;
@@ -1024,6 +1053,12 @@
this->fds[this->fds_count].fd = sockfd;
this->fds[this->fds_count++].events = POLLIN;
+
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_ADD_POLL_FD,
+ (void *)(long)sockfd, NULL, POLLIN);
+
}
/* drop any root privs for this process */
@@ -1094,7 +1129,13 @@
this->fds[this->fds_count].fd = fd;
this->fds[this->fds_count].events = POLLIN;
+ this->fds[this->fds_count].revents = 0;
this->fds_count++;
+
+ /* external POLL support via protocol 0 */
+ this->protocols[0].callback(wsi,
+ LWS_CALLBACK_ADD_POLL_FD,
+ (void *)(long)fd, NULL, POLLIN);
}
return this;
@@ -1116,10 +1157,10 @@
int
libwebsockets_fork_service_loop(struct libwebsocket_context *this)
{
- int client;
int fd;
struct sockaddr_in cli_addr;
int n;
+ int p;
n = fork();
if (n < 0)
@@ -1129,7 +1170,12 @@
/* main process context */
- for (client = 1; client < this->count_protocols + 1; client++) {
+ /*
+ * set up the proxy sockets to allow broadcast from
+ * service process context
+ */
+
+ for (p = 0; p < this->count_protocols; p++) {
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0) {
fprintf(stderr, "Unable to create socket\n");
@@ -1137,22 +1183,20 @@
}
cli_addr.sin_family = AF_INET;
cli_addr.sin_port = htons(
- this->protocols[client - 1].broadcast_socket_port);
+ this->protocols[p].broadcast_socket_port);
cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
n = connect(fd, (struct sockaddr *)&cli_addr,
sizeof cli_addr);
if (n < 0) {
fprintf(stderr, "Unable to connect to "
"broadcast socket %d, %s\n",
- client, strerror(errno));
+ n, strerror(errno));
return -1;
}
- this->protocols[client - 1].broadcast_socket_user_fd =
- fd;
+ this->protocols[p].broadcast_socket_user_fd = fd;
}
-
return 0;
}
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index d15c2c7..5a870d7 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -40,7 +40,13 @@
LWS_CALLBACK_CLIENT_RECEIVE_PONG,
LWS_CALLBACK_CLIENT_WRITEABLE,
LWS_CALLBACK_HTTP,
- LWS_CALLBACK_BROADCAST
+ LWS_CALLBACK_BROADCAST,
+
+ /* external poll() management support */
+ LWS_CALLBACK_ADD_POLL_FD,
+ LWS_CALLBACK_DEL_POLL_FD,
+ LWS_CALLBACK_SET_MODE_POLL_FD,
+ LWS_CALLBACK_CLEAR_MODE_POLL_FD,
};
enum libwebsocket_write_protocol {
diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html
index 9e5f27e..40a0c0b 100644
--- a/libwebsockets-api-doc.html
+++ b/libwebsockets-api-doc.html
@@ -78,7 +78,7 @@
nothing is pending, or as soon as it services whatever was pending.
</blockquote>
<hr>
-<h2>libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking</h2>
+<h2>libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking *</h2>
<i>int</i>
<b>libwebsocket_callback_on_writable</b>
(<i>struct libwebsocket *</i> <b>wsi</b>)
@@ -87,13 +87,6 @@
<dt><b>wsi</b>
<dd>Websocket connection instance to get callback for
</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>
<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>
@@ -104,13 +97,6 @@
<dt><b>protocol</b>
<dd>Protocol whose connections will get callbacks
</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>
<h2>libwebsocket_get_socket_fd - returns the socket file descriptor</h2>
<i>int</i>
@@ -144,10 +130,6 @@
<p>
If the output side of a server process becomes choked, this allows flow
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>
<hr>
<h2>libwebsocket_canonical_hostname - returns this host's hostname</h2>