[Libwebsockets] [PATCH 08/11] move register, unregister and watching direction change into event_ops

Andy Green andy at warmcat.com
Tue Dec 16 01:28:34 CET 2014



On 16 December 2014 07:36:29 GMT+08:00, Alejandro Mery <amery at geeks.cl> wrote:
>Signed-off-by: Alejandro Mery <amery at geeks.cl>
>---
> lib/event-poll-unix.c       |  9 +++++++++
>lib/event-poll-win.c        | 41
>+++++++++++++++++++++++++++++++++++++++++
> lib/lws-plat-unix.c         | 20 --------------------
> lib/lws-plat-win.c          | 36 ------------------------------------
> lib/pollfd.c                | 12 +++++++-----
> lib/private-libwebsockets.h | 19 ++++++++++---------
> 6 files changed, 67 insertions(+), 70 deletions(-)
>
>diff --git a/lib/event-poll-unix.c b/lib/event-poll-unix.c
>index e043a2f..d2f0684 100644
>--- a/lib/event-poll-unix.c
>+++ b/lib/event-poll-unix.c
>@@ -86,6 +86,15 @@ poll_service(struct libwebsocket_context *context,
>int timeout_ms)
> 	return 0;
> }
> 
>+
>+static void
>+poll_register(struct libwebsocket_context *context,
>+	      struct libwebsocket *wsi)
>+{
>+	context->fds[context->fds_count++].revents = 0;
>+}
>+
> struct lws_event_ops lws_poll_event_ops = {
> 	.service = poll_service,
>+	.socket_register = poll_register,
> };
>diff --git a/lib/event-poll-win.c b/lib/event-poll-win.c
>index 3a86955..04a33de 100644
>--- a/lib/event-poll-win.c
>+++ b/lib/event-poll-win.c
>@@ -67,6 +67,47 @@ poll_service(struct libwebsocket_context *context,
>int timeout_ms)
> 	return libwebsocket_service_fd(context, pfd);
> }
> 
>+static void
>+poll_register(struct libwebsocket_context *context,
>+	      struct libwebsocket *wsi)
>+{
>+	context->fds[context->fds_count++].revents = 0;
>+	context->e.poll.events[context->fds_count] = WSACreateEvent();
>+	WSAEventSelect(wsi->sock, context->e.poll.events[context->fds_count],
>LWS_POLLIN);
>+}
>+
>+static void
>+poll_unregister(struct libwebsocket_context *context,
>+		struct libwebsocket *wsi,
>+		int m)
>+{
>+	WSACloseEvent(context->e.poll.events[m + 1]);
>+	context->e.poll.events[m + 1] =
>context->e.poll.events[context->fds_count + 1];
>+}
>+
>+static int
>+poll_change(struct libwebsocket_context *context,
>+	    struct libwebsocket *wsi,
>+	    struct libwebsocket_pollfd *pfd)
>+{
>+	long networkevents = LWS_POLLOUT | LWS_POLLHUP;
>+
>+	if ((pfd->events & LWS_POLLIN))
>+		networkevents |= LWS_POLLIN;
>+
>+	if (WSAEventSelect(wsi->sock,
>+			   context->e.poll.events[wsi->position_in_fds_table + 1],
>+			   networkevents) != SOCKET_ERROR)
>+		return 0;
>+
>+	lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO);
>+
>+	return 1;
>+}
>+
> struct lws_event_ops lws_poll_event_ops = {
> 	.service = poll_service,
>+	.socket_register = poll_register,
>+	.socket_unregister = poll_unregister,
>+	.socket_change = poll_change,
> };
>diff --git a/lib/lws-plat-unix.c b/lib/lws-plat-unix.c
>index a0f1104..485a45e 100644
>--- a/lib/lws-plat-unix.c
>+++ b/lib/lws-plat-unix.c
>@@ -295,19 +295,6 @@ interface_to_sa(struct libwebsocket_context
>*context,
> }
> 
> LWS_VISIBLE void
>-lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
>-						       struct libwebsocket *wsi)
>-{
>-	context->fds[context->fds_count++].revents = 0;
>-}
>-
>-LWS_VISIBLE void
>-lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
>-						struct libwebsocket *wsi, int m)
>-{
>-}
>-
>-LWS_VISIBLE void
> lws_plat_service_periodic(struct libwebsocket_context *context)
> {
> 	/* if our parent went down, don't linger around */
>@@ -317,13 +304,6 @@ lws_plat_service_periodic(struct
>libwebsocket_context *context)
> }
> 
> LWS_VISIBLE int
>-lws_plat_change_pollfd(struct libwebsocket_context *context,
>-		      struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd)
>-{
>-	return 0;
>-}
>-
>-LWS_VISIBLE int
> lws_plat_open_file(const char* filename, unsigned long* filelen)
> {
> 	struct stat stat_buf;
>diff --git a/lib/lws-plat-win.c b/lib/lws-plat-win.c
>index 88c04fb..0afc787 100644
>--- a/lib/lws-plat-win.c
>+++ b/lib/lws-plat-win.c
>@@ -199,46 +199,10 @@ interface_to_sa(struct libwebsocket_context
>*context,
> }
> 
> LWS_VISIBLE void
>-lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
>-						       struct libwebsocket *wsi)
>-{
>-	context->fds[context->fds_count++].revents = 0;
>-	context->e.poll.events[context->fds_count] = WSACreateEvent();
>-	WSAEventSelect(wsi->sock, context->e.poll.events[context->fds_count],
>LWS_POLLIN);
>-}
>-
>-LWS_VISIBLE void
>-lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
>-						struct libwebsocket *wsi, int m)
>-{
>-	WSACloseEvent(context->e.poll.events[m + 1]);
>-	context->e.poll.events[m + 1] =
>context->e.poll.events[context->fds_count + 1];
>-}
>-
>-LWS_VISIBLE void
> lws_plat_service_periodic(struct libwebsocket_context *context)
> {
> }
> 
>-LWS_VISIBLE int
>-lws_plat_change_pollfd(struct libwebsocket_context *context,
>-		      struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd)
>-{
>-	long networkevents = LWS_POLLOUT | LWS_POLLHUP;
>-		
>-	if ((pfd->events & LWS_POLLIN))
>-		networkevents |= LWS_POLLIN;
>-
>-	if (WSAEventSelect(wsi->sock,
>-			context->e.poll.events[wsi->position_in_fds_table + 1],
>-					       networkevents) != SOCKET_ERROR)
>-		return 0;
>-
>-	lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO);
>-
>-	return 1;
>-}
>-
> LWS_VISIBLE HANDLE
> lws_plat_open_file(const char* filename, unsigned long* filelen)
> {
>diff --git a/lib/pollfd.c b/lib/pollfd.c
>index c12ac5b..638ca89 100644
>--- a/lib/pollfd.c
>+++ b/lib/pollfd.c
>@@ -52,8 +52,9 @@ insert_wsi_socket_into_fds(struct
>libwebsocket_context *context,
> 	wsi->position_in_fds_table = context->fds_count;
> 	context->fds[context->fds_count].fd = wsi->sock;
> 	context->fds[context->fds_count].events = LWS_POLLIN;
>-	
>-	lws_plat_insert_socket_into_fds(context, wsi);
>+
>+	if (context->event_ops->socket_register)
>+		context->event_ops->socket_register(context, wsi);
> 
> 	/* external POLL support via protocol 0 */
> 	context->protocols[0].callback(context, wsi,
>@@ -99,7 +100,8 @@ remove_wsi_socket_from_fds(struct
>libwebsocket_context *context,
> 	/* have the last guy take up the vacant slot */
> 	context->fds[m] = context->fds[context->fds_count];
> 
>-	lws_plat_delete_socket_from_fds(context, wsi, m);
>+	if (context->event_ops->socket_unregister)
>+		context->event_ops->socket_unregister(context, wsi, m);

This looks like it is the right stuff to allow user-provided event-ops to also mop up external poll loop integration.  At the moment we handle it by callbacks but this would be cleaner and faster.

Basically some usecases graft lws on an already existing app who does his own event management perfectly well already and cannot deal with another one.  So lws has to join his event loop management in a customized way.  This looks very nice for that.

-Andy

> 	/*
> 	 * end guy's fds_lookup entry remains unchanged
>@@ -163,8 +165,8 @@ lws_change_pollfd(struct libwebsocket *wsi, int
>_and, int _or)
> 	 *         then cancel it to force a restart with our changed events
> 	 */
> 	if (pa.prev_events != pa.events) {
>-		
>-		if (lws_plat_change_pollfd(context, wsi, pfd)) {
>+		if (context->event_ops->socket_change &&
>+		    context->event_ops->socket_change(context, wsi, pfd)) {
> 			lwsl_info("%s failed\n", __func__);
> 			return 1;
> 		}
>diff --git a/lib/private-libwebsockets.h b/lib/private-libwebsockets.h
>index 5c2c034..6eed5e8 100755
>--- a/lib/private-libwebsockets.h
>+++ b/lib/private-libwebsockets.h
>@@ -406,6 +406,16 @@ struct lws_event_ops {
> 
> 	int (*service)(struct libwebsocket_context *context,
> 		       int timeout_ms);
>+
>+	void (*socket_register)(struct libwebsocket_context *context,
>+				struct libwebsocket *wsi);
>+	void (*socket_unregister)(struct libwebsocket_context *context,
>+				  struct libwebsocket *wsi,
>+				  int m);
>+	int (*socket_change)(struct libwebsocket_context *context,
>+			     struct libwebsocket *wsi,
>+			     struct libwebsocket_pollfd *pfd);
>+
> };
> 
> extern struct lws_event_ops lws_poll_event_ops;
>@@ -1182,18 +1192,9 @@ lws_zalloc(size_t size);
>  * lws_plat_
>  */
> LWS_EXTERN void
>-lws_plat_delete_socket_from_fds(struct libwebsocket_context *context,
>-					       struct libwebsocket *wsi, int m);
>-LWS_EXTERN void
>-lws_plat_insert_socket_into_fds(struct libwebsocket_context *context,
>-						      struct libwebsocket *wsi);
>-LWS_EXTERN void
> lws_plat_service_periodic(struct libwebsocket_context *context);
> 
> LWS_EXTERN int
>-lws_plat_change_pollfd(struct libwebsocket_context *context,
>-		     struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd);
>-LWS_EXTERN int
> lws_plat_context_early_init(void);
> LWS_EXTERN void
> lws_plat_context_early_destroy(struct libwebsocket_context *context);




More information about the Libwebsockets mailing list