diff --git a/changelog b/changelog index 442ab6a2b3e9a71e92f7c37c7ff3d892cd51ac85..cd789c39b7400203293fc0a2d613828940c616d6 100644 --- a/changelog +++ b/changelog @@ -21,6 +21,12 @@ User api additions can enable it by setting a non-zero timeout (in seconds) at the new ka_time member at context creation time. + - Two new optional user callbacks added, LWS_CALLBACK_PROTOCOL_DESTROY which + is called one-time per protocol as the context is being destroyed, and + LWS_CALLBACK_PROTOCOL_INIT which is called when the context is created + and the protocols are added, again it's a one-time affair. + This lets you manage per-protocol allocations properly including + cleaning up after yourself when the server goes down. User api changes ---------------- diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c index e5d148addebc3e1ffd2e84f5218b271c86b3d97c..49a51fe9f6d9ee52a2d1f5f9c6abd0a5f1a1cfd9 100644 --- a/lib/libwebsockets.c +++ b/lib/libwebsockets.c @@ -1041,6 +1041,7 @@ libwebsocket_context_destroy(struct libwebsocket_context *context) int n; int m; struct libwebsocket_extension *ext; + struct libwebsocket_protocols *protocol = context->protocols; #ifdef LWS_LATENCY if (context->worst_latency_info[0]) @@ -1067,6 +1068,18 @@ libwebsocket_context_destroy(struct libwebsocket_context *context) ext->callback(context, ext, NULL, (enum libwebsocket_extension_callback_reasons)m, NULL, NULL, 0); ext++; } + + /* + * inform all the protocols that they are done and will have no more + * callbacks + */ + + while (protocol->callback) { + protocol->callback(context, NULL, LWS_CALLBACK_PROTOCOL_DESTROY, + NULL, NULL, 0); + protocol++; + } + #endif #ifdef WIN32 @@ -2023,6 +2036,13 @@ libwebsocket_create_context(struct lws_context_creation_info *info) context; info->protocols[context->count_protocols].protocol_index = context->count_protocols; + + /* + * inform all the protocols that they are doing their one-time + * initialization if they want to + */ + info->protocols[context->count_protocols].callback(context, + NULL, LWS_CALLBACK_PROTOCOL_INIT, NULL, NULL, 0); } #ifndef LWS_NO_EXTENSIONS diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index c39d13a8fc0e6ad57ec4f6fcfa872a042050c488..8ead4100cf32c457245da128a582a903a057c44c 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -142,6 +142,8 @@ enum libwebsocket_callback_reasons { LWS_CALLBACK_CLIENT_APPEND_HANDSHAKE_HEADER, LWS_CALLBACK_CONFIRM_EXTENSION_OKAY, LWS_CALLBACK_CLIENT_CONFIRM_EXTENSION_SUPPORTED, + LWS_CALLBACK_PROTOCOL_INIT, + LWS_CALLBACK_PROTOCOL_DESTROY, /* external poll() management support */ LWS_CALLBACK_ADD_POLL_FD, LWS_CALLBACK_DEL_POLL_FD, @@ -534,6 +536,14 @@ struct libwebsocket_extension; * support included in the header to the server. Notice this * callback comes to protocols[0]. * + * LWS_CALLBACK_PROTOCOL_INIT: One-time call per protocol so it can + * do initial setup / allocations etc + * + * LWS_CALLBACK_PROTOCOL_DESTROY: One-time call per protocol indicating + * this protocol won't get used at all after this callback, the + * context is getting destroyed. Take the opportunity to + * deallocate everything that was allocated by the protocol. + * * The next four reasons are optional and only need taking care of if you * will be integrating libwebsockets sockets into an external polling * array. diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html index a3f6415ef1523334cdb192e501d8e020abbc0d13..726b68864d192304ba9d384e4ad3c78f36e1e631 100644 --- a/libwebsockets-api-doc.html +++ b/libwebsockets-api-doc.html @@ -752,6 +752,18 @@ claim to support that extension by returning non-zero. If unhandled, by default 0 will be returned and the extension support included in the header to the server. Notice this callback comes to protocols[0]. +</blockquote> +<h3>LWS_CALLBACK_PROTOCOL_INIT</h3> +<blockquote> +One-time call per protocol so it can +do initial setup / allocations etc +</blockquote> +<h3>LWS_CALLBACK_PROTOCOL_DESTROY</h3> +<blockquote> +One-time call per protocol indicating +this protocol won't get used at all after this callback, the +context is getting destroyed. Take the opportunity to +deallocate everything that was allocated by the protocol. <p> The next four reasons are optional and only need taking care of if you will be integrating libwebsockets sockets into an external polling diff --git a/test-server/test-server.c b/test-server/test-server.c index d786f4b7e7680f589f9adfc5e5a5fa7104ddd7ca..388303e820b2da7a7d142e461b8763f3b4377e13 100644 --- a/test-server/test-server.c +++ b/test-server/test-server.c @@ -356,6 +356,13 @@ callback_lws_mirror(struct libwebsocket_context *context, pss->wsi = wsi; break; + case LWS_CALLBACK_PROTOCOL_DESTROY: + lwsl_notice("mirror protocol cleaning up\n"); + for (n = 0; n < sizeof ringbuffer / sizeof ringbuffer[0]; n++) + if (ringbuffer[n].payload) + free(ringbuffer[n].payload); + break; + case LWS_CALLBACK_SERVER_WRITEABLE: if (close_testing) break;