mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
event libs: default to building as dynamically loaded plugins
Event lib support as it has been isn't scaling well, at the low level libevent and libev headers have a namespace conflict so they can't both be built into the same image, and at the distro level, binding all the event libs to libwebsockets.so makes a bloaty situation for packaging, lws will drag in all the event libs every time. This patch implements the plan discussed here https://github.com/warmcat/libwebsockets/issues/1980 and refactors the event lib support so they are built into isolated plugins and bound at runtime according to what the application says it wants to use. The event lib plugins can be packaged individually so that only the needed sets of support are installed (perhaps none of them if the user code is OK with the default poll() loop). And dependent user code can mark the specific event loop plugin package as required so pieces are added as needed. The eventlib-foreign example is also refactored to build the selected lib support isolated. A readme is added detailing the changes and how to use them. https://libwebsockets.org/git/libwebsockets/tree/READMEs/README.event-libs.md
This commit is contained in:
parent
d98101d1e3
commit
c6c7ab2b44
57 changed files with 1480 additions and 839 deletions
|
@ -12,7 +12,7 @@
|
|||
"build": "mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G DEB\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
|
||||
},
|
||||
"linux-fedora-32/x86_64-amd/gcc": {
|
||||
"build": "mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G RPM\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
|
||||
"build": "rm -rf build destdir ; mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G RPM\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
|
||||
},
|
||||
"linux-gentoo/x86_64-amd/gcc": {
|
||||
"build": "mkdir build destdir;cd build;export CCACHE_DISABLE=1;export SAI_CPACK=\"-G ZIP\";cmake .. ${cmake} && make -j && make -j DESTDIR=../destdir install && ctest -j4 --output-on-failure ${cpack}"
|
||||
|
|
|
@ -86,8 +86,8 @@ if(LWS_WITH_DISTRO_RECOMMENDED)
|
|||
set(LWS_WITH_GLIB 1) # glib
|
||||
set(LWS_WITH_LIBUV 1) # libuv
|
||||
set(LWS_WITH_LIBEV 1) # libev
|
||||
# libev + libevent cannot coexist at build-time
|
||||
set(LWS_WITH_LIBEVENT 0)
|
||||
set(LWS_WITH_LIBEVENT 1) # libevent
|
||||
set(LWS_WITH_EVLIB_PLUGINS 1) # event libraries created as plugins / individual packages
|
||||
set(LWS_WITHOUT_EXTENSIONS 0) # libz
|
||||
set(LWS_ROLE_DBUS 1) # dbus-related libs
|
||||
set(LWS_WITH_FTS 1) # selfcontained
|
||||
|
@ -112,6 +112,17 @@ if(LWS_WITH_DISTRO_RECOMMENDED)
|
|||
set(LWS_WITH_DIR 1) # selfcontained
|
||||
endif()
|
||||
|
||||
# LWS_WITH_EVENT_LIBS is set if any event lib selected
|
||||
|
||||
if (LWS_WITH_LIBEV OR
|
||||
LWS_WITH_LIBUV OR
|
||||
LWS_WITH_LIBEVENT OR
|
||||
LWS_WITH_GLIB)
|
||||
set(LWS_WITH_EVENT_LIBS 1)
|
||||
else()
|
||||
unset(LWS_WITH_EVENT_LIBS)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_SECURE_STREAMS_PROXY_API)
|
||||
set(LWS_WITH_LWS_DSH 1)
|
||||
set(LWS_WITH_UNIX_SOCK 1)
|
||||
|
@ -184,10 +195,14 @@ if (NOT LWS_ROLE_WS)
|
|||
set(LWS_WITHOUT_EXTENSIONS 1)
|
||||
endif()
|
||||
|
||||
unset(LWS_WITH_LIBUV_INTERNAL)
|
||||
|
||||
if (LWS_WITH_LWSWS)
|
||||
message(STATUS "LWS_WITH_LWSWS --> Enabling LWS_WITH_PLUGINS and LWS_WITH_LIBUV")
|
||||
set(LWS_WITH_PLUGINS 1)
|
||||
set(LWS_WITH_LIBUV 1)
|
||||
set(LWS_WITH_LIBUV_INTERNAL 1)
|
||||
set(LWS_WITH_EVENT_LIBS 1) # implied by LIBUV_INTERNAL
|
||||
set(LWS_WITH_ACCESS_LOG 1)
|
||||
set(LWS_WITH_SERVER_STATUS 1)
|
||||
set(LWS_WITH_LEJP 1)
|
||||
|
@ -249,6 +264,9 @@ endif()
|
|||
|
||||
if (WIN32)
|
||||
set(LWS_MAX_SMP 1)
|
||||
if (LWS_WITH_PLUGINS)
|
||||
set(LWS_WITH_LIBUV_INTERNAL 1)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (LWS_WITHOUT_SERVER)
|
||||
|
@ -355,7 +373,7 @@ endif()
|
|||
# set(LWS_WITH_ABSTRACT 1)
|
||||
#endif()
|
||||
|
||||
if (LWS_WITH_LIBEV AND LWS_WITH_LIBEVENT)
|
||||
if (NOT LWS_WITH_EVLIB_PLUGINS AND (LWS_WITH_LIBEV AND LWS_WITH_LIBEVENT))
|
||||
message(FATAL_ERROR "Sorry libev and libevent conflict with each others' namespace, you can only have one or the other")
|
||||
endif()
|
||||
|
||||
|
|
|
@ -153,6 +153,13 @@ option(LWS_WITH_LIBUV "Compile with support for libuv" OFF)
|
|||
option(LWS_WITH_LIBEVENT "Compile with support for libevent" OFF)
|
||||
option(LWS_WITH_GLIB "Compile with support for glib event loop" OFF)
|
||||
|
||||
if (UNIX)
|
||||
# since v4.1, on unix platforms default is build any event libs as runtime plugins
|
||||
option(LWS_WITH_EVLIB_PLUGINS "Compile event lib support into runtime-selected plugins" ON)
|
||||
else()
|
||||
# otherwise default to linking the event lib(s) to libwebsockets.so
|
||||
option(LWS_WITH_EVLIB_PLUGINS "Compile event lib support into runtime-selected plugins" OFF)
|
||||
endif()
|
||||
#
|
||||
# LWS Drivers
|
||||
#
|
||||
|
@ -353,15 +360,19 @@ set(VERSION "${CPACK_PACKAGE_VERSION}")
|
|||
|
||||
set(CPACK_RPM_PACKAGE_RELEASE_DIST ON)
|
||||
set(CPACK_RPM_FILE_NAME "RPM-DEFAULT")
|
||||
set(CPACK_RPM_DEBUGINFO_PACKAGE ON)
|
||||
# below makes path length problems in CI
|
||||
set(CPACK_RPM_DEBUGINFO_PACKAGE OFF)
|
||||
# below makes some kind of chimera rpm with binaries and sources
|
||||
set(CPACK_RPM_PACKAGE_SOURCES OFF)
|
||||
set(CPACK_RPM_INSTALL_WITH_EXEC ON)
|
||||
set(CPACK_RPM_COMPONENT_INSTALL ON)
|
||||
|
||||
set(CPACK_DEBIAN_FILE_NAME "DEB-DEFAULT")
|
||||
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
|
||||
set(CPACK_DEBIAN_DEBUGINFO_PACKAGE ON)
|
||||
set(CPACK_DEBIAN_PACKAGE_SOURCE ON)
|
||||
set(CPACK_DEBIAN_COMPONENT_INSTALL ON)
|
||||
|
||||
|
||||
set(LWS_LIBRARY_VERSION ${CPACK_PACKAGE_VERSION})
|
||||
set(LWS_LIBRARY_VERSION_MAJOR ${CPACK_PACKAGE_VERSION_MAJOR})
|
||||
|
@ -916,9 +927,9 @@ endif()
|
|||
export(PACKAGE libwebsockets)
|
||||
|
||||
install(DIRECTORY include/libwebsockets
|
||||
DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev_headers)
|
||||
DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev)
|
||||
install(FILES ${PROJECT_BINARY_DIR}/include/libwebsockets.h ${PROJECT_BINARY_DIR}/include/lws_config.h
|
||||
DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev_headers)
|
||||
DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev)
|
||||
|
||||
# Generate the config file for the installation tree.
|
||||
get_filename_component(LWS_ABSOLUTE_INSTALL_CMAKE_DIR ${LWS_INSTALL_CMAKE_DIR} ABSOLUTE)
|
||||
|
|
80
READMEs/README.event-libs.md
Normal file
80
READMEs/README.event-libs.md
Normal file
|
@ -0,0 +1,80 @@
|
|||
# lws event library support
|
||||
|
||||
## v4.0 and below
|
||||
|
||||
Before v4.1, lws allowed selecting some event library support for inclusion
|
||||
in the libwebsockets library
|
||||
|
||||
Option|Feature
|
||||
---|---
|
||||
`LWS_WITH_GLIB`|glib
|
||||
`LWS_WITH_LIBEVENT`|libevent
|
||||
`LWS_WITH_LIBUV`|libuv
|
||||
`LWS_WITH_LIBEV`|libev
|
||||
|
||||
The user code can select by `info->options` flags at runtime which event loop
|
||||
it wants to use.
|
||||
|
||||
The only restriction is that libev and libevent can't coexist, because their
|
||||
header namespace conflicts.
|
||||
|
||||
## v4.1 and above
|
||||
|
||||
Lws continues to support the old way described above, but there's an additional
|
||||
new cmake option that decides how they are built if any are selected,
|
||||
`LWS_WITH_EVLIB_PLUGINS`.
|
||||
|
||||
The old behaviour is set by `LWS_WITH_EVLIB_PLUGINS=0`, for UNIX platforms, this
|
||||
is set to 1 by default. This causes the enabled event lib support to each be built into
|
||||
its own dynamically linked plugin, and lws will bring in the requested support alone
|
||||
at runtime after seeing the `info->options` flags requested by the user code.
|
||||
|
||||
This has two main benefits, first the conflict around building libevent and libev
|
||||
together is removed, they each build isolated in their own plugin; the libwebsockets
|
||||
core library build doesn't import any of their headers (see below for exception).
|
||||
And second, for distro packaging, the event lib support plugins can be separately
|
||||
packaged, and apps take dependencies on the specific event lib plugin package, which
|
||||
itself depends on the libwebsockets core library. This allows just the needed
|
||||
dependencies for the packageset without forcing everything to bring everything in.
|
||||
|
||||
Separately, lws itself has some optional dependencies on libuv, if you build lwsws
|
||||
or on Windows you want plugins at all. CMake will detect these situations and
|
||||
select to link the lws library itself to libuv if so as well, independent of whatever
|
||||
is happening with the event lib support.
|
||||
|
||||
## evlib plugin install
|
||||
|
||||
The produced plugins are named
|
||||
|
||||
event lib|plugin name
|
||||
---|---
|
||||
glib|`libwebsockets-evlib_glib.so`
|
||||
event|`libwebsockets-evlib_event.so`
|
||||
uv|`libwebsockets-evlib_uv.so`
|
||||
ev|`libwebsockets-evlib_ev.so`
|
||||
|
||||
The evlib plugins are installed alongside libwebsockets.so/.a into the configured
|
||||
library dir, it's often `/usr/local/lib/` by default on linux.
|
||||
|
||||
Lws looks for them at runtime using the build-time-configured path.
|
||||
|
||||
## Component packaging
|
||||
|
||||
The canonical package name is `libwebsockets`, the recommended way to split the
|
||||
packaging is put the expected libs and pkgconfig in `libwebsockets` or `libwebsockets-core`,
|
||||
the latter is followed by the provided cmake, and produce an additional package per build
|
||||
event library plugin, named, eg `libwebsockets-evlib_glib`, which has a dependency on
|
||||
`libwebsockets[-core]`.
|
||||
|
||||
Applications that use the default event loop can directly require `libwebsockets[-core]`,
|
||||
and application packages that need specific event loop support can just require, eg,
|
||||
`libwebsockets-evlib_glib`, which will bring that in and the core lws pieces in one step.
|
||||
There is then no problem with multiple apps requiring different event libs, they will
|
||||
bring in all the necessary pieces which will not conflict either as packages or at
|
||||
runtime.
|
||||
|
||||
## `LWS_WITH_DISTRO_RECOMMENDED`
|
||||
|
||||
The cmake helper config `LWS_WITH_DISTRO_RECOMMENDED` is adapted to build all the
|
||||
event libs with the event lib plugin support enabled.
|
||||
|
|
@ -7,6 +7,7 @@
|
|||
#endif
|
||||
|
||||
#define LWS_INSTALL_DATADIR "${CMAKE_INSTALL_PREFIX}/share"
|
||||
#define LWS_INSTALL_LIBDIR "${CMAKE_INSTALL_PREFIX}/${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}"
|
||||
#define LWS_LIBRARY_VERSION_MAJOR ${LWS_LIBRARY_VERSION_MAJOR}
|
||||
#define LWS_LIBRARY_VERSION_MINOR ${LWS_LIBRARY_VERSION_MINOR}
|
||||
#define LWS_LIBRARY_VERSION_PATCH_ELABORATED ${LWS_LIBRARY_VERSION_PATCH_ELABORATED}
|
||||
|
@ -189,4 +190,7 @@
|
|||
#cmakedefine LWS_WITH_ZIP_FOPS
|
||||
#cmakedefine USE_OLD_CYASSL
|
||||
#cmakedefine USE_WOLFSSL
|
||||
#cmakedefine LWS_WITH_EVENT_LIBS
|
||||
#cmakedefine LWS_WITH_EVLIB_PLUGINS
|
||||
#cmakedefine LWS_WITH_LIBUV_INTERNAL
|
||||
|
||||
|
|
|
@ -190,21 +190,17 @@ typedef unsigned long long lws_intptr_t;
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
#include <ev.h>
|
||||
#endif /* LWS_WITH_LIBEV */
|
||||
#ifdef LWS_WITH_LIBUV
|
||||
#if defined(LWS_WITH_LIBUV_INTERNAL)
|
||||
#include <uv.h>
|
||||
|
||||
#ifdef LWS_HAVE_UV_VERSION_H
|
||||
#include <uv-version.h>
|
||||
#endif
|
||||
|
||||
#ifdef LWS_HAVE_NEW_UV_VERSION_H
|
||||
#include <uv/version.h>
|
||||
#endif
|
||||
#endif /* LWS_WITH_LIBUV */
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
#include <event2/event.h>
|
||||
#endif /* LWS_WITH_LIBEVENT */
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
|
||||
|
@ -610,6 +606,7 @@ struct lws;
|
|||
|
||||
#endif
|
||||
|
||||
#include <libwebsockets/lws-eventlib-exports.h>
|
||||
#include <libwebsockets/lws-i2c.h>
|
||||
#include <libwebsockets/lws-spi.h>
|
||||
#include <libwebsockets/lws-gpio.h>
|
||||
|
|
61
include/libwebsockets/lws-eventlib-exports.h
Normal file
61
include/libwebsockets/lws-eventlib-exports.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
* deal in the Software without restriction, including without limitation the
|
||||
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
* sell copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* These are exports needed by event lib plugins.
|
||||
*
|
||||
* You should consider these opaque for normal user code.
|
||||
*/
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void *
|
||||
lws_realloc(void *ptr, size_t size, const char *reason);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lws_vhost_destroy1(struct lws_vhost *vh);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lws_close_free_wsi(struct lws *wsi, enum lws_close_status reason,
|
||||
const char *caller);
|
||||
|
||||
struct lws_context_per_thread;
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lws_service_do_ripe_rxflow(struct lws_context_per_thread *pt);
|
||||
|
||||
#if !defined(wsi_from_fd) && !defined(WIN32) && !defined(_WIN32)
|
||||
struct lws_context;
|
||||
LWS_VISIBLE LWS_EXTERN struct lws *
|
||||
wsi_from_fd(const struct lws_context *context, int fd);
|
||||
#endif
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
_lws_plat_service_forced_tsi(struct lws_context *context, int tsi);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lws_context_destroy2(struct lws_context *context);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
lws_destroy_event_pipe(struct lws *wsi);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN void
|
||||
__lws_close_free_wsi_final(struct lws *wsi);
|
||||
|
||||
|
|
@ -194,8 +194,6 @@ lws_pvo_get_str(void *in, const char *name, const char **result);
|
|||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_protocol_init(struct lws_context *context);
|
||||
|
||||
#ifdef LWS_WITH_PLUGINS
|
||||
|
||||
#define LWS_PLUGIN_API_MAGIC 190
|
||||
|
||||
/*
|
||||
|
@ -244,7 +242,7 @@ struct lws_plugin {
|
|||
const lws_plugin_header_t *hdr;
|
||||
|
||||
union {
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
#if defined(LWS_WITH_LIBUV) && defined(UV_ERRNO_MAP)
|
||||
#if (UV_VERSION_MAJOR > 0)
|
||||
uv_lib_t lib; /**< shared library pointer */
|
||||
#endif
|
||||
|
@ -253,6 +251,16 @@ struct lws_plugin {
|
|||
} u;
|
||||
};
|
||||
|
||||
/*
|
||||
* Event lib library plugin type (when LWS_WITH_EVLIB_PLUGINS)
|
||||
* Public so new event libs can equally be supported outside lws itself
|
||||
*/
|
||||
|
||||
typedef struct lws_plugin_evlib {
|
||||
lws_plugin_header_t hdr;
|
||||
const struct lws_event_loop_ops *ops;
|
||||
} lws_plugin_evlib_t;
|
||||
|
||||
typedef int (*each_plugin_cb_t)(struct lws_plugin *p, void *user);
|
||||
|
||||
/**
|
||||
|
@ -297,6 +305,5 @@ lws_plugins_init(struct lws_plugin **pplugin, const char * const *d,
|
|||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_plugins_destroy(struct lws_plugin **pplugin, each_plugin_cb_t each,
|
||||
void *each_user);
|
||||
#endif
|
||||
|
||||
///@}
|
||||
|
|
|
@ -167,7 +167,8 @@ lws_handle_POLLOUT_event(struct lws *wsi, struct lws_pollfd *pollfd);
|
|||
* APIs specific to libuv event loop itegration
|
||||
*/
|
||||
///@{
|
||||
#ifdef LWS_WITH_LIBUV
|
||||
#if defined(LWS_WITH_LIBUV) && defined(UV_ERRNO_MAP)
|
||||
|
||||
/*
|
||||
* Any direct libuv allocations in lws protocol handlers must participate in the
|
||||
* lws reference counting scheme. Two apis are provided:
|
||||
|
|
|
@ -122,7 +122,6 @@ configure_file(
|
|||
add_subdir_include_dirs(core)
|
||||
add_subdir_include_dirs(misc)
|
||||
add_subdir_include_dirs(system)
|
||||
add_subdir_include_dirs(event-libs)
|
||||
|
||||
if (LWS_WITH_DRIVERS)
|
||||
add_subdir_include_dirs(drivers)
|
||||
|
@ -144,6 +143,8 @@ if (LWS_WITH_SECURE_STREAMS)
|
|||
add_subdir_include_dirs(secure-streams)
|
||||
endif()
|
||||
|
||||
add_subdir_include_dirs(event-libs)
|
||||
|
||||
if (LWS_WITH_STATIC)
|
||||
if (LWS_STATIC_PIC)
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
@ -249,12 +250,12 @@ endif()
|
|||
# Install libs and headers.
|
||||
install(TARGETS ${LWS_LIBRARIES}
|
||||
EXPORT LibwebsocketsTargets
|
||||
LIBRARY DESTINATION "${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}" COMPONENT libraries
|
||||
ARCHIVE DESTINATION "${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}" COMPONENT libraries
|
||||
RUNTIME DESTINATION "${LWS_INSTALL_BIN_DIR}" COMPONENT libraries # Windows DLLs
|
||||
LIBRARY DESTINATION "${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}" COMPONENT core
|
||||
ARCHIVE DESTINATION "${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}" COMPONENT core
|
||||
RUNTIME DESTINATION "${LWS_INSTALL_BIN_DIR}" COMPONENT core # Windows DLLs
|
||||
PUBLIC_HEADER DESTINATION "${LWS_INSTALL_INCLUDE_DIR}" COMPONENT dev)
|
||||
|
||||
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries" PARENT_SCOPE)
|
||||
#set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Libraries" PARENT_SCOPE)
|
||||
set(CPACK_COMPONENT_DEV_DISPLAY_NAME "Development files" PARENT_SCOPE)
|
||||
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi)
|
|||
{
|
||||
struct lws *new_wsi;
|
||||
int n = fixed_tsi;
|
||||
size_t s = sizeof(struct lws);
|
||||
|
||||
if (n < 0)
|
||||
n = lws_get_idlest_tsi(vhost->context);
|
||||
|
@ -58,12 +59,20 @@ lws_create_new_server_wsi(struct lws_vhost *vhost, int fixed_tsi)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
new_wsi = lws_zalloc(sizeof(struct lws), "new server wsi");
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
s += vhost->context->event_loop_ops->evlib_size_wsi;
|
||||
#endif
|
||||
|
||||
new_wsi = lws_zalloc(s, "new server wsi");
|
||||
if (new_wsi == NULL) {
|
||||
lwsl_err("Out of memory for new connection\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
new_wsi->evlib_wsi = (uint8_t *)new_wsi + sizeof(*new_wsi);
|
||||
#endif
|
||||
|
||||
new_wsi->wsistate |= LWSIFR_SERVER;
|
||||
new_wsi->tsi = n;
|
||||
lwsl_debug("new wsi %p joining vhost %s, tsi %d\n", new_wsi,
|
||||
|
|
|
@ -31,6 +31,7 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
const char *local = i->protocol;
|
||||
struct lws *wsi, *safe = NULL;
|
||||
const struct lws_protocols *p;
|
||||
size_t s = sizeof(struct lws);
|
||||
const char *cisin[CIS_COUNT];
|
||||
int tid = 0, n, m;
|
||||
size_t size;
|
||||
|
@ -54,10 +55,18 @@ lws_client_connect_via_info(const struct lws_client_connect_info *i)
|
|||
|
||||
/* PHASE 1: create a bare wsi */
|
||||
|
||||
wsi = lws_zalloc(sizeof(struct lws), "client wsi");
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
s += i->context->event_loop_ops->evlib_size_wsi;
|
||||
#endif
|
||||
|
||||
wsi = lws_zalloc(s, "client wsi");
|
||||
if (wsi == NULL)
|
||||
goto bail;
|
||||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
wsi->evlib_wsi = (uint8_t *)wsi + sizeof(*wsi);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Until we exit, we can report connection failure directly to the
|
||||
* caller without needing to call through to protocol CONNECTION_ERROR.
|
||||
|
|
|
@ -27,8 +27,7 @@
|
|||
int
|
||||
_lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)
|
||||
{
|
||||
#if !defined(LWS_WITH_LIBUV) && !defined(LWS_WITH_LIBEV) && \
|
||||
!defined(LWS_WITH_LIBEVENT) && !defined(LWS_WITH_GLIB)
|
||||
#if !defined(LWS_WITH_EVENT_LIBS)
|
||||
volatile struct lws_context_per_thread *vpt;
|
||||
#endif
|
||||
struct lws_context_per_thread *pt;
|
||||
|
@ -72,8 +71,7 @@ _lws_change_pollfd(struct lws *wsi, int _and, int _or, struct lws_pollargs *pa)
|
|||
|
||||
assert(wsi->position_in_fds_table < (int)pt->fds_count);
|
||||
|
||||
#if !defined(LWS_WITH_LIBUV) && !defined(LWS_WITH_LIBEV) && \
|
||||
!defined(LWS_WITH_LIBEVENT) && !defined(LWS_WITH_GLIB)
|
||||
#if !defined(LWS_WITH_EVENT_LIBS)
|
||||
/*
|
||||
* This only applies when we use the default poll() event loop.
|
||||
*
|
||||
|
|
|
@ -428,22 +428,8 @@ struct lws_context_per_thread {
|
|||
#endif
|
||||
/* --- event library based members --- */
|
||||
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
struct lws_pt_eventlibs_libev ev;
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
struct lws_pt_eventlibs_libuv uv;
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
struct lws_pt_eventlibs_libevent event;
|
||||
#endif
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
struct lws_pt_eventlibs_glib glib;
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || \
|
||||
defined(LWS_WITH_LIBEVENT) || defined(LWS_WITH_GLIB)
|
||||
struct lws_signal_watcher w_sigint;
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
void *evlib_pt; /* overallocated */
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_DETAILED_LATENCY)
|
||||
|
@ -530,8 +516,8 @@ struct lws_vhost {
|
|||
char socks_user[96];
|
||||
char socks_password[96];
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
struct lws_io_watcher w_accept;
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
void *evlib_vh; /* overallocated */
|
||||
#endif
|
||||
#if defined(LWS_WITH_SERVER_STATUS)
|
||||
struct lws_conn_stats conn_stats;
|
||||
|
@ -719,12 +705,8 @@ struct lws {
|
|||
|
||||
/* lifetime members */
|
||||
|
||||
#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || \
|
||||
defined(LWS_WITH_LIBEVENT) || defined(LWS_WITH_GLIB)
|
||||
struct lws_io_watcher w_read;
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBEVENT)
|
||||
struct lws_io_watcher w_write;
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
void *evlib_wsi; /* overallocated */
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_DETAILED_LATENCY)
|
||||
|
@ -1158,6 +1140,7 @@ lws_libuv_closehandle(struct lws *wsi);
|
|||
int
|
||||
lws_libuv_check_watcher_active(struct lws *wsi);
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS) || defined(LWS_WITH_PLUGINS)
|
||||
const lws_plugin_header_t *
|
||||
lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
|
||||
const char *sofilename, const char *_class,
|
||||
|
@ -1165,6 +1148,7 @@ lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
|
|||
|
||||
int
|
||||
lws_plat_destroy_dl(struct lws_plugin *p);
|
||||
#endif
|
||||
|
||||
struct lws *
|
||||
lws_adopt_socket_vhost(struct lws_vhost *vh, lws_sockfd_type accept_fd);
|
||||
|
|
|
@ -175,9 +175,9 @@ lws_json_dump_context(const struct lws_context *context, char *buf, int len,
|
|||
struct lws_cgi * const *pcgi;
|
||||
#endif
|
||||
|
||||
#ifdef LWS_WITH_LIBUV
|
||||
uv_uptime(&d);
|
||||
#endif
|
||||
//#ifdef LWS_WITH_LIBUV &&
|
||||
// uv_uptime(&d);
|
||||
//#endif
|
||||
|
||||
buf += lws_snprintf(buf, end - buf, "{ "
|
||||
"\"version\":\"%s\",\n"
|
||||
|
|
|
@ -714,6 +714,8 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,
|
|||
case LWS_HPI_RET_HANDLED:
|
||||
break;
|
||||
case LWS_HPI_RET_PLEASE_CLOSE_ME:
|
||||
lwsl_notice("%s: %s pollin says please close me\n", __func__,
|
||||
wsi->role_ops->name);
|
||||
close_and_handled:
|
||||
lwsl_debug("%p: Close and handled\n", wsi);
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
|
||||
|
@ -724,7 +726,7 @@ close_and_handled:
|
|||
* it waits for libuv service to complete the first async
|
||||
* close
|
||||
*/
|
||||
if (context->event_loop_ops == &event_loop_ops_uv)
|
||||
if (!strcmp(context->event_loop_ops->name, "libuv"))
|
||||
lws_close_free_wsi(wsi, LWS_CLOSE_STATUS_NOSTATUS,
|
||||
"close_and_handled uv repeat test");
|
||||
#endif
|
||||
|
|
|
@ -46,22 +46,6 @@ const struct lws_role_ops *available_roles[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
const struct lws_event_loop_ops *available_event_libs[] = {
|
||||
#if defined(LWS_WITH_POLL)
|
||||
&event_loop_ops_poll,
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
&event_loop_ops_uv,
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
&event_loop_ops_event,
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
&event_loop_ops_ev,
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
|
||||
#if defined(LWS_WITH_ABSTRACT)
|
||||
const struct lws_protocols *available_abstract_protocols[] = {
|
||||
#if defined(LWS_ROLE_RAW)
|
||||
|
@ -471,8 +455,7 @@ struct lws_vhost *
|
|||
lws_create_vhost(struct lws_context *context,
|
||||
const struct lws_context_creation_info *info)
|
||||
{
|
||||
struct lws_vhost *vh = lws_zalloc(sizeof(*vh), "create vhost"),
|
||||
**vh1 = &context->vhost_list;
|
||||
struct lws_vhost *vh, **vh1 = &context->vhost_list;
|
||||
const struct lws_http_mount *mounts;
|
||||
const struct lws_protocols *pcols = info->protocols;
|
||||
#ifdef LWS_WITH_PLUGINS
|
||||
|
@ -490,9 +473,19 @@ lws_create_vhost(struct lws_context *context,
|
|||
#endif
|
||||
int n;
|
||||
|
||||
|
||||
vh = lws_zalloc(sizeof(*vh)
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
+ context->event_loop_ops->evlib_size_vh
|
||||
#endif
|
||||
, __func__);
|
||||
if (!vh)
|
||||
return NULL;
|
||||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
vh->evlib_vh = (void *)&vh[1];
|
||||
#endif
|
||||
|
||||
#if LWS_MAX_SMP > 1
|
||||
pthread_mutex_init(&vh->lock, NULL);
|
||||
#endif
|
||||
|
@ -915,6 +908,7 @@ lws_cancel_service(struct lws_context *context)
|
|||
int
|
||||
lws_create_event_pipes(struct lws_context *context)
|
||||
{
|
||||
size_t s = sizeof(struct lws);
|
||||
struct lws *wsi;
|
||||
int n;
|
||||
|
||||
|
@ -932,11 +926,18 @@ lws_create_event_pipes(struct lws_context *context)
|
|||
if (context->pt[n].pipe_wsi)
|
||||
return 0;
|
||||
|
||||
wsi = lws_zalloc(sizeof(*wsi), "event pipe wsi");
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
s += context->event_loop_ops->evlib_size_wsi;
|
||||
#endif
|
||||
|
||||
wsi = lws_zalloc(s, "event pipe wsi");
|
||||
if (!wsi) {
|
||||
lwsl_err("%s: Out of mem\n", __func__);
|
||||
return 1;
|
||||
}
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
wsi->evlib_wsi = (uint8_t *)wsi + sizeof(*wsi);
|
||||
#endif
|
||||
wsi->a.context = context;
|
||||
lws_role_transition(wsi, 0, LRS_UNCONNECTED, &role_ops_pipe);
|
||||
wsi->a.protocol = NULL;
|
||||
|
|
|
@ -850,8 +850,7 @@ _lws_generic_transaction_completed_active_conn(struct lws **_wsi, char take_vh_l
|
|||
* new guy and snuff out the old guy's magic spark at that level as well
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_LIBEV) || defined(LWS_WITH_LIBUV) || \
|
||||
defined(LWS_WITH_LIBEVENT) || defined(LWS_WITH_GLIB)
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
if (wsi->a.context->event_loop_ops->destroy_wsi)
|
||||
wsi->a.context->event_loop_ops->destroy_wsi(wsi);
|
||||
if (wsi->a.context->event_loop_ops->sock_accept)
|
||||
|
|
|
@ -331,6 +331,22 @@ static const char * const opts_str =
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS)
|
||||
static const struct lws_evlib_map {
|
||||
uint64_t flag;
|
||||
const char *name;
|
||||
} map[] = {
|
||||
{ LWS_SERVER_OPTION_LIBUV, "evlib_uv" },
|
||||
{ LWS_SERVER_OPTION_LIBEVENT, "evlib_event" },
|
||||
{ LWS_SERVER_OPTION_GLIB, "evlib_glib" },
|
||||
{ LWS_SERVER_OPTION_LIBEV, "evlib_ev" },
|
||||
};
|
||||
static const char * const dlist[] = {
|
||||
LWS_INSTALL_LIBDIR,
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
struct lws_context *
|
||||
lws_create_context(const struct lws_context_creation_info *info)
|
||||
{
|
||||
|
@ -360,6 +376,10 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
#endif
|
||||
size = sizeof(struct lws_context);
|
||||
int n, lpf = info->fd_limit_per_thread;
|
||||
const lws_plugin_evlib_t *plev = NULL;
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS)
|
||||
struct lws_plugin *evlib_plugin_list = NULL;
|
||||
#endif
|
||||
|
||||
if (lpf) {
|
||||
lpf+= 2;
|
||||
|
@ -407,6 +427,102 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
#if !defined(LWS_PLAT_FREERTOS)
|
||||
size += (count_threads * sizeof(struct lws));
|
||||
#endif
|
||||
#endif /* network */
|
||||
|
||||
#if defined(LWS_WITH_POLL)
|
||||
{
|
||||
extern const lws_plugin_evlib_t evlib_poll;
|
||||
plev = &evlib_poll;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS)
|
||||
|
||||
/*
|
||||
* New style dynamically loaded event lib support
|
||||
*
|
||||
* We have to pick and load the event lib plugin before we allocate
|
||||
* the context object, so we can overallocate it correctly
|
||||
*/
|
||||
|
||||
lwsl_info("%s: ev lib path %s\n", __func__, LWS_INSTALL_LIBDIR);
|
||||
|
||||
for (n = 0; n < (int)LWS_ARRAY_SIZE(map); n++) {
|
||||
if (!lws_check_opt(info->options, map[n].flag))
|
||||
continue;
|
||||
|
||||
if (lws_plugins_init(&evlib_plugin_list,
|
||||
dlist, "lws_evlib_plugin",
|
||||
map[n].name, NULL, NULL)) {
|
||||
lwsl_err("%s: failed to load %s\n", __func__,
|
||||
map[n].name);
|
||||
goto bail;
|
||||
}
|
||||
|
||||
if (!evlib_plugin_list) {
|
||||
lwsl_err("%s: unable to load evlib plugin %s\n",
|
||||
__func__, map[n].name);
|
||||
|
||||
goto bail;
|
||||
}
|
||||
plev = (const lws_plugin_evlib_t *)evlib_plugin_list->hdr;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
/*
|
||||
* set the context event loops ops struct
|
||||
*
|
||||
* after this, all event_loop actions use the generic ops
|
||||
*/
|
||||
|
||||
/*
|
||||
* oldstyle built-in event lib support
|
||||
*
|
||||
* We have composed them into the libwebsockets lib itself, we can
|
||||
* just pick the ops we want and done
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBUV)) {
|
||||
extern const lws_plugin_evlib_t evlib_uv;
|
||||
plev = &evlib_uv;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBEVENT)) {
|
||||
extern const lws_plugin_evlib_t evlib_event;
|
||||
plev = &evlib_event;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
if (lws_check_opt(info->options, LWS_SERVER_OPTION_GLIB)) {
|
||||
extern const lws_plugin_evlib_t evlib_glib;
|
||||
plev = &evlib_glib;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
if (lws_check_opt(info->options, LWS_SERVER_OPTION_LIBEV)) {
|
||||
extern const lws_plugin_evlib_t evlib_ev;
|
||||
plev = &evlib_ev;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* with event libs */
|
||||
|
||||
#endif /* not with ev plugins */
|
||||
|
||||
if (!plev)
|
||||
goto fail_event_libs;
|
||||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
size += plev->ops->evlib_size_ctx /* the ctx evlib priv */ +
|
||||
(count_threads * plev->ops->evlib_size_pt) /* the pt evlib priv */;
|
||||
|
||||
lwsl_info("Event loop: %s\n", plev->ops->name);
|
||||
#endif
|
||||
|
||||
context = lws_zalloc(size, "context");
|
||||
|
@ -415,6 +531,18 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
context->event_loop_ops = plev->ops;
|
||||
#endif
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
/* at the very end */
|
||||
context->evlib_ctx = (uint8_t *)context + size -
|
||||
plev->ops->evlib_size_ctx;
|
||||
#endif
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS)
|
||||
context->evlib_plugin_list = evlib_plugin_list;
|
||||
#endif
|
||||
|
||||
#if !defined(LWS_PLAT_FREERTOS)
|
||||
context->uid = info->uid;
|
||||
context->gid = info->gid;
|
||||
|
@ -460,7 +588,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
if (info->extensions)
|
||||
lwsl_warn("%s: LWS_WITHOUT_EXTENSIONS but extensions ptr set\n", __func__);
|
||||
#endif
|
||||
#endif
|
||||
#endif /* network */
|
||||
|
||||
#if defined(LWS_WITH_SECURE_STREAMS)
|
||||
#if !defined(LWS_WITH_SECURE_STREAMS_STATIC_POLICY_ONLY)
|
||||
|
@ -603,52 +731,9 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
}
|
||||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
|
||||
context->token_limits = info->token_limits;
|
||||
|
||||
/*
|
||||
* set the context event loops ops struct
|
||||
*
|
||||
* after this, all event_loop actions use the generic ops
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_POLL)
|
||||
context->event_loop_ops = &event_loop_ops_poll;
|
||||
#endif
|
||||
|
||||
if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV))
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
context->event_loop_ops = &event_loop_ops_uv;
|
||||
#else
|
||||
goto fail_event_libs;
|
||||
#endif
|
||||
|
||||
if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEV))
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
context->event_loop_ops = &event_loop_ops_ev;
|
||||
#else
|
||||
goto fail_event_libs;
|
||||
#endif
|
||||
|
||||
if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBEVENT))
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
context->event_loop_ops = &event_loop_ops_event;
|
||||
#else
|
||||
goto fail_event_libs;
|
||||
#endif
|
||||
|
||||
if (lws_check_opt(context->options, LWS_SERVER_OPTION_GLIB))
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
context->event_loop_ops = &event_loop_ops_glib;
|
||||
#else
|
||||
goto fail_event_libs;
|
||||
#endif
|
||||
|
||||
if (!context->event_loop_ops)
|
||||
goto fail_event_libs;
|
||||
|
||||
lwsl_info("Using event loop: %s\n", context->event_loop_ops->name);
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_TLS) && defined(LWS_WITH_NETWORK)
|
||||
time(&context->tls.last_cert_check_s);
|
||||
|
@ -728,7 +813,7 @@ lws_create_context(const struct lws_context_creation_info *info)
|
|||
}
|
||||
#endif
|
||||
|
||||
n = 0;
|
||||
n = 0;
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
|
||||
context->default_retry.retry_ms_table = default_backoff_table;
|
||||
|
@ -773,6 +858,11 @@ n = 0;
|
|||
memset(context->pt[n].fake_wsi, 0, sizeof(struct lws));
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
context->pt[n].evlib_pt = u;
|
||||
u += plev->ops->evlib_size_pt;
|
||||
#endif
|
||||
|
||||
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
|
||||
context->pt[n].http.ah_list = NULL;
|
||||
context->pt[n].http.ah_pool_length = 0;
|
||||
|
@ -1100,19 +1190,9 @@ bail:
|
|||
|
||||
return NULL;
|
||||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
fail_event_libs:
|
||||
lwsl_err("Requested event library support not configured, available:\n");
|
||||
{
|
||||
extern const struct lws_event_loop_ops *available_event_libs[];
|
||||
const struct lws_event_loop_ops **elops = available_event_libs;
|
||||
lwsl_err("Requested event library support not configured\n");
|
||||
|
||||
while (*elops) {
|
||||
lwsl_err(" - %s\n", (*elops)->name);
|
||||
elops++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
lws_free(context);
|
||||
|
||||
return NULL;
|
||||
|
@ -1282,6 +1362,11 @@ lws_context_destroy3(struct lws_context *context)
|
|||
lws_free(df);
|
||||
};
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS)
|
||||
if (context->evlib_plugin_list)
|
||||
lws_plugins_destroy(&context->evlib_plugin_list, NULL, NULL);
|
||||
#endif
|
||||
|
||||
lws_free(context);
|
||||
lwsl_debug("%s: ctx %p freed\n", __func__, context);
|
||||
|
||||
|
|
|
@ -212,56 +212,24 @@ struct lws_ring {
|
|||
struct lws_protocols;
|
||||
struct lws;
|
||||
|
||||
#if defined(LWS_WITH_NETWORK)
|
||||
#if defined(LWS_WITH_NETWORK) /* network */
|
||||
#include "private-lib-event-libs.h"
|
||||
|
||||
#if defined(LWS_WITH_SECURE_STREAMS)
|
||||
#include "private-lib-secure-streams.h"
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(LWS_WITH_SYS_SMD)
|
||||
#include "private-lib-system-smd.h"
|
||||
#endif
|
||||
|
||||
struct lws_io_watcher {
|
||||
#ifdef LWS_WITH_LIBEV
|
||||
struct lws_io_watcher_libev ev;
|
||||
#endif
|
||||
#ifdef LWS_WITH_LIBUV
|
||||
struct lws_io_watcher_libuv uv;
|
||||
#endif
|
||||
#ifdef LWS_WITH_LIBEVENT
|
||||
struct lws_io_watcher_libevent event;
|
||||
#endif
|
||||
#ifdef LWS_WITH_GLIB
|
||||
struct lws_io_watcher_glib glib;
|
||||
#endif
|
||||
struct lws_context *context;
|
||||
|
||||
uint8_t actual_events;
|
||||
};
|
||||
|
||||
struct lws_signal_watcher {
|
||||
#ifdef LWS_WITH_LIBEV
|
||||
struct lws_signal_watcher_libev ev;
|
||||
#endif
|
||||
#ifdef LWS_WITH_LIBUV
|
||||
struct lws_signal_watcher_libuv uv;
|
||||
#endif
|
||||
#ifdef LWS_WITH_LIBEVENT
|
||||
struct lws_signal_watcher_libevent event;
|
||||
#endif
|
||||
struct lws_context *context;
|
||||
};
|
||||
|
||||
struct lws_foreign_thread_pollfd {
|
||||
struct lws_foreign_thread_pollfd *next;
|
||||
int fd_index;
|
||||
int _and;
|
||||
int _or;
|
||||
};
|
||||
#endif
|
||||
#endif /* network */
|
||||
|
||||
#if LWS_MAX_SMP > 1
|
||||
|
||||
|
@ -368,20 +336,13 @@ struct lws_context {
|
|||
* LWS_WITH_NETWORK =====>
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
struct lws_context_eventlibs_libev ev;
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
struct lws_context_eventlibs_libuv uv;
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
struct lws_context_eventlibs_libevent event;
|
||||
#endif
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
struct lws_context_eventlibs_glib glib;
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
struct lws_plugin *evlib_plugin_list;
|
||||
void *evlib_ctx; /* overallocated */
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
struct lws_context_tls tls;
|
||||
struct lws_context_tls tls;
|
||||
#endif
|
||||
#if defined(LWS_WITH_DRIVERS)
|
||||
lws_netdevs_t netdevs;
|
||||
|
@ -427,7 +388,7 @@ struct lws_context {
|
|||
const char *server_string;
|
||||
#endif
|
||||
|
||||
struct lws_event_loop_ops *event_loop_ops;
|
||||
const struct lws_event_loop_ops *event_loop_ops;
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_TLS)
|
||||
|
|
|
@ -24,15 +24,50 @@
|
|||
|
||||
include_directories(.)
|
||||
|
||||
macro(create_evlib_plugin PLUGIN_NAME MAIN_SRC PLUGIN_HDR EVLIB)
|
||||
|
||||
set(PLUGIN_SRCS ${MAIN_SRC})
|
||||
|
||||
source_group("Headers Private" FILES ${PLUGIN_HDR})
|
||||
source_group("Sources" FILES ${MAIN_SRC})
|
||||
add_library(websockets-${PLUGIN_NAME} SHARED ${MAIN_SRC} ${PLUGIN_HDR})
|
||||
|
||||
foreach(libpath ${LWS_DEP_LIB_PATHS})
|
||||
target_link_directories(${TEST_NAME} ${libpath})
|
||||
endforeach()
|
||||
|
||||
target_link_libraries(websockets-${PLUGIN_NAME} websockets_shared ${EVLIB})
|
||||
add_dependencies(websockets-${PLUGIN_NAME} websockets_shared)
|
||||
|
||||
target_include_directories(websockets-${PLUGIN_NAME} PRIVATE
|
||||
${PLUGIN_INCLUDE} ${LWS_LIB_BUILD_INC_PATHS})
|
||||
|
||||
# Set test app specific defines.
|
||||
# set_property(TARGET ${PLUGIN_NAME}
|
||||
# PROPERTY COMPILE_DEFINITIONS
|
||||
# INSTALL_DATADIR="${CMAKE_INSTALL_PREFIX}/evlib-plugins"
|
||||
#)
|
||||
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
install(TARGETS websockets-${PLUGIN_NAME}
|
||||
EXPORT LibwebsocketsTargets
|
||||
LIBRARY DESTINATION "${LWS_INSTALL_LIB_DIR}${LIB_SUFFIX}"
|
||||
COMPONENT ${PLUGIN_NAME})
|
||||
|
||||
list(APPEND EVLIB_PLUGINS_LIST websockets-${PLUGIN_NAME})
|
||||
|
||||
endmacro()
|
||||
|
||||
#
|
||||
# These can coexist, except libev conflicts with libevent
|
||||
# poll support gets built into the lib as the default
|
||||
#
|
||||
|
||||
if (LWS_WITH_POLL)
|
||||
add_subdir_include_directories(poll)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_LIBUV)
|
||||
if (LWS_WITH_LIBUV OR LWS_WITH_LIBUV_INTERNAL)
|
||||
add_subdir_include_directories(libuv)
|
||||
set(LWS_HAVE_UV_VERSION_H ${LWS_HAVE_UV_VERSION_H} PARENT_SCOPE)
|
||||
set(LWS_HAVE_NEW_UV_VERSION_H ${LWS_HAVE_NEW_UV_VERSION_H} PARENT_SCOPE)
|
||||
|
@ -52,8 +87,12 @@ if (LWS_WITH_LIBEV)
|
|||
set(LWS_HAVE_EVBACKEND_IOURING ${LWS_HAVE_EVBACKEND_IOURING} PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
#
|
||||
# Keep explicit parent scope exports at end
|
||||
#
|
||||
|
||||
export_to_parent_intermediate()
|
||||
set(EVLIB_PLUGINS_LIST ${EVLIB_PLUGINS_LIST} PARENT_SCOPE)
|
||||
|
||||
|
|
|
@ -52,13 +52,24 @@ endif()
|
|||
message("glib include dir: ${GLIB_INCLUDE_DIRS}")
|
||||
message("glib libraries: ${GLIB_LIBRARIES}")
|
||||
include_directories("${GLIB_INCLUDE_DIRS}")
|
||||
list(APPEND LIB_LIST ${GLIB_LIBRARIES})
|
||||
|
||||
if (LWS_WITH_NETWORK)
|
||||
list(APPEND SOURCES
|
||||
event-libs/glib/glib.c)
|
||||
if (LWS_WITH_EVLIB_PLUGINS)
|
||||
|
||||
create_evlib_plugin(evlib_glib
|
||||
glib.c
|
||||
private-lib-event-libs-glib.h
|
||||
${GLIB_LIBRARIES})
|
||||
|
||||
else()
|
||||
|
||||
list(APPEND LIB_LIST ${GLIB_LIBRARIES})
|
||||
|
||||
if (LWS_WITH_NETWORK)
|
||||
list(APPEND SOURCES
|
||||
event-libs/glib/glib.c)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
#
|
||||
# Keep explicit parent scope exports at end
|
||||
#
|
||||
|
|
|
@ -26,13 +26,18 @@
|
|||
|
||||
#include <glib-unix.h>
|
||||
|
||||
#include "private-lib-event-libs-glib.h"
|
||||
|
||||
#if !defined(G_SOURCE_FUNC)
|
||||
#define G_SOURCE_FUNC(f) ((GSourceFunc) (void (*)(void)) (f))
|
||||
#endif
|
||||
|
||||
#define wsi_to_subclass(_w) ((_w)->w_read.glib.source)
|
||||
#define pt_to_priv_glib(_pt) ((struct lws_pt_eventlibs_glib *)(_pt)->evlib_pt)
|
||||
#define wsi_to_priv_glib(_w) ((struct lws_wsi_eventlibs_glib *)(_w)->evlib_wsi)
|
||||
|
||||
#define wsi_to_subclass(_w) (wsi_to_priv_glib(_w)->w_read.source)
|
||||
#define wsi_to_gsource(_w) ((GSource *)wsi_to_subclass(_w))
|
||||
#define pt_to_loop(_pt) ((_pt)->glib.loop)
|
||||
#define pt_to_loop(_pt) (pt_to_priv_glib(_pt)->loop)
|
||||
#define pt_to_g_main_context(_pt) g_main_loop_get_context(pt_to_loop(_pt))
|
||||
|
||||
#define lws_gs_valid(t) (t.gs)
|
||||
|
@ -68,17 +73,17 @@ lws_glib_check(GSource *src)
|
|||
static int
|
||||
lws_glib_set_idle(struct lws_context_per_thread *pt)
|
||||
{
|
||||
if (lws_gs_valid(pt->glib.idle))
|
||||
if (lws_gs_valid(pt_to_priv_glib(pt)->idle))
|
||||
return 0;
|
||||
|
||||
pt->glib.idle.gs = g_idle_source_new();
|
||||
if (!pt->glib.idle.gs)
|
||||
pt_to_priv_glib(pt)->idle.gs = g_idle_source_new();
|
||||
if (!pt_to_priv_glib(pt)->idle.gs)
|
||||
return 1;
|
||||
|
||||
g_source_set_callback(pt->glib.idle.gs, lws_glib_idle_timer_cb, pt,
|
||||
NULL);
|
||||
pt->glib.idle.tag = g_source_attach(pt->glib.idle.gs,
|
||||
pt_to_g_main_context(pt));
|
||||
g_source_set_callback(pt_to_priv_glib(pt)->idle.gs,
|
||||
lws_glib_idle_timer_cb, pt, NULL);
|
||||
pt_to_priv_glib(pt)->idle.tag = g_source_attach(
|
||||
pt_to_priv_glib(pt)->idle.gs, pt_to_g_main_context(pt));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -86,16 +91,17 @@ lws_glib_set_idle(struct lws_context_per_thread *pt)
|
|||
static int
|
||||
lws_glib_set_timeout(struct lws_context_per_thread *pt, unsigned int ms)
|
||||
{
|
||||
lws_gs_destroy(pt->glib.hrtimer);
|
||||
lws_gs_destroy(pt_to_priv_glib(pt)->hrtimer);
|
||||
|
||||
pt->glib.hrtimer.gs = g_timeout_source_new(ms);
|
||||
if (!pt->glib.hrtimer.gs)
|
||||
pt_to_priv_glib(pt)->hrtimer.gs = g_timeout_source_new(ms);
|
||||
if (!pt_to_priv_glib(pt)->hrtimer.gs)
|
||||
return 1;
|
||||
|
||||
g_source_set_callback(pt->glib.hrtimer.gs, lws_glib_hrtimer_cb, pt,
|
||||
NULL);
|
||||
pt->glib.hrtimer.tag = g_source_attach(pt->glib.hrtimer.gs,
|
||||
pt_to_g_main_context(pt));
|
||||
g_source_set_callback(pt_to_priv_glib(pt)->hrtimer.gs,
|
||||
lws_glib_hrtimer_cb, pt, NULL);
|
||||
pt_to_priv_glib(pt)->hrtimer.tag = g_source_attach(
|
||||
pt_to_priv_glib(pt)->hrtimer.gs,
|
||||
pt_to_g_main_context(pt));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -135,7 +141,7 @@ lws_glib_dispatch(GSource *src, GSourceFunc x, gpointer userData)
|
|||
|
||||
lws_service_fd_tsi(sub->wsi->a.context, &eventfd, sub->wsi->tsi);
|
||||
|
||||
if (!lws_gs_valid(pt->glib.idle))
|
||||
if (!lws_gs_valid(pt_to_priv_glib(pt)->idle))
|
||||
lws_glib_set_idle(pt);
|
||||
|
||||
if (pt->destroy_self)
|
||||
|
@ -166,7 +172,7 @@ lws_glib_hrtimer_cb(void *p)
|
|||
|
||||
lws_pt_lock(pt, __func__);
|
||||
|
||||
lws_gs_destroy(pt->glib.hrtimer);
|
||||
lws_gs_destroy(pt_to_priv_glib(pt)->hrtimer);
|
||||
|
||||
us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
|
||||
lws_now_usecs());
|
||||
|
@ -217,7 +223,7 @@ lws_glib_idle_timer_cb(void *p)
|
|||
* We reenable the idle callback on the next network or scheduled event
|
||||
*/
|
||||
|
||||
lws_gs_destroy(pt->glib.idle);
|
||||
lws_gs_destroy(pt_to_priv_glib(pt)->idle);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -242,12 +248,12 @@ static int
|
|||
elops_init_context_glib(struct lws_context *context,
|
||||
const struct lws_context_creation_info *info)
|
||||
{
|
||||
int n;
|
||||
// int n;
|
||||
|
||||
context->eventlib_signal_cb = info->signal_cb;
|
||||
|
||||
for (n = 0; n < context->count_threads; n++)
|
||||
context->pt[n].w_sigint.context = context;
|
||||
// for (n = 0; n < context->count_threads; n++)
|
||||
// pt_to_priv_glib(&context->pt[n])->w_sigint.context = context;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -256,6 +262,7 @@ static int
|
|||
elops_accept_glib(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
struct lws_wsi_eventlibs_glib *wsipr = wsi_to_priv_glib(wsi);
|
||||
int fd;
|
||||
|
||||
assert(!wsi_to_subclass(wsi));
|
||||
|
@ -266,7 +273,7 @@ elops_accept_glib(struct lws *wsi)
|
|||
if (!wsi_to_subclass(wsi))
|
||||
return 1;
|
||||
|
||||
wsi->w_read.context = wsi->a.context;
|
||||
wsipr->w_read.context = wsi->a.context;
|
||||
wsi_to_subclass(wsi)->wsi = wsi;
|
||||
|
||||
if (wsi->role_ops->file_handle)
|
||||
|
@ -276,7 +283,7 @@ elops_accept_glib(struct lws *wsi)
|
|||
|
||||
wsi_to_subclass(wsi)->tag = g_source_add_unix_fd(wsi_to_gsource(wsi),
|
||||
fd, (GIOCondition)LWS_POLLIN);
|
||||
wsi->w_read.actual_events = LWS_POLLIN;
|
||||
wsipr->w_read.actual_events = LWS_POLLIN;
|
||||
|
||||
g_source_set_callback(wsi_to_gsource(wsi),
|
||||
G_SOURCE_FUNC(lws_service_fd), wsi->a.context, NULL);
|
||||
|
@ -290,6 +297,7 @@ static int
|
|||
elops_init_pt_glib(struct lws_context *context, void *_loop, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct lws_pt_eventlibs_glib *ptpr = pt_to_priv_glib(pt);
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
GMainLoop *loop = (GMainLoop *)_loop;
|
||||
|
||||
|
@ -304,7 +312,7 @@ elops_init_pt_glib(struct lws_context *context, void *_loop, int tsi)
|
|||
return -1;
|
||||
}
|
||||
|
||||
pt->glib.loop = loop;
|
||||
ptpr->loop = loop;
|
||||
|
||||
/*
|
||||
* Initialize all events with the listening sockets
|
||||
|
@ -325,7 +333,7 @@ elops_init_pt_glib(struct lws_context *context, void *_loop, int tsi)
|
|||
if (pt->event_loop_foreign)
|
||||
return 0;
|
||||
|
||||
pt->glib.sigint.tag = g_unix_signal_add(SIGINT,
|
||||
ptpr->sigint.tag = g_unix_signal_add(SIGINT,
|
||||
G_SOURCE_FUNC(lws_glib_sigint_cb), pt);
|
||||
|
||||
return 0;
|
||||
|
@ -339,9 +347,11 @@ static void
|
|||
elops_io_glib(struct lws *wsi, int flags)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
GIOCondition cond = wsi->w_read.actual_events | G_IO_ERR;
|
||||
struct lws_wsi_eventlibs_glib *wsipr = wsi_to_priv_glib(wsi);
|
||||
GIOCondition cond = wsipr->w_read.actual_events | G_IO_ERR;
|
||||
|
||||
if (!pt_to_loop(pt) || wsi->a.context->being_destroyed || pt->is_destroyed)
|
||||
if (!pt_to_loop(pt) || wsi->a.context->being_destroyed ||
|
||||
pt->is_destroyed)
|
||||
return;
|
||||
|
||||
if (!wsi_to_subclass(wsi))
|
||||
|
@ -366,7 +376,7 @@ elops_io_glib(struct lws *wsi, int flags)
|
|||
cond |= G_IO_OUT;
|
||||
}
|
||||
|
||||
wsi->w_read.actual_events = cond;
|
||||
wsipr->w_read.actual_events = cond;
|
||||
|
||||
lwsl_debug("%s: wsi %p, fd %d, 0x%x/0x%x\n", __func__, wsi,
|
||||
wsi->desc.sockfd, flags, (int)cond);
|
||||
|
@ -414,6 +424,7 @@ static void
|
|||
elops_destroy_pt_glib(struct lws_context *context, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct lws_pt_eventlibs_glib *ptpr = pt_to_priv_glib(pt);
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
|
||||
if (!pt_to_loop(pt))
|
||||
|
@ -429,12 +440,12 @@ elops_destroy_pt_glib(struct lws_context *context, int tsi)
|
|||
vh = vh->vhost_next;
|
||||
}
|
||||
|
||||
lws_gs_destroy(pt->glib.idle);
|
||||
lws_gs_destroy(pt->glib.hrtimer);
|
||||
lws_gs_destroy(ptpr->idle);
|
||||
lws_gs_destroy(ptpr->hrtimer);
|
||||
|
||||
if (!pt->event_loop_foreign) {
|
||||
g_main_loop_quit(pt_to_loop(pt));
|
||||
lws_gs_destroy(pt->glib.sigint);
|
||||
lws_gs_destroy(ptpr->sigint);
|
||||
g_main_loop_unref(pt_to_loop(pt));
|
||||
}
|
||||
|
||||
|
@ -464,7 +475,7 @@ elops_wsi_logical_close_glib(struct lws *wsi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct lws_event_loop_ops event_loop_ops_glib = {
|
||||
static const struct lws_event_loop_ops event_loop_ops_glib = {
|
||||
/* name */ "glib",
|
||||
/* init_context */ elops_init_context_glib,
|
||||
/* destroy_context1 */ NULL,
|
||||
|
@ -481,4 +492,22 @@ struct lws_event_loop_ops event_loop_ops_glib = {
|
|||
/* destroy wsi */ elops_destroy_wsi_glib,
|
||||
|
||||
/* flags */ LELOF_DESTROY_FINAL,
|
||||
|
||||
/* evlib_size_ctx */ 0,
|
||||
/* evlib_size_pt */ sizeof(struct lws_pt_eventlibs_glib),
|
||||
/* evlib_size_vh */ 0,
|
||||
/* evlib_size_wsi */ sizeof(struct lws_io_watcher_glib),
|
||||
};
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS)
|
||||
LWS_VISIBLE
|
||||
#endif
|
||||
const lws_plugin_evlib_t evlib_glib = {
|
||||
.hdr = {
|
||||
"glib event loop",
|
||||
"lws_evlib_plugin",
|
||||
LWS_PLUGIN_API_MAGIC
|
||||
},
|
||||
|
||||
.ops = &event_loop_ops_glib
|
||||
};
|
||||
|
|
|
@ -41,6 +41,8 @@ struct lws_pt_eventlibs_glib {
|
|||
lws_glib_tag_t hrtimer;
|
||||
lws_glib_tag_t sigint;
|
||||
lws_glib_tag_t idle;
|
||||
|
||||
//struct lws_signal_watcher_libuv w_sigint;
|
||||
};
|
||||
|
||||
struct lws_io_watcher_glib_subclass {
|
||||
|
@ -55,10 +57,11 @@ struct lws_io_watcher_glib_subclass {
|
|||
|
||||
struct lws_io_watcher_glib {
|
||||
struct lws_io_watcher_glib_subclass *source; /* these are created and destroyed by glib */
|
||||
struct lws_context *context;
|
||||
uint8_t actual_events;
|
||||
};
|
||||
|
||||
struct lws_context_eventlibs_glib {
|
||||
//int placeholder;
|
||||
struct lws_wsi_eventlibs_glib {
|
||||
struct lws_io_watcher_glib w_read;
|
||||
};
|
||||
|
||||
extern struct lws_event_loop_ops event_loop_ops_glib;
|
||||
|
|
|
@ -40,7 +40,6 @@ endif()
|
|||
message("libev include dir: ${LIBEV_INCLUDE_DIRS}")
|
||||
message("libev libraries: ${LIBEV_LIBRARIES}")
|
||||
include_directories("${LIBEV_INCLUDE_DIRS}")
|
||||
list(APPEND LIB_LIST ${LIBEV_LIBRARIES})
|
||||
|
||||
if ("${LWS_LIBEV_LIBRARIES}" STREQUAL "" OR "${LWS_LIBEV_INCLUDE_DIRS}" STREQUAL "")
|
||||
else()
|
||||
|
@ -48,13 +47,26 @@ else()
|
|||
set(LIBEV_INCLUDE_DIRS ${LWS_LIBEV_INCLUDE_DIRS})
|
||||
endif()
|
||||
|
||||
list(APPEND SOURCES
|
||||
event-libs/libev/libev.c)
|
||||
if (LWS_WITH_EVLIB_PLUGINS)
|
||||
|
||||
create_evlib_plugin(
|
||||
evlib_ev
|
||||
libev.c
|
||||
private-lib-event-libs-libev.h
|
||||
${LIBEV_LIBRARIES})
|
||||
|
||||
else()
|
||||
|
||||
list(APPEND LIB_LIST ${LIBEV_LIBRARIES})
|
||||
|
||||
list(APPEND SOURCES
|
||||
event-libs/libev/libev.c)
|
||||
# see README.build.md for discussion of why of the supported event libs,
|
||||
# only libev cannot cope with -Werror
|
||||
set_source_files_properties(event-libs/libev/libev.c
|
||||
PROPERTIES COMPILE_FLAGS "-Wno-error" )
|
||||
|
||||
set_source_files_properties(event-libs/libev/libev.c
|
||||
PROPERTIES COMPILE_FLAGS "-Wno-error" )
|
||||
endif()
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${LIB_LIST})
|
||||
|
||||
CHECK_C_SOURCE_COMPILES(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
|
@ -23,20 +23,26 @@
|
|||
*/
|
||||
|
||||
#include "private-lib-core.h"
|
||||
#include "private-lib-event-libs-libev.h"
|
||||
|
||||
#define pt_to_priv_ev(_pt) ((struct lws_pt_eventlibs_libev *)(_pt)->evlib_pt)
|
||||
#define vh_to_priv_ev(_vh) ((struct lws_vh_eventlibs_libev *)(_vh)->evlib_vh)
|
||||
#define wsi_to_priv_ev(_w) ((struct lws_wsi_eventlibs_libev *)(_w)->evlib_wsi)
|
||||
|
||||
static void
|
||||
lws_ev_hrtimer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents)
|
||||
{
|
||||
struct lws_context_per_thread *pt =
|
||||
(struct lws_context_per_thread *)watcher->data;
|
||||
struct lws_pt_eventlibs_libev *ptpr = lws_container_of(watcher,
|
||||
struct lws_pt_eventlibs_libev, hrtimer);
|
||||
struct lws_context_per_thread *pt = ptpr->pt;
|
||||
lws_usec_t us;
|
||||
|
||||
lws_pt_lock(pt, __func__);
|
||||
us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
|
||||
lws_now_usecs());
|
||||
if (us) {
|
||||
ev_timer_set(&pt->ev.hrtimer, ((float)us) / 1000000.0, 0);
|
||||
ev_timer_start(pt->ev.io_loop, &pt->ev.hrtimer);
|
||||
ev_timer_set(&ptpr->hrtimer, ((float)us) / 1000000.0, 0);
|
||||
ev_timer_start(ptpr->io_loop, &ptpr->hrtimer);
|
||||
}
|
||||
lws_pt_unlock(pt);
|
||||
}
|
||||
|
@ -44,10 +50,11 @@ lws_ev_hrtimer_cb(struct ev_loop *loop, struct ev_timer *watcher, int revents)
|
|||
static void
|
||||
lws_ev_idle_cb(struct ev_loop *loop, struct ev_idle *handle, int revents)
|
||||
{
|
||||
struct lws_context_per_thread *pt = lws_container_of(handle,
|
||||
struct lws_context_per_thread, ev.idle);
|
||||
lws_usec_t us;
|
||||
struct lws_pt_eventlibs_libev *ptpr = lws_container_of(handle,
|
||||
struct lws_pt_eventlibs_libev, idle);
|
||||
struct lws_context_per_thread *pt = ptpr->pt;
|
||||
int reschedule = 0;
|
||||
lws_usec_t us;
|
||||
|
||||
lws_service_do_ripe_rxflow(pt);
|
||||
|
||||
|
@ -64,8 +71,8 @@ lws_ev_idle_cb(struct ev_loop *loop, struct ev_idle *handle, int revents)
|
|||
us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
|
||||
lws_now_usecs());
|
||||
if (us) {
|
||||
ev_timer_set(&pt->ev.hrtimer, ((float)us) / 1000000.0, 0);
|
||||
ev_timer_start(pt->ev.io_loop, &pt->ev.hrtimer);
|
||||
ev_timer_set(&ptpr->hrtimer, ((float)us) / 1000000.0, 0);
|
||||
ev_timer_start(ptpr->io_loop, &ptpr->hrtimer);
|
||||
}
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
|
@ -80,9 +87,10 @@ lws_ev_idle_cb(struct ev_loop *loop, struct ev_idle *handle, int revents)
|
|||
static void
|
||||
lws_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||
{
|
||||
struct lws_io_watcher *lws_io = lws_container_of(watcher,
|
||||
struct lws_io_watcher, ev.watcher);
|
||||
struct lws_io_watcher_libev *lws_io = lws_container_of(watcher,
|
||||
struct lws_io_watcher_libev, watcher);
|
||||
struct lws_context *context = lws_io->context;
|
||||
struct lws_pt_eventlibs_libev *ptpr;
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_pollfd eventfd;
|
||||
struct lws *wsi;
|
||||
|
@ -105,10 +113,11 @@ lws_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
|||
|
||||
wsi = wsi_from_fd(context, watcher->fd);
|
||||
pt = &context->pt[(int)wsi->tsi];
|
||||
ptpr = pt_to_priv_ev(pt);
|
||||
|
||||
lws_service_fd_tsi(context, &eventfd, (int)wsi->tsi);
|
||||
|
||||
ev_idle_start(pt->ev.io_loop, &pt->ev.idle);
|
||||
ev_idle_start(ptpr->io_loop, &ptpr->idle);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -128,7 +137,8 @@ static int
|
|||
elops_init_pt_ev(struct lws_context *context, void *_loop, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct ev_signal *w_sigint = &context->pt[tsi].w_sigint.ev.watcher;
|
||||
struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
|
||||
struct ev_signal *w_sigint = &ptpr->w_sigint.watcher;
|
||||
struct ev_loop *loop = (struct ev_loop *)_loop;
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
const char *backend_name;
|
||||
|
@ -137,6 +147,8 @@ elops_init_pt_ev(struct lws_context *context, void *_loop, int tsi)
|
|||
|
||||
lwsl_info("%s: loop %p\n", __func__, _loop);
|
||||
|
||||
ptpr->pt = pt;
|
||||
|
||||
if (!loop)
|
||||
loop = ev_loop_new(0);
|
||||
else
|
||||
|
@ -148,7 +160,7 @@ elops_init_pt_ev(struct lws_context *context, void *_loop, int tsi)
|
|||
return -1;
|
||||
}
|
||||
|
||||
pt->ev.io_loop = loop;
|
||||
ptpr->io_loop = loop;
|
||||
|
||||
/*
|
||||
* Initialize the accept w_accept with all the listening sockets
|
||||
|
@ -156,13 +168,17 @@ elops_init_pt_ev(struct lws_context *context, void *_loop, int tsi)
|
|||
*/
|
||||
while (vh) {
|
||||
if (vh->lserv_wsi) {
|
||||
vh->lserv_wsi->w_read.context = context;
|
||||
vh->w_accept.context = context;
|
||||
struct lws_wsi_eventlibs_libev *w =
|
||||
wsi_to_priv_ev(vh->lserv_wsi);
|
||||
|
||||
ev_io_init(&vh->w_accept.ev.watcher, lws_accept_cb,
|
||||
w->w_read.context = context;
|
||||
w->w_write.context = context;
|
||||
vh_to_priv_ev(vh)->w_accept.context = context;
|
||||
|
||||
ev_io_init(&vh_to_priv_ev(vh)->w_accept.watcher,
|
||||
lws_accept_cb,
|
||||
vh->lserv_wsi->desc.sockfd, EV_READ);
|
||||
ev_io_start(loop, &vh->w_accept.ev.watcher);
|
||||
|
||||
ev_io_start(loop, &vh_to_priv_ev(vh)->w_accept.watcher);
|
||||
}
|
||||
vh = vh->vhost_next;
|
||||
}
|
||||
|
@ -212,10 +228,10 @@ elops_init_pt_ev(struct lws_context *context, void *_loop, int tsi)
|
|||
lwsl_info(" libev backend: %s\n", backend_name);
|
||||
(void)backend_name;
|
||||
|
||||
ev_timer_init(&pt->ev.hrtimer, lws_ev_hrtimer_cb, 0, 0);
|
||||
pt->ev.hrtimer.data = pt;
|
||||
ev_timer_init(&ptpr->hrtimer, lws_ev_hrtimer_cb, 0, 0);
|
||||
ptpr->hrtimer.data = pt;
|
||||
|
||||
ev_idle_init(&pt->ev.idle, lws_ev_idle_cb);
|
||||
ev_idle_init(&ptpr->idle, lws_ev_idle_cb);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -224,21 +240,23 @@ static void
|
|||
elops_destroy_pt_ev(struct lws_context *context, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
|
||||
while (vh) {
|
||||
if (vh->lserv_wsi)
|
||||
ev_io_stop(pt->ev.io_loop, &vh->w_accept.ev.watcher);
|
||||
ev_io_stop(ptpr->io_loop,
|
||||
&vh_to_priv_ev(vh)->w_accept.watcher);
|
||||
vh = vh->vhost_next;
|
||||
}
|
||||
|
||||
/* static assets */
|
||||
|
||||
ev_timer_stop(pt->ev.io_loop, &pt->ev.hrtimer);
|
||||
ev_idle_stop(pt->ev.io_loop, &pt->ev.idle);
|
||||
ev_timer_stop(ptpr->io_loop, &ptpr->hrtimer);
|
||||
ev_idle_stop(ptpr->io_loop, &ptpr->idle);
|
||||
|
||||
if (!pt->event_loop_foreign)
|
||||
ev_signal_stop(pt->ev.io_loop, &pt->w_sigint.ev.watcher);
|
||||
ev_signal_stop(ptpr->io_loop, &ptpr->w_sigint.watcher);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -250,7 +268,7 @@ elops_init_context_ev(struct lws_context *context,
|
|||
context->eventlib_signal_cb = info->signal_cb;
|
||||
|
||||
for (n = 0; n < context->count_threads; n++)
|
||||
context->pt[n].w_sigint.context = context;
|
||||
pt_to_priv_ev(&context->pt[n])->w_sigint.context = context;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -258,18 +276,21 @@ elops_init_context_ev(struct lws_context *context,
|
|||
static int
|
||||
elops_accept_ev(struct lws *wsi)
|
||||
{
|
||||
struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi);
|
||||
int fd;
|
||||
|
||||
lwsl_notice("%s\n", __func__);
|
||||
|
||||
if (wsi->role_ops->file_handle)
|
||||
fd = wsi->desc.filefd;
|
||||
else
|
||||
fd = wsi->desc.sockfd;
|
||||
|
||||
wsi->w_read.context = wsi->a.context;
|
||||
wsi->w_write.context = wsi->a.context;
|
||||
w->w_read.context = wsi->a.context;
|
||||
w->w_write.context = wsi->a.context;
|
||||
|
||||
ev_io_init(&wsi->w_read.ev.watcher, lws_accept_cb, fd, EV_READ);
|
||||
ev_io_init(&wsi->w_write.ev.watcher, lws_accept_cb, fd, EV_WRITE);
|
||||
ev_io_init(&w->w_read.watcher, lws_accept_cb, fd, EV_READ);
|
||||
ev_io_init(&w->w_write.watcher, lws_accept_cb, fd, EV_WRITE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -278,8 +299,14 @@ static void
|
|||
elops_io_ev(struct lws *wsi, int flags)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
|
||||
struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi);
|
||||
|
||||
if (!pt->ev.io_loop || pt->is_destroyed)
|
||||
lwsl_notice("%s: wsi %p %s flags 0x%x %p %d\n", __func__,
|
||||
wsi, wsi->role_ops->name, flags,
|
||||
ptpr->io_loop, pt->is_destroyed);
|
||||
|
||||
if (!ptpr->io_loop || pt->is_destroyed)
|
||||
return;
|
||||
|
||||
assert((flags & (LWS_EV_START | LWS_EV_STOP)) &&
|
||||
|
@ -287,14 +314,14 @@ elops_io_ev(struct lws *wsi, int flags)
|
|||
|
||||
if (flags & LWS_EV_START) {
|
||||
if (flags & LWS_EV_WRITE)
|
||||
ev_io_start(pt->ev.io_loop, &wsi->w_write.ev.watcher);
|
||||
ev_io_start(ptpr->io_loop, &w->w_write.watcher);
|
||||
if (flags & LWS_EV_READ)
|
||||
ev_io_start(pt->ev.io_loop, &wsi->w_read.ev.watcher);
|
||||
ev_io_start(ptpr->io_loop, &w->w_read.watcher);
|
||||
} else {
|
||||
if (flags & LWS_EV_WRITE)
|
||||
ev_io_stop(pt->ev.io_loop, &wsi->w_write.ev.watcher);
|
||||
ev_io_stop(ptpr->io_loop, &w->w_write.watcher);
|
||||
if (flags & LWS_EV_READ)
|
||||
ev_io_stop(pt->ev.io_loop, &wsi->w_read.ev.watcher);
|
||||
ev_io_stop(ptpr->io_loop, &w->w_read.watcher);
|
||||
}
|
||||
|
||||
if (pt->destroy_self)
|
||||
|
@ -304,14 +331,15 @@ elops_io_ev(struct lws *wsi, int flags)
|
|||
static void
|
||||
elops_run_pt_ev(struct lws_context *context, int tsi)
|
||||
{
|
||||
if (context->pt[tsi].ev.io_loop)
|
||||
ev_run(context->pt[tsi].ev.io_loop, 0);
|
||||
if (pt_to_priv_ev(&context->pt[tsi])->io_loop)
|
||||
ev_run(pt_to_priv_ev(&context->pt[tsi])->io_loop, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
elops_destroy_context2_ev(struct lws_context *context)
|
||||
{
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_pt_eventlibs_libev *ptpr;
|
||||
int n, m;
|
||||
|
||||
lwsl_debug("%s\n", __func__);
|
||||
|
@ -320,21 +348,22 @@ elops_destroy_context2_ev(struct lws_context *context)
|
|||
int budget = 1000;
|
||||
|
||||
pt = &context->pt[n];
|
||||
ptpr = pt_to_priv_ev(pt);
|
||||
|
||||
/* only for internal loops... */
|
||||
|
||||
if (pt->event_loop_foreign || !pt->ev.io_loop)
|
||||
if (pt->event_loop_foreign || !ptpr->io_loop)
|
||||
continue;
|
||||
|
||||
if (!context->finalize_destroy_after_internal_loops_stopped) {
|
||||
ev_break(pt->ev.io_loop, EVBREAK_ONE);
|
||||
ev_break(ptpr->io_loop, EVBREAK_ONE);
|
||||
continue;
|
||||
}
|
||||
while (budget-- &&
|
||||
(m = ev_run(pt->ev.io_loop, 0)))
|
||||
(m = ev_run(ptpr->io_loop, 0)))
|
||||
;
|
||||
|
||||
ev_loop_destroy(pt->ev.io_loop);
|
||||
ev_loop_destroy(ptpr->io_loop);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -343,6 +372,7 @@ elops_destroy_context2_ev(struct lws_context *context)
|
|||
static int
|
||||
elops_init_vhost_listen_wsi_ev(struct lws *wsi)
|
||||
{
|
||||
struct lws_wsi_eventlibs_libev *w;
|
||||
int fd;
|
||||
|
||||
if (!wsi) {
|
||||
|
@ -350,16 +380,17 @@ elops_init_vhost_listen_wsi_ev(struct lws *wsi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
wsi->w_read.context = wsi->a.context;
|
||||
wsi->w_write.context = wsi->a.context;
|
||||
w = wsi_to_priv_ev(wsi);
|
||||
w->w_read.context = wsi->a.context;
|
||||
w->w_write.context = wsi->a.context;
|
||||
|
||||
if (wsi->role_ops->file_handle)
|
||||
fd = wsi->desc.filefd;
|
||||
else
|
||||
fd = wsi->desc.sockfd;
|
||||
|
||||
ev_io_init(&wsi->w_read.ev.watcher, lws_accept_cb, fd, EV_READ);
|
||||
ev_io_init(&wsi->w_write.ev.watcher, lws_accept_cb, fd, EV_WRITE);
|
||||
ev_io_init(&w->w_read.watcher, lws_accept_cb, fd, EV_READ);
|
||||
//ev_io_init(&w->w_write.watcher, lws_accept_cb, fd, EV_WRITE);
|
||||
|
||||
elops_io_ev(wsi, LWS_EV_START | LWS_EV_READ);
|
||||
|
||||
|
@ -370,12 +401,14 @@ static void
|
|||
elops_destroy_wsi_ev(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
struct lws_pt_eventlibs_libev *ptpr = pt_to_priv_ev(pt);
|
||||
struct lws_wsi_eventlibs_libev *w = wsi_to_priv_ev(wsi);
|
||||
|
||||
ev_io_stop(pt->ev.io_loop, &wsi->w_read.ev.watcher);
|
||||
ev_io_stop(pt->ev.io_loop, &wsi->w_write.ev.watcher);
|
||||
ev_io_stop(ptpr->io_loop, &w->w_read.watcher);
|
||||
ev_io_stop(ptpr->io_loop, &w->w_write.watcher);
|
||||
}
|
||||
|
||||
struct lws_event_loop_ops event_loop_ops_ev = {
|
||||
static const struct lws_event_loop_ops event_loop_ops_ev = {
|
||||
/* name */ "libev",
|
||||
/* init_context */ elops_init_context_ev,
|
||||
/* destroy_context1 */ NULL,
|
||||
|
@ -392,4 +425,22 @@ struct lws_event_loop_ops event_loop_ops_ev = {
|
|||
/* destroy wsi */ elops_destroy_wsi_ev,
|
||||
|
||||
/* flags */ 0,
|
||||
|
||||
/* evlib_size_ctx */ 0,
|
||||
/* evlib_size_pt */ sizeof(struct lws_pt_eventlibs_libev),
|
||||
/* evlib_size_vh */ sizeof(struct lws_vh_eventlibs_libev),
|
||||
/* evlib_size_wsi */ sizeof(struct lws_wsi_eventlibs_libev),
|
||||
};
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS)
|
||||
LWS_VISIBLE
|
||||
#endif
|
||||
const lws_plugin_evlib_t evlib_ev = {
|
||||
.hdr = {
|
||||
"libev event loop",
|
||||
"lws_evlib_plugin",
|
||||
LWS_PLUGIN_API_MAGIC
|
||||
},
|
||||
|
||||
.ops = &event_loop_ops_ev
|
||||
};
|
||||
|
|
|
@ -33,22 +33,30 @@
|
|||
(--(LWS_UV_REFCOUNT_STATIC_HANDLE_TO_CONTEXT(_x)-> \
|
||||
count_event_loop_static_asset_handles))
|
||||
|
||||
struct lws_signal_watcher_libev {
|
||||
ev_signal watcher;
|
||||
struct lws_context *context;
|
||||
};
|
||||
|
||||
struct lws_pt_eventlibs_libev {
|
||||
struct ev_loop *io_loop;
|
||||
struct ev_timer hrtimer;
|
||||
struct ev_idle idle;
|
||||
struct lws_signal_watcher_libev w_sigint;
|
||||
struct lws_context_per_thread *pt;
|
||||
};
|
||||
|
||||
struct lws_io_watcher_libev {
|
||||
ev_io watcher;
|
||||
struct lws_context *context;
|
||||
};
|
||||
|
||||
struct lws_signal_watcher_libev {
|
||||
ev_signal watcher;
|
||||
struct lws_vh_eventlibs_libev {
|
||||
struct lws_io_watcher_libev w_accept;
|
||||
};
|
||||
|
||||
struct lws_context_eventlibs_libev {
|
||||
int placeholder;
|
||||
struct lws_wsi_eventlibs_libev {
|
||||
struct lws_io_watcher_libev w_read;
|
||||
struct lws_io_watcher_libev w_write;
|
||||
};
|
||||
|
||||
extern struct lws_event_loop_ops event_loop_ops_ev;
|
||||
|
|
|
@ -40,18 +40,29 @@ endif()
|
|||
message("libevent include dir: ${LIBEVENT_INCLUDE_DIRS}")
|
||||
message("libevent libraries: ${LIBEVENT_LIBRARIES}")
|
||||
include_directories("${LIBEVENT_INCLUDE_DIRS}")
|
||||
list(APPEND LIB_LIST ${LIBEVENT_LIBRARIES})
|
||||
|
||||
if ("${LWS_LIBEVENT_LIBRARIES}" STREQUAL "" OR "${LWS_LIBEVENT_INCLUDE_DIRS}" STREQUAL "")
|
||||
else()
|
||||
set(LIBEVENT_LIBRARIES ${LWS_LIBEVENT_LIBRARIES})
|
||||
set(LIBEVENT_INCLUDE_DIRS ${LWS_LIBEVENT_INCLUDE_DIRS})
|
||||
set(LIBEVENT_FOUND 1 PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_NETWORK)
|
||||
list(APPEND SOURCES
|
||||
event-libs/libevent/libevent.c)
|
||||
|
||||
if (LWS_WITH_EVLIB_PLUGINS)
|
||||
|
||||
create_evlib_plugin(evlib_event
|
||||
libevent.c
|
||||
private-lib-event-libs-libevent.h
|
||||
${LIBEVENT_LIBRARIES})
|
||||
|
||||
else()
|
||||
|
||||
list(APPEND LIB_LIST ${LIBEVENT_LIBRARIES})
|
||||
set(LIBEVENT_FOUND 1 PARENT_SCOPE)
|
||||
if (LWS_WITH_NETWORK)
|
||||
list(APPEND SOURCES
|
||||
event-libs/libevent/libevent.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
|
|
|
@ -23,11 +23,16 @@
|
|||
*/
|
||||
|
||||
#include "private-lib-core.h"
|
||||
#include "private-lib-event-libs-libevent.h"
|
||||
|
||||
#define pt_to_priv_event(_pt) ((struct lws_pt_eventlibs_libevent *)(_pt)->evlib_pt)
|
||||
#define wsi_to_priv_event(_w) ((struct lws_wsi_eventlibs_libevent *)(_w)->evlib_wsi)
|
||||
|
||||
static void
|
||||
lws_event_hrtimer_cb(int fd, short event, void *p)
|
||||
{
|
||||
struct lws_context_per_thread *pt = (struct lws_context_per_thread *)p;
|
||||
struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt);
|
||||
struct timeval tv;
|
||||
lws_usec_t us;
|
||||
|
||||
|
@ -37,7 +42,7 @@ lws_event_hrtimer_cb(int fd, short event, void *p)
|
|||
if (us) {
|
||||
tv.tv_sec = us / LWS_US_PER_SEC;
|
||||
tv.tv_usec = us - (tv.tv_sec * LWS_US_PER_SEC);
|
||||
evtimer_add(pt->event.hrtimer, &tv);
|
||||
evtimer_add(ptpr->hrtimer, &tv);
|
||||
}
|
||||
lws_pt_unlock(pt);
|
||||
}
|
||||
|
@ -46,6 +51,7 @@ static void
|
|||
lws_event_idle_timer_cb(int fd, short event, void *p)
|
||||
{
|
||||
struct lws_context_per_thread *pt = (struct lws_context_per_thread *)p;
|
||||
struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt);
|
||||
struct timeval tv;
|
||||
lws_usec_t us;
|
||||
|
||||
|
@ -66,7 +72,7 @@ lws_event_idle_timer_cb(int fd, short event, void *p)
|
|||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000;
|
||||
evtimer_add(pt->event.idle_timer, &tv);
|
||||
evtimer_add(ptpr->idle_timer, &tv);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -82,11 +88,10 @@ lws_event_idle_timer_cb(int fd, short event, void *p)
|
|||
if (us) {
|
||||
tv.tv_sec = us / LWS_US_PER_SEC;
|
||||
tv.tv_usec = us - (tv.tv_sec * LWS_US_PER_SEC);
|
||||
evtimer_add(pt->event.hrtimer, &tv);
|
||||
evtimer_add(ptpr->hrtimer, &tv);
|
||||
}
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
|
||||
if (pt->destroy_self)
|
||||
lws_context_destroy(pt->context);
|
||||
}
|
||||
|
@ -94,7 +99,8 @@ lws_event_idle_timer_cb(int fd, short event, void *p)
|
|||
static void
|
||||
lws_event_cb(evutil_socket_t sock_fd, short revents, void *ctx)
|
||||
{
|
||||
struct lws_io_watcher *lws_io = (struct lws_io_watcher *)ctx;
|
||||
struct lws_signal_watcher_libevent *lws_io =
|
||||
(struct lws_signal_watcher_libevent *)ctx;
|
||||
struct lws_context *context = lws_io->context;
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_pollfd eventfd;
|
||||
|
@ -145,7 +151,7 @@ lws_event_cb(evutil_socket_t sock_fd, short revents, void *ctx)
|
|||
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 1000;
|
||||
evtimer_add(pt->event.idle_timer, &tv);
|
||||
evtimer_add(pt_to_priv_event(pt)->idle_timer, &tv);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -161,16 +167,16 @@ lws_event_sigint_cb(evutil_socket_t sock_fd, short revents, void *ctx)
|
|||
return;
|
||||
}
|
||||
if (!pt->event_loop_foreign)
|
||||
event_base_loopbreak(pt->event.io_loop);
|
||||
event_base_loopbreak(pt_to_priv_event(pt)->io_loop);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
elops_init_pt_event(struct lws_context *context, void *_loop, int tsi)
|
||||
{
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
struct event_base *loop = (struct event_base *)_loop;
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt);
|
||||
|
||||
lwsl_info("%s: loop %p\n", __func__, _loop);
|
||||
|
||||
|
@ -185,7 +191,7 @@ elops_init_pt_event(struct lws_context *context, void *_loop, int tsi)
|
|||
return -1;
|
||||
}
|
||||
|
||||
pt->event.io_loop = loop;
|
||||
ptpr->io_loop = loop;
|
||||
|
||||
/*
|
||||
* Initialize all events with the listening sockets
|
||||
|
@ -194,23 +200,26 @@ elops_init_pt_event(struct lws_context *context, void *_loop, int tsi)
|
|||
|
||||
while (vh) {
|
||||
if (vh->lserv_wsi) {
|
||||
vh->lserv_wsi->w_read.context = context;
|
||||
vh->lserv_wsi->w_read.event.watcher = event_new(
|
||||
struct lws_io_watcher_libevent *w_read =
|
||||
&(wsi_to_priv_event(vh->lserv_wsi)->w_read);
|
||||
|
||||
w_read->context = context;
|
||||
w_read->watcher = event_new(
|
||||
loop, vh->lserv_wsi->desc.sockfd,
|
||||
(EV_READ | EV_PERSIST), lws_event_cb,
|
||||
&vh->lserv_wsi->w_read);
|
||||
event_add(vh->lserv_wsi->w_read.event.watcher, NULL);
|
||||
vh->lserv_wsi->w_read.event.set = 1;
|
||||
w_read);
|
||||
event_add(w_read->watcher, NULL);
|
||||
w_read->set = 1;
|
||||
}
|
||||
vh = vh->vhost_next;
|
||||
}
|
||||
|
||||
/* static event loop objects */
|
||||
|
||||
pt->event.hrtimer = event_new(loop, -1, EV_PERSIST,
|
||||
ptpr->hrtimer = event_new(loop, -1, EV_PERSIST,
|
||||
lws_event_hrtimer_cb, pt);
|
||||
|
||||
pt->event.idle_timer = event_new(loop, -1, 0,
|
||||
ptpr->idle_timer = event_new(loop, -1, 0,
|
||||
lws_event_idle_timer_cb, pt);
|
||||
|
||||
/* Register the signal watcher unless it's a foreign loop */
|
||||
|
@ -218,9 +227,9 @@ elops_init_pt_event(struct lws_context *context, void *_loop, int tsi)
|
|||
if (pt->event_loop_foreign)
|
||||
return 0;
|
||||
|
||||
pt->w_sigint.event.watcher = evsignal_new(loop, SIGINT,
|
||||
ptpr->w_sigint.watcher = evsignal_new(loop, SIGINT,
|
||||
lws_event_sigint_cb, pt);
|
||||
event_add(pt->w_sigint.event.watcher, NULL);
|
||||
event_add(ptpr->w_sigint.watcher, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -234,7 +243,7 @@ elops_init_context_event(struct lws_context *context,
|
|||
context->eventlib_signal_cb = info->signal_cb;
|
||||
|
||||
for (n = 0; n < context->count_threads; n++)
|
||||
context->pt[n].w_sigint.context = context;
|
||||
pt_to_priv_event(&context->pt[n])->w_sigint.context = context;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -244,23 +253,26 @@ elops_accept_event(struct lws *wsi)
|
|||
{
|
||||
struct lws_context *context = lws_get_context(wsi);
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_pt_eventlibs_libevent *ptpr;
|
||||
struct lws_wsi_eventlibs_libevent *wpr = wsi_to_priv_event(wsi);
|
||||
int fd;
|
||||
|
||||
wsi->w_read.context = context;
|
||||
wsi->w_write.context = context;
|
||||
wpr->w_read.context = context;
|
||||
wpr->w_write.context = context;
|
||||
|
||||
// Initialize the event
|
||||
pt = &context->pt[(int)wsi->tsi];
|
||||
ptpr = pt_to_priv_event(pt);
|
||||
|
||||
if (wsi->role_ops->file_handle)
|
||||
fd = wsi->desc.filefd;
|
||||
else
|
||||
fd = wsi->desc.sockfd;
|
||||
|
||||
wsi->w_read.event.watcher = event_new(pt->event.io_loop, fd,
|
||||
(EV_READ | EV_PERSIST), lws_event_cb, &wsi->w_read);
|
||||
wsi->w_write.event.watcher = event_new(pt->event.io_loop, fd,
|
||||
(EV_WRITE | EV_PERSIST), lws_event_cb, &wsi->w_write);
|
||||
wpr->w_read.watcher = event_new(ptpr->io_loop, fd,
|
||||
(EV_READ | EV_PERSIST), lws_event_cb, &wpr->w_read);
|
||||
wpr->w_write.watcher = event_new(ptpr->io_loop, fd,
|
||||
(EV_WRITE | EV_PERSIST), lws_event_cb, &wpr->w_write);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -269,8 +281,10 @@ static void
|
|||
elops_io_event(struct lws *wsi, int flags)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt);
|
||||
struct lws_wsi_eventlibs_libevent *wpr = wsi_to_priv_event(wsi);
|
||||
|
||||
if (!pt->event.io_loop || wsi->a.context->being_destroyed ||
|
||||
if (!ptpr->io_loop || wsi->a.context->being_destroyed ||
|
||||
pt->is_destroyed)
|
||||
return;
|
||||
|
||||
|
@ -278,24 +292,24 @@ elops_io_event(struct lws *wsi, int flags)
|
|||
(flags & (LWS_EV_READ | LWS_EV_WRITE)));
|
||||
|
||||
if (flags & LWS_EV_START) {
|
||||
if ((flags & LWS_EV_WRITE) && !wsi->w_write.event.set) {
|
||||
event_add(wsi->w_write.event.watcher, NULL);
|
||||
wsi->w_write.event.set = 1;
|
||||
if ((flags & LWS_EV_WRITE) && !wpr->w_write.set) {
|
||||
event_add(wpr->w_write.watcher, NULL);
|
||||
wpr->w_write.set = 1;
|
||||
}
|
||||
|
||||
if ((flags & LWS_EV_READ) && !wsi->w_read.event.set) {
|
||||
event_add(wsi->w_read.event.watcher, NULL);
|
||||
wsi->w_read.event.set = 1;
|
||||
if ((flags & LWS_EV_READ) && !wpr->w_read.set) {
|
||||
event_add(wpr->w_read.watcher, NULL);
|
||||
wpr->w_read.set = 1;
|
||||
}
|
||||
} else {
|
||||
if ((flags & LWS_EV_WRITE) && wsi->w_write.event.set) {
|
||||
event_del(wsi->w_write.event.watcher);
|
||||
wsi->w_write.event.set = 0;
|
||||
if ((flags & LWS_EV_WRITE) && wpr->w_write.set) {
|
||||
event_del(wpr->w_write.watcher);
|
||||
wpr->w_write.set = 0;
|
||||
}
|
||||
|
||||
if ((flags & LWS_EV_READ) && wsi->w_read.event.set) {
|
||||
event_del(wsi->w_read.event.watcher);
|
||||
wsi->w_read.event.set = 0;
|
||||
if ((flags & LWS_EV_READ) && wpr->w_read.set) {
|
||||
event_del(wpr->w_read.watcher);
|
||||
wpr->w_read.set = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -304,19 +318,21 @@ static void
|
|||
elops_run_pt_event(struct lws_context *context, int tsi)
|
||||
{
|
||||
/* Run / Dispatch the event_base loop */
|
||||
if (context->pt[tsi].event.io_loop)
|
||||
event_base_dispatch(context->pt[tsi].event.io_loop);
|
||||
if (pt_to_priv_event(&context->pt[tsi])->io_loop)
|
||||
event_base_dispatch(
|
||||
pt_to_priv_event(&context->pt[tsi])->io_loop);
|
||||
}
|
||||
|
||||
static void
|
||||
elops_destroy_pt_event(struct lws_context *context, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct lws_pt_eventlibs_libevent *ptpr = pt_to_priv_event(pt);
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
|
||||
lwsl_info("%s\n", __func__);
|
||||
|
||||
if (!pt->event.io_loop)
|
||||
if (!ptpr->io_loop)
|
||||
return;
|
||||
|
||||
/*
|
||||
|
@ -324,21 +340,24 @@ elops_destroy_pt_event(struct lws_context *context, int tsi)
|
|||
*/
|
||||
while (vh) {
|
||||
if (vh->lserv_wsi) {
|
||||
event_free(vh->lserv_wsi->w_read.event.watcher);
|
||||
vh->lserv_wsi->w_read.event.watcher = NULL;
|
||||
event_free(vh->lserv_wsi->w_write.event.watcher);
|
||||
vh->lserv_wsi->w_write.event.watcher = NULL;
|
||||
struct lws_wsi_eventlibs_libevent *w =
|
||||
wsi_to_priv_event(vh->lserv_wsi);
|
||||
|
||||
event_free(w->w_read.watcher);
|
||||
w->w_read.watcher = NULL;
|
||||
event_free(w->w_write.watcher);
|
||||
w->w_write.watcher = NULL;
|
||||
}
|
||||
vh = vh->vhost_next;
|
||||
}
|
||||
|
||||
event_free(pt->event.hrtimer);
|
||||
event_free(pt->event.idle_timer);
|
||||
event_free(ptpr->hrtimer);
|
||||
event_free(ptpr->idle_timer);
|
||||
|
||||
if (!pt->event_loop_foreign) {
|
||||
event_del(pt->w_sigint.event.watcher);
|
||||
event_free(pt->w_sigint.event.watcher);
|
||||
event_base_loopexit(pt->event.io_loop, NULL);
|
||||
event_del(ptpr->w_sigint.watcher);
|
||||
event_free(ptpr->w_sigint.watcher);
|
||||
event_base_loopexit(ptpr->io_loop, NULL);
|
||||
// event_base_free(pt->event.io_loop);
|
||||
// pt->event.io_loop = NULL;
|
||||
lwsl_notice("%s: set to exit loop\n", __func__);
|
||||
|
@ -349,6 +368,7 @@ static void
|
|||
elops_destroy_wsi_event(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_wsi_eventlibs_libevent *w;
|
||||
|
||||
if (!wsi)
|
||||
return;
|
||||
|
@ -357,14 +377,16 @@ elops_destroy_wsi_event(struct lws *wsi)
|
|||
if (pt->is_destroyed)
|
||||
return;
|
||||
|
||||
if (wsi->w_read.event.watcher) {
|
||||
event_free(wsi->w_read.event.watcher);
|
||||
wsi->w_read.event.watcher = NULL;
|
||||
w = wsi_to_priv_event(wsi);
|
||||
|
||||
if (w->w_read.watcher) {
|
||||
event_free(w->w_read.watcher);
|
||||
w->w_read.watcher = NULL;
|
||||
}
|
||||
|
||||
if (wsi->w_write.event.watcher) {
|
||||
event_free(wsi->w_write.event.watcher);
|
||||
wsi->w_write.event.watcher = NULL;
|
||||
if (w->w_write.watcher) {
|
||||
event_free(w->w_write.watcher);
|
||||
w->w_write.watcher = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -380,6 +402,8 @@ static int
|
|||
elops_init_vhost_listen_wsi_event(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_pt_eventlibs_libevent *ptpr;
|
||||
struct lws_wsi_eventlibs_libevent *w;
|
||||
int fd;
|
||||
|
||||
if (!wsi) {
|
||||
|
@ -387,22 +411,24 @@ elops_init_vhost_listen_wsi_event(struct lws *wsi)
|
|||
return 0;
|
||||
}
|
||||
|
||||
wsi->w_read.context = wsi->a.context;
|
||||
wsi->w_write.context = wsi->a.context;
|
||||
w = wsi_to_priv_event(wsi);
|
||||
|
||||
w->w_read.context = wsi->a.context;
|
||||
w->w_write.context = wsi->a.context;
|
||||
|
||||
pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
ptpr = pt_to_priv_event(pt);
|
||||
|
||||
if (wsi->role_ops->file_handle)
|
||||
fd = wsi->desc.filefd;
|
||||
else
|
||||
fd = wsi->desc.sockfd;
|
||||
|
||||
wsi->w_read.event.watcher = event_new(pt->event.io_loop, fd,
|
||||
(EV_READ | EV_PERSIST),
|
||||
lws_event_cb, &wsi->w_read);
|
||||
wsi->w_write.event.watcher = event_new(pt->event.io_loop, fd,
|
||||
(EV_WRITE | EV_PERSIST),
|
||||
lws_event_cb, &wsi->w_write);
|
||||
w->w_read.watcher = event_new(ptpr->io_loop, fd, (EV_READ | EV_PERSIST),
|
||||
lws_event_cb, &w->w_read);
|
||||
w->w_write.watcher = event_new(ptpr->io_loop, fd,
|
||||
(EV_WRITE | EV_PERSIST),
|
||||
lws_event_cb, &w->w_write);
|
||||
|
||||
elops_io_event(wsi, LWS_EV_START | LWS_EV_READ);
|
||||
|
||||
|
@ -413,6 +439,7 @@ static int
|
|||
elops_destroy_context2_event(struct lws_context *context)
|
||||
{
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_pt_eventlibs_libevent *ptpr;
|
||||
int n, m;
|
||||
|
||||
lwsl_debug("%s: in\n", __func__);
|
||||
|
@ -421,31 +448,31 @@ elops_destroy_context2_event(struct lws_context *context)
|
|||
int budget = 1000;
|
||||
|
||||
pt = &context->pt[n];
|
||||
ptpr = pt_to_priv_event(pt);
|
||||
|
||||
/* only for internal loops... */
|
||||
|
||||
if (pt->event_loop_foreign || !pt->event.io_loop)
|
||||
if (pt->event_loop_foreign || !ptpr->io_loop)
|
||||
continue;
|
||||
|
||||
if (!context->finalize_destroy_after_internal_loops_stopped) {
|
||||
event_base_loopexit(pt->event.io_loop, NULL);
|
||||
event_base_loopexit(ptpr->io_loop, NULL);
|
||||
continue;
|
||||
}
|
||||
while (budget-- &&
|
||||
(m = event_base_loop(pt->event.io_loop, EVLOOP_NONBLOCK)))
|
||||
(m = event_base_loop(ptpr->io_loop, EVLOOP_NONBLOCK)))
|
||||
;
|
||||
#if 0
|
||||
if (m) {
|
||||
lwsl_err("%s: tsi %d: NOT everything closed\n",
|
||||
__func__, n);
|
||||
event_base_dump_events(pt->event.io_loop, stderr);
|
||||
event_base_dump_events(ptpr->io_loop, stderr);
|
||||
} else
|
||||
lwsl_debug("%s: %d: everything closed OK\n", __func__, n);
|
||||
#endif
|
||||
lwsl_err("%s: event_base_free\n", __func__);
|
||||
event_base_free(pt->event.io_loop);
|
||||
pt->event.io_loop = NULL;
|
||||
|
||||
event_base_free(ptpr->io_loop);
|
||||
ptpr->io_loop = NULL;
|
||||
}
|
||||
|
||||
lwsl_debug("%s: out\n", __func__);
|
||||
|
@ -453,7 +480,7 @@ elops_destroy_context2_event(struct lws_context *context)
|
|||
return 0;
|
||||
}
|
||||
|
||||
struct lws_event_loop_ops event_loop_ops_event = {
|
||||
static const struct lws_event_loop_ops event_loop_ops_event = {
|
||||
/* name */ "libevent",
|
||||
/* init_context */ elops_init_context_event,
|
||||
/* destroy_context1 */ NULL,
|
||||
|
@ -470,4 +497,22 @@ struct lws_event_loop_ops event_loop_ops_event = {
|
|||
/* destroy wsi */ elops_destroy_wsi_event,
|
||||
|
||||
/* flags */ 0,
|
||||
|
||||
/* evlib_size_ctx */ 0,
|
||||
/* evlib_size_pt */ sizeof(struct lws_pt_eventlibs_libevent),
|
||||
/* evlib_size_vh */ 0,
|
||||
/* evlib_size_wsi */ sizeof(struct lws_wsi_eventlibs_libevent),
|
||||
};
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS)
|
||||
LWS_VISIBLE
|
||||
#endif
|
||||
const lws_plugin_evlib_t evlib_event = {
|
||||
.hdr = {
|
||||
"libevent event loop",
|
||||
"lws_evlib_plugin",
|
||||
LWS_PLUGIN_API_MAGIC
|
||||
},
|
||||
|
||||
.ops = &event_loop_ops_event
|
||||
};
|
||||
|
|
|
@ -24,23 +24,26 @@
|
|||
|
||||
#include <event2/event.h>
|
||||
|
||||
struct lws_signal_watcher_libevent {
|
||||
struct event *watcher;
|
||||
struct lws_context *context;
|
||||
};
|
||||
|
||||
struct lws_pt_eventlibs_libevent {
|
||||
struct event_base *io_loop;
|
||||
struct event *hrtimer;
|
||||
struct event *idle_timer;
|
||||
struct lws_signal_watcher_libevent w_sigint;
|
||||
};
|
||||
|
||||
struct lws_io_watcher_libevent {
|
||||
struct event *watcher;
|
||||
struct lws_context *context;
|
||||
uint8_t actual_events;
|
||||
char set;
|
||||
};
|
||||
|
||||
struct lws_signal_watcher_libevent {
|
||||
struct event *watcher;
|
||||
struct lws_wsi_eventlibs_libevent {
|
||||
struct lws_io_watcher_libevent w_read;
|
||||
struct lws_io_watcher_libevent w_write;
|
||||
};
|
||||
|
||||
struct lws_context_eventlibs_libevent {
|
||||
int placeholder;
|
||||
};
|
||||
|
||||
extern struct lws_event_loop_ops event_loop_ops_event;
|
||||
|
|
|
@ -47,7 +47,6 @@ message("libuv include dir: ${LIBUV_INCLUDE_DIRS}")
|
|||
message("libuv libraries: ${LIBUV_LIBRARIES}")
|
||||
|
||||
include_directories("${LIBUV_INCLUDE_DIRS}")
|
||||
list(APPEND LIB_LIST ${LIBUV_LIBRARIES})
|
||||
|
||||
CHECK_INCLUDE_FILE(uv-version.h LWS_HAVE_UV_VERSION_H)
|
||||
# libuv changed the location in 1.21.0. Retain both
|
||||
|
@ -55,11 +54,27 @@ CHECK_INCLUDE_FILE(uv-version.h LWS_HAVE_UV_VERSION_H)
|
|||
if (NOT LWS_HAVE_UV_VERSION_H)
|
||||
CHECK_INCLUDE_FILE(uv/version.h LWS_HAVE_NEW_UV_VERSION_H)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_EVLIB_PLUGINS AND LWS_WITH_LIBUV)
|
||||
|
||||
if (LWS_WITH_NETWORK)
|
||||
list(APPEND SOURCES
|
||||
event-libs/libuv/libuv.c)
|
||||
endif()
|
||||
create_evlib_plugin(evlib_uv
|
||||
libuv.c
|
||||
private-lib-event-libs-libuv.h
|
||||
${LIBUV_LIBRARIES})
|
||||
endif()
|
||||
|
||||
# wanting libuv in the library is a separate question than
|
||||
# wanting libuv as a selectable event loop plugin
|
||||
# we only came here because LWS_WITH_LIBUV or LWS_WITH_LIBUV_INTERNAL
|
||||
|
||||
if ((NOT LWS_WITH_EVLIB_PLUGINS) OR LWS_WITH_LIBUV_INTERNAL)
|
||||
list(APPEND LIB_LIST ${LIBUV_LIBRARIES})
|
||||
|
||||
if (LWS_WITH_NETWORK)
|
||||
list(APPEND SOURCES
|
||||
event-libs/libuv/libuv.c)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
#
|
||||
# Keep explicit parent scope exports at end
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
*/
|
||||
|
||||
#include "private-lib-core.h"
|
||||
#include "private-lib-event-libs-libuv.h"
|
||||
|
||||
#define pt_to_priv_uv(_pt) ((struct lws_pt_eventlibs_libuv *)(_pt)->evlib_pt)
|
||||
#define wsi_to_priv_uv(_w) ((struct lws_wsi_eventlibs_libuv *)(_w)->evlib_wsi)
|
||||
|
||||
static void
|
||||
lws_uv_sultimer_cb(uv_timer_t *timer
|
||||
|
@ -31,15 +35,17 @@ lws_uv_sultimer_cb(uv_timer_t *timer
|
|||
#endif
|
||||
)
|
||||
{
|
||||
struct lws_context_per_thread *pt = lws_container_of(timer,
|
||||
struct lws_context_per_thread, uv.sultimer);
|
||||
struct lws_pt_eventlibs_libuv *ptpr = lws_container_of(timer,
|
||||
struct lws_pt_eventlibs_libuv, sultimer);
|
||||
struct lws_context_per_thread *pt = lws_container_of(ptpr,
|
||||
struct lws_context_per_thread, evlib_pt);
|
||||
lws_usec_t us;
|
||||
|
||||
lws_pt_lock(pt, __func__);
|
||||
us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
|
||||
lws_now_usecs());
|
||||
if (us)
|
||||
uv_timer_start(&pt->uv.sultimer, lws_uv_sultimer_cb,
|
||||
uv_timer_start(&pt_to_priv_uv(pt)->sultimer, lws_uv_sultimer_cb,
|
||||
LWS_US_TO_MS(us), 0);
|
||||
lws_pt_unlock(pt);
|
||||
}
|
||||
|
@ -50,9 +56,10 @@ lws_uv_idle(uv_idle_t *handle
|
|||
, int status
|
||||
#endif
|
||||
)
|
||||
{
|
||||
struct lws_context_per_thread *pt = lws_container_of(handle,
|
||||
struct lws_context_per_thread, uv.idle);
|
||||
{ struct lws_pt_eventlibs_libuv *ptpr = lws_container_of(handle,
|
||||
struct lws_pt_eventlibs_libuv, idle);
|
||||
struct lws_context_per_thread *pt = lws_container_of(ptpr,
|
||||
struct lws_context_per_thread, evlib_pt);
|
||||
lws_usec_t us;
|
||||
|
||||
lws_service_do_ripe_rxflow(pt);
|
||||
|
@ -70,7 +77,7 @@ lws_uv_idle(uv_idle_t *handle
|
|||
us = __lws_sul_service_ripe(pt->pt_sul_owner, LWS_COUNT_PT_SUL_OWNERS,
|
||||
lws_now_usecs());
|
||||
if (us)
|
||||
uv_timer_start(&pt->uv.sultimer, lws_uv_sultimer_cb,
|
||||
uv_timer_start(&pt_to_priv_uv(pt)->sultimer, lws_uv_sultimer_cb,
|
||||
LWS_US_TO_MS(us), 0);
|
||||
lws_pt_unlock(pt);
|
||||
|
||||
|
@ -126,7 +133,7 @@ lws_io_cb(uv_poll_t *watcher, int status, int revents)
|
|||
return;
|
||||
}
|
||||
|
||||
uv_idle_start(&pt->uv.idle, lws_uv_idle);
|
||||
uv_idle_start(&pt_to_priv_uv(pt)->idle, lws_uv_idle);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -161,7 +168,7 @@ lws_libuv_stop(struct lws_context *context)
|
|||
pt = &context->pt[m];
|
||||
|
||||
if (pt->pipe_wsi) {
|
||||
uv_poll_stop(pt->pipe_wsi->w_read.uv.pwatcher);
|
||||
uv_poll_stop(wsi_to_priv_uv(pt->pipe_wsi)->w_read.pwatcher);
|
||||
lws_destroy_event_pipe(pt->pipe_wsi);
|
||||
pt->pipe_wsi = NULL;
|
||||
}
|
||||
|
@ -231,8 +238,8 @@ lws_uv_close_cb_sa(uv_handle_t *handle)
|
|||
for (n = 0; n < context->count_threads; n++) {
|
||||
struct lws_context_per_thread *pt = &context->pt[n];
|
||||
|
||||
if (pt->uv.io_loop && !pt->event_loop_foreign)
|
||||
uv_stop(pt->uv.io_loop);
|
||||
if (pt_to_priv_uv(pt)->io_loop && !pt->event_loop_foreign)
|
||||
uv_stop(pt_to_priv_uv(pt)->io_loop);
|
||||
}
|
||||
|
||||
if (!context->pt[0].event_loop_foreign) {
|
||||
|
@ -286,8 +293,8 @@ lws_close_all_handles_in_loop(uv_loop_t *loop)
|
|||
void
|
||||
lws_libuv_stop_without_kill(const struct lws_context *context, int tsi)
|
||||
{
|
||||
if (context->pt[tsi].uv.io_loop)
|
||||
uv_stop(context->pt[tsi].uv.io_loop);
|
||||
if (pt_to_priv_uv(&context->pt[tsi])->io_loop)
|
||||
uv_stop(pt_to_priv_uv(&context->pt[tsi])->io_loop);
|
||||
}
|
||||
|
||||
|
||||
|
@ -295,8 +302,8 @@ lws_libuv_stop_without_kill(const struct lws_context *context, int tsi)
|
|||
uv_loop_t *
|
||||
lws_uv_getloop(struct lws_context *context, int tsi)
|
||||
{
|
||||
if (context->pt[tsi].uv.io_loop)
|
||||
return context->pt[tsi].uv.io_loop;
|
||||
if (pt_to_priv_uv(&context->pt[tsi])->io_loop)
|
||||
return pt_to_priv_uv(&context->pt[tsi])->io_loop;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
@ -304,7 +311,7 @@ lws_uv_getloop(struct lws_context *context, int tsi)
|
|||
int
|
||||
lws_libuv_check_watcher_active(struct lws *wsi)
|
||||
{
|
||||
uv_handle_t *h = (uv_handle_t *)wsi->w_read.uv.pwatcher;
|
||||
uv_handle_t *h = (uv_handle_t *)wsi_to_priv_uv(wsi)->w_read.pwatcher;
|
||||
|
||||
if (!h)
|
||||
return 0;
|
||||
|
@ -321,7 +328,7 @@ elops_init_context_uv(struct lws_context *context,
|
|||
context->eventlib_signal_cb = info->signal_cb;
|
||||
|
||||
for (n = 0; n < context->count_threads; n++)
|
||||
context->pt[n].w_sigint.context = context;
|
||||
pt_to_priv_uv(&context->pt[n])->w_sigint.context = context;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -340,7 +347,7 @@ elops_destroy_context1_uv(struct lws_context *context)
|
|||
|
||||
if (!pt->event_loop_foreign) {
|
||||
|
||||
while (budget-- && (m = uv_run(pt->uv.io_loop,
|
||||
while (budget-- && (m = uv_run(pt_to_priv_uv(pt)->io_loop,
|
||||
UV_RUN_NOWAIT)))
|
||||
;
|
||||
if (m)
|
||||
|
@ -365,15 +372,15 @@ elops_destroy_context2_uv(struct lws_context *context)
|
|||
|
||||
/* only for internal loops... */
|
||||
|
||||
if (!pt->event_loop_foreign && pt->uv.io_loop) {
|
||||
if (!pt->event_loop_foreign && pt_to_priv_uv(pt)->io_loop) {
|
||||
internal = 1;
|
||||
if (!context->finalize_destroy_after_internal_loops_stopped)
|
||||
uv_stop(pt->uv.io_loop);
|
||||
uv_stop(pt_to_priv_uv(pt)->io_loop);
|
||||
else {
|
||||
#if UV_VERSION_MAJOR > 0
|
||||
uv_loop_close(pt->uv.io_loop);
|
||||
uv_loop_close(pt_to_priv_uv(pt)->io_loop);
|
||||
#endif
|
||||
lws_free_set_NULL(pt->uv.io_loop);
|
||||
lws_free_set_NULL(pt_to_priv_uv(pt)->io_loop);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,14 +392,14 @@ static int
|
|||
elops_wsi_logical_close_uv(struct lws *wsi)
|
||||
{
|
||||
if (!lws_socket_is_valid(wsi->desc.sockfd) &&
|
||||
wsi->role_ops != &role_ops_raw_file)
|
||||
wsi->role_ops && strcmp(wsi->role_ops->name, "raw-file"))
|
||||
return 0;
|
||||
|
||||
if (wsi->listener || wsi->event_pipe) {
|
||||
lwsl_debug("%s: %p: %d %d stop listener / pipe poll\n",
|
||||
__func__, wsi, wsi->listener, wsi->event_pipe);
|
||||
if (wsi->w_read.uv.pwatcher)
|
||||
uv_poll_stop(wsi->w_read.uv.pwatcher);
|
||||
if (wsi_to_priv_uv(wsi)->w_read.pwatcher)
|
||||
uv_poll_stop(wsi_to_priv_uv(wsi)->w_read.pwatcher);
|
||||
}
|
||||
lwsl_debug("%s: lws_libuv_closehandle: wsi %p\n", __func__, wsi);
|
||||
/*
|
||||
|
@ -426,7 +433,7 @@ lws_libuv_closewsi_m(uv_handle_t* handle)
|
|||
static void
|
||||
elops_close_handle_manually_uv(struct lws *wsi)
|
||||
{
|
||||
uv_handle_t *h = (uv_handle_t *)wsi->w_read.uv.pwatcher;
|
||||
uv_handle_t *h = (uv_handle_t *)wsi_to_priv_uv(wsi)->w_read.pwatcher;
|
||||
|
||||
lwsl_debug("%s: lws_libuv_closehandle: wsi %p\n", __func__, wsi);
|
||||
|
||||
|
@ -442,7 +449,7 @@ elops_close_handle_manually_uv(struct lws *wsi)
|
|||
*/
|
||||
|
||||
wsi->desc.sockfd = LWS_SOCK_INVALID;
|
||||
wsi->w_read.uv.pwatcher = NULL;
|
||||
wsi_to_priv_uv(wsi)->w_read.pwatcher = NULL;
|
||||
wsi->told_event_loop_closed = 1;
|
||||
|
||||
uv_close(h, lws_libuv_closewsi_m);
|
||||
|
@ -452,23 +459,22 @@ static int
|
|||
elops_accept_uv(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
struct lws_io_watcher_libuv *w_read = &wsi_to_priv_uv(wsi)->w_read;
|
||||
|
||||
wsi->w_read.context = wsi->a.context;
|
||||
w_read->context = wsi->a.context;
|
||||
|
||||
wsi->w_read.uv.pwatcher =
|
||||
lws_malloc(sizeof(*wsi->w_read.uv.pwatcher), "uvh");
|
||||
if (!wsi->w_read.uv.pwatcher)
|
||||
w_read->pwatcher = lws_malloc(sizeof(*w_read->pwatcher), "uvh");
|
||||
if (!w_read->pwatcher)
|
||||
return -1;
|
||||
|
||||
if (wsi->role_ops->file_handle)
|
||||
uv_poll_init(pt->uv.io_loop, wsi->w_read.uv.pwatcher,
|
||||
uv_poll_init(pt_to_priv_uv(pt)->io_loop, w_read->pwatcher,
|
||||
(int)(lws_intptr_t)wsi->desc.filefd);
|
||||
else
|
||||
uv_poll_init_socket(pt->uv.io_loop,
|
||||
wsi->w_read.uv.pwatcher,
|
||||
wsi->desc.sockfd);
|
||||
uv_poll_init_socket(pt_to_priv_uv(pt)->io_loop,
|
||||
w_read->pwatcher, wsi->desc.sockfd);
|
||||
|
||||
((uv_handle_t *)wsi->w_read.uv.pwatcher)->data = (void *)wsi;
|
||||
((uv_handle_t *)w_read->pwatcher)->data = (void *)wsi;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -477,14 +483,14 @@ static void
|
|||
elops_io_uv(struct lws *wsi, int flags)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
struct lws_io_watcher *w = &wsi->w_read;
|
||||
struct lws_io_watcher_libuv *w = &(wsi_to_priv_uv(wsi)->w_read);
|
||||
int current_events = w->actual_events & (UV_READABLE | UV_WRITABLE);
|
||||
|
||||
lwsl_debug("%s: %p: %d\n", __func__, wsi, flags);
|
||||
|
||||
/* w->context is set after the loop is initialized */
|
||||
|
||||
if (!pt->uv.io_loop || !w->context) {
|
||||
if (!pt_to_priv_uv(pt)->io_loop || !w->context) {
|
||||
lwsl_info("%s: no io loop yet\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
@ -495,7 +501,7 @@ elops_io_uv(struct lws *wsi, int flags)
|
|||
assert(0);
|
||||
}
|
||||
|
||||
if (!w->uv.pwatcher || wsi->told_event_loop_closed) {
|
||||
if (!w->pwatcher || wsi->told_event_loop_closed) {
|
||||
lwsl_info("%s: no watcher\n", __func__);
|
||||
|
||||
return;
|
||||
|
@ -508,7 +514,7 @@ elops_io_uv(struct lws *wsi, int flags)
|
|||
if (flags & LWS_EV_READ)
|
||||
current_events |= UV_READABLE;
|
||||
|
||||
uv_poll_start(w->uv.pwatcher, current_events, lws_io_cb);
|
||||
uv_poll_start(w->pwatcher, current_events, lws_io_cb);
|
||||
} else {
|
||||
if (flags & LWS_EV_WRITE)
|
||||
current_events &= ~UV_WRITABLE;
|
||||
|
@ -517,10 +523,9 @@ elops_io_uv(struct lws *wsi, int flags)
|
|||
current_events &= ~UV_READABLE;
|
||||
|
||||
if (!(current_events & (UV_READABLE | UV_WRITABLE)))
|
||||
uv_poll_stop(w->uv.pwatcher);
|
||||
uv_poll_stop(w->pwatcher);
|
||||
else
|
||||
uv_poll_start(w->uv.pwatcher, current_events,
|
||||
lws_io_cb);
|
||||
uv_poll_start(w->pwatcher, current_events, lws_io_cb);
|
||||
}
|
||||
|
||||
w->actual_events = current_events;
|
||||
|
@ -530,26 +535,26 @@ static int
|
|||
elops_init_vhost_listen_wsi_uv(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt;
|
||||
struct lws_io_watcher_libuv *w_read = &wsi_to_priv_uv(wsi)->w_read;
|
||||
int n;
|
||||
|
||||
if (!wsi)
|
||||
return 0;
|
||||
if (wsi->w_read.context)
|
||||
if (w_read->context)
|
||||
return 0;
|
||||
|
||||
pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
if (!pt->uv.io_loop)
|
||||
if (!pt_to_priv_uv(pt)->io_loop)
|
||||
return 0;
|
||||
|
||||
wsi->w_read.context = wsi->a.context;
|
||||
w_read->context = wsi->a.context;
|
||||
|
||||
wsi->w_read.uv.pwatcher =
|
||||
lws_malloc(sizeof(*wsi->w_read.uv.pwatcher), "uvh");
|
||||
if (!wsi->w_read.uv.pwatcher)
|
||||
w_read->pwatcher = lws_malloc(sizeof(*w_read->pwatcher), "uvh");
|
||||
if (!w_read->pwatcher)
|
||||
return -1;
|
||||
|
||||
n = uv_poll_init_socket(pt->uv.io_loop, wsi->w_read.uv.pwatcher,
|
||||
wsi->desc.sockfd);
|
||||
n = uv_poll_init_socket(pt_to_priv_uv(pt)->io_loop,
|
||||
w_read->pwatcher, wsi->desc.sockfd);
|
||||
if (n) {
|
||||
lwsl_err("uv_poll_init failed %d, sockfd=%p\n", n,
|
||||
(void *)(lws_intptr_t)wsi->desc.sockfd);
|
||||
|
@ -557,7 +562,7 @@ elops_init_vhost_listen_wsi_uv(struct lws *wsi)
|
|||
return -1;
|
||||
}
|
||||
|
||||
((uv_handle_t *)wsi->w_read.uv.pwatcher)->data = (void *)wsi;
|
||||
((uv_handle_t *)w_read->pwatcher)->data = (void *)wsi;
|
||||
|
||||
elops_io_uv(wsi, LWS_EV_START | LWS_EV_READ);
|
||||
|
||||
|
@ -567,8 +572,8 @@ elops_init_vhost_listen_wsi_uv(struct lws *wsi)
|
|||
static void
|
||||
elops_run_pt_uv(struct lws_context *context, int tsi)
|
||||
{
|
||||
if (context->pt[tsi].uv.io_loop)
|
||||
uv_run(context->pt[tsi].uv.io_loop, 0);
|
||||
if (pt_to_priv_uv(&context->pt[tsi])->io_loop)
|
||||
uv_run(pt_to_priv_uv(&context->pt[tsi])->io_loop, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -582,7 +587,7 @@ elops_destroy_pt_uv(struct lws_context *context, int tsi)
|
|||
if (!lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV))
|
||||
return;
|
||||
|
||||
if (!pt->uv.io_loop)
|
||||
if (!pt_to_priv_uv(pt)->io_loop)
|
||||
return;
|
||||
|
||||
if (pt->event_loop_destroy_processing_done)
|
||||
|
@ -591,7 +596,7 @@ elops_destroy_pt_uv(struct lws_context *context, int tsi)
|
|||
pt->event_loop_destroy_processing_done = 1;
|
||||
|
||||
if (!pt->event_loop_foreign) {
|
||||
uv_signal_stop(&pt->w_sigint.uv.watcher);
|
||||
uv_signal_stop(&pt_to_priv_uv(pt)->w_sigint.watcher);
|
||||
|
||||
ns = LWS_ARRAY_SIZE(sigs);
|
||||
if (lws_check_opt(context->options,
|
||||
|
@ -599,18 +604,18 @@ elops_destroy_pt_uv(struct lws_context *context, int tsi)
|
|||
ns = 2;
|
||||
|
||||
for (m = 0; m < ns; m++) {
|
||||
uv_signal_stop(&pt->uv.signals[m]);
|
||||
uv_close((uv_handle_t *)&pt->uv.signals[m],
|
||||
uv_signal_stop(&pt_to_priv_uv(pt)->signals[m]);
|
||||
uv_close((uv_handle_t *)&pt_to_priv_uv(pt)->signals[m],
|
||||
lws_uv_close_cb_sa);
|
||||
}
|
||||
} else
|
||||
lwsl_debug("%s: not closing pt signals\n", __func__);
|
||||
|
||||
uv_timer_stop(&pt->uv.sultimer);
|
||||
uv_close((uv_handle_t *)&pt->uv.sultimer, lws_uv_close_cb_sa);
|
||||
uv_timer_stop(&pt_to_priv_uv(pt)->sultimer);
|
||||
uv_close((uv_handle_t *)&pt_to_priv_uv(pt)->sultimer, lws_uv_close_cb_sa);
|
||||
|
||||
uv_idle_stop(&pt->uv.idle);
|
||||
uv_close((uv_handle_t *)&pt->uv.idle, lws_uv_close_cb_sa);
|
||||
uv_idle_stop(&pt_to_priv_uv(pt)->idle);
|
||||
uv_close((uv_handle_t *)&pt_to_priv_uv(pt)->idle, lws_uv_close_cb_sa);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -624,11 +629,12 @@ int
|
|||
elops_init_pt_uv(struct lws_context *context, void *_loop, int tsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &context->pt[tsi];
|
||||
struct lws_pt_eventlibs_libuv *ptpriv = pt_to_priv_uv(pt);
|
||||
struct lws_vhost *vh = context->vhost_list;
|
||||
int status = 0, n, ns, first = 1;
|
||||
uv_loop_t *loop = (uv_loop_t *)_loop;
|
||||
|
||||
if (!pt->uv.io_loop) {
|
||||
if (!ptpriv->io_loop) {
|
||||
if (!loop) {
|
||||
loop = lws_malloc(sizeof(*loop), "libuv loop");
|
||||
if (!loop) {
|
||||
|
@ -647,9 +653,9 @@ elops_init_pt_uv(struct lws_context *context, void *_loop, int tsi)
|
|||
pt->event_loop_foreign = 1;
|
||||
}
|
||||
|
||||
pt->uv.io_loop = loop;
|
||||
uv_idle_init(loop, &pt->uv.idle);
|
||||
LWS_UV_REFCOUNT_STATIC_HANDLE_NEW(&pt->uv.idle, context);
|
||||
ptpriv->io_loop = loop;
|
||||
uv_idle_init(loop, &ptpriv->idle);
|
||||
LWS_UV_REFCOUNT_STATIC_HANDLE_NEW(&ptpriv->idle, context);
|
||||
|
||||
|
||||
ns = LWS_ARRAY_SIZE(sigs);
|
||||
|
@ -658,13 +664,13 @@ elops_init_pt_uv(struct lws_context *context, void *_loop, int tsi)
|
|||
ns = 2;
|
||||
|
||||
if (!pt->event_loop_foreign) {
|
||||
assert(ns <= (int)LWS_ARRAY_SIZE(pt->uv.signals));
|
||||
assert(ns <= (int)LWS_ARRAY_SIZE(ptpriv->signals));
|
||||
for (n = 0; n < ns; n++) {
|
||||
uv_signal_init(loop, &pt->uv.signals[n]);
|
||||
LWS_UV_REFCOUNT_STATIC_HANDLE_NEW(&pt->uv.signals[n],
|
||||
uv_signal_init(loop, &ptpriv->signals[n]);
|
||||
LWS_UV_REFCOUNT_STATIC_HANDLE_NEW(&ptpriv->signals[n],
|
||||
context);
|
||||
pt->uv.signals[n].data = pt->context;
|
||||
uv_signal_start(&pt->uv.signals[n],
|
||||
ptpriv->signals[n].data = pt->context;
|
||||
uv_signal_start(&ptpriv->signals[n],
|
||||
lws_uv_signal_handler, sigs[n]);
|
||||
}
|
||||
}
|
||||
|
@ -687,8 +693,8 @@ elops_init_pt_uv(struct lws_context *context, void *_loop, int tsi)
|
|||
if (!first)
|
||||
return status;
|
||||
|
||||
uv_timer_init(pt->uv.io_loop, &pt->uv.sultimer);
|
||||
LWS_UV_REFCOUNT_STATIC_HANDLE_NEW(&pt->uv.sultimer, context);
|
||||
uv_timer_init(ptpriv->io_loop, &ptpriv->sultimer);
|
||||
LWS_UV_REFCOUNT_STATIC_HANDLE_NEW(&ptpriv->sultimer, context);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -710,7 +716,8 @@ lws_libuv_closewsi(uv_handle_t* handle)
|
|||
*/
|
||||
|
||||
#if defined(LWS_WITH_SERVER)
|
||||
if (wsi->role_ops == &role_ops_listen && wsi->a.context->deprecated) {
|
||||
if (wsi->role_ops && !strcmp(wsi->role_ops->name, "listen") &&
|
||||
wsi->a.context->deprecated) {
|
||||
lspd = 1;
|
||||
context->deprecation_pending_listen_close_count--;
|
||||
if (!context->deprecation_pending_listen_close_count)
|
||||
|
@ -773,8 +780,9 @@ void
|
|||
lws_libuv_closehandle(struct lws *wsi)
|
||||
{
|
||||
uv_handle_t* handle;
|
||||
struct lws_io_watcher_libuv *w_read = &wsi_to_priv_uv(wsi)->w_read;
|
||||
|
||||
if (!wsi->w_read.uv.pwatcher)
|
||||
if (!w_read->pwatcher)
|
||||
return;
|
||||
|
||||
if (wsi->told_event_loop_closed) {
|
||||
|
@ -791,16 +799,16 @@ lws_libuv_closehandle(struct lws *wsi)
|
|||
* handle->data.
|
||||
*/
|
||||
|
||||
handle = (uv_handle_t *)wsi->w_read.uv.pwatcher;
|
||||
handle = (uv_handle_t *)w_read->pwatcher;
|
||||
|
||||
/* ensure we can only do this once */
|
||||
|
||||
wsi->w_read.uv.pwatcher = NULL;
|
||||
w_read->pwatcher = NULL;
|
||||
|
||||
uv_close(handle, lws_libuv_closewsi);
|
||||
}
|
||||
|
||||
struct lws_event_loop_ops event_loop_ops_uv = {
|
||||
static const struct lws_event_loop_ops event_loop_ops_uv = {
|
||||
/* name */ "libuv",
|
||||
/* init_context */ elops_init_context_uv,
|
||||
/* destroy_context1 */ elops_destroy_context1_uv,
|
||||
|
@ -817,4 +825,23 @@ struct lws_event_loop_ops event_loop_ops_uv = {
|
|||
/* destroy wsi */ NULL,
|
||||
|
||||
/* flags */ 0,
|
||||
|
||||
/* evlib_size_ctx */ sizeof(struct lws_context_eventlibs_libuv),
|
||||
/* evlib_size_pt */ sizeof(struct lws_pt_eventlibs_libuv),
|
||||
/* evlib_size_vh */ 0,
|
||||
/* evlib_size_wsi */ sizeof(struct lws_io_watcher_libuv),
|
||||
};
|
||||
|
||||
#if defined(LWS_WITH_EVLIB_PLUGINS)
|
||||
LWS_VISIBLE
|
||||
#endif
|
||||
const lws_plugin_evlib_t evlib_uv = {
|
||||
.hdr = {
|
||||
"libuv event loop",
|
||||
"lws_evlib_plugin",
|
||||
LWS_PLUGIN_API_MAGIC
|
||||
},
|
||||
|
||||
.ops = &event_loop_ops_uv
|
||||
};
|
||||
|
||||
|
|
|
@ -46,11 +46,17 @@
|
|||
(--(LWS_UV_REFCOUNT_STATIC_HANDLE_TO_CONTEXT(_x)-> \
|
||||
count_event_loop_static_asset_handles))
|
||||
|
||||
struct lws_signal_watcher_libuv {
|
||||
uv_signal_t watcher;
|
||||
struct lws_context *context;
|
||||
};
|
||||
|
||||
struct lws_pt_eventlibs_libuv {
|
||||
uv_loop_t *io_loop;
|
||||
uv_signal_t signals[8];
|
||||
uv_timer_t sultimer;
|
||||
uv_idle_t idle;
|
||||
struct lws_signal_watcher_libuv w_sigint;
|
||||
};
|
||||
|
||||
struct lws_context_eventlibs_libuv {
|
||||
|
@ -59,14 +65,14 @@ struct lws_context_eventlibs_libuv {
|
|||
|
||||
struct lws_io_watcher_libuv {
|
||||
uv_poll_t *pwatcher;
|
||||
struct lws_context *context;
|
||||
uint8_t actual_events;
|
||||
};
|
||||
|
||||
struct lws_signal_watcher_libuv {
|
||||
uv_signal_t watcher;
|
||||
struct lws_wsi_eventlibs_libuv {
|
||||
struct lws_io_watcher_libuv w_read;
|
||||
};
|
||||
|
||||
extern struct lws_event_loop_ops event_loop_ops_uv;
|
||||
|
||||
uv_loop_t *
|
||||
lws_uv_getloop(struct lws_context *context, int tsi);
|
||||
|
||||
|
|
|
@ -19,12 +19,11 @@
|
|||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*
|
||||
* This is included from private-lib-core.h if LWS_ROLE_WS
|
||||
* IN THE SOFTWARE
|
||||
*/
|
||||
|
||||
#include <private-lib-core.h>
|
||||
#include "private-lib-event-libs-poll.h"
|
||||
|
||||
struct lws_event_loop_ops event_loop_ops_poll = {
|
||||
/* name */ "poll",
|
||||
|
@ -43,4 +42,19 @@ struct lws_event_loop_ops event_loop_ops_poll = {
|
|||
/* destroy wsi */ NULL,
|
||||
|
||||
/* flags */ LELOF_ISPOLL,
|
||||
|
||||
/* evlib_size_ctx */ 0,
|
||||
/* evlib_size_pt */ 0,
|
||||
/* evlib_size_vh */ 0,
|
||||
/* evlib_size_wsi */ 0,
|
||||
};
|
||||
|
||||
const lws_plugin_evlib_t evlib_poll = {
|
||||
.hdr = {
|
||||
"poll",
|
||||
"lws_evlib_plugin",
|
||||
LWS_PLUGIN_API_MAGIC
|
||||
},
|
||||
|
||||
.ops = &event_loop_ops_poll
|
||||
};
|
||||
|
|
|
@ -60,27 +60,9 @@ struct lws_event_loop_ops {
|
|||
void (*destroy_wsi)(struct lws *wsi);
|
||||
|
||||
uint8_t flags;
|
||||
|
||||
uint16_t evlib_size_ctx;
|
||||
uint16_t evlib_size_pt;
|
||||
uint16_t evlib_size_vh;
|
||||
uint16_t evlib_size_wsi;
|
||||
};
|
||||
|
||||
/* bring in event libs private declarations */
|
||||
|
||||
#if defined(LWS_WITH_POLL)
|
||||
#include "private-lib-event-libs-poll.h"
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
#include "private-lib-event-libs-libuv.h"
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
#include "private-lib-event-libs-libevent.h"
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
#include "private-lib-event-libs-glib.h"
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
#include "private-lib-event-libs-libev.h"
|
||||
#endif
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
#endif
|
||||
#endif /* win32 */
|
||||
|
||||
#define COMBO_SIZEOF 256
|
||||
#define COMBO_SIZEOF 512
|
||||
|
||||
#if !defined(LWS_PLAT_FREERTOS)
|
||||
|
||||
|
@ -189,7 +189,7 @@ lws_dir(const char *dirpath, void *user, lws_dir_callback_function cb)
|
|||
}
|
||||
#endif
|
||||
if (cb(dirpath, user, &lde)) {
|
||||
while (i++ < n)
|
||||
while (++i < n)
|
||||
free(namelist[i]);
|
||||
goto bail;
|
||||
}
|
||||
|
@ -265,7 +265,16 @@ lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
|
|||
lws_snprintf(path, sizeof(path), "%s%c%s", dirpath, csep, lde->name);
|
||||
|
||||
if (lde->type == LDOT_DIR) {
|
||||
lws_dir(path, NULL, lws_dir_rm_rf_cb);
|
||||
#if !defined(WIN32) && !defined(_WIN32)
|
||||
char dummy[8];
|
||||
/*
|
||||
* hm... eg, recursive dir symlinks can show up a LDOT_DIR
|
||||
* here
|
||||
*/
|
||||
if (readlink(path, dummy, sizeof(dummy)) < 0)
|
||||
#endif
|
||||
lws_dir(path, NULL, lws_dir_rm_rf_cb);
|
||||
|
||||
if (rmdir(path))
|
||||
lwsl_warn("%s: rmdir %s failed %d\n", __func__, path, errno);
|
||||
} else {
|
||||
|
@ -287,7 +296,8 @@ lws_dir_rm_rf_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS)
|
||||
#if defined(LWS_WITH_PLUGINS) || \
|
||||
(defined(LWS_WITH_EVLIB_PLUGINS) && defined(LWS_WITH_EVENT_LIBS))
|
||||
|
||||
struct lws_plugins_args {
|
||||
struct lws_plugin **pplugin;
|
||||
|
@ -301,19 +311,38 @@ static int
|
|||
lws_plugins_dir_cb(const char *dirpath, void *user, struct lws_dir_entry *lde)
|
||||
{
|
||||
struct lws_plugins_args *pa = (struct lws_plugins_args *)user;
|
||||
char path[256];
|
||||
char path[256], base[64], *q = base;
|
||||
const char *p;
|
||||
|
||||
if (strlen(lde->name) < 7)
|
||||
return 0;
|
||||
|
||||
/* if he's given a filter, only match if name + 3 matches it */
|
||||
if (pa->filter && strncmp(lde->name + 3, pa->filter, strlen(pa->filter)))
|
||||
/*
|
||||
* The actual plugin names for protocol plugins look like
|
||||
* "libprotocol_lws_ssh_base.so" and for event libs
|
||||
* "libwebsockets-evlib_ev.so"... to recover the base name of
|
||||
* "lws_ssh_base" and "evlib_ev" we strip from the left to after the
|
||||
* first _ or -, and then truncate at the first .
|
||||
*/
|
||||
|
||||
p = lde->name;
|
||||
while (*p && *p != '_' && *p != '-')
|
||||
p++;
|
||||
if (!*p)
|
||||
return 0;
|
||||
p++;
|
||||
while (*p && *p != '.' && lws_ptr_diff(q, base) < (int)sizeof(base) - 1)
|
||||
*q++ = *p++;
|
||||
*q = '\0';
|
||||
|
||||
/* if he's given a filter, only match if base matches it */
|
||||
if (pa->filter && strcmp(base, pa->filter))
|
||||
return 0;
|
||||
|
||||
lws_snprintf(path, sizeof(path) - 1, "%s/%s", dirpath, lde->name);
|
||||
lwsl_notice(" %s\n", path);
|
||||
|
||||
return !lws_plat_dlopen(pa->pplugin, path, lde->name + 3, pa->_class,
|
||||
return !lws_plat_dlopen(pa->pplugin, path, base, pa->_class,
|
||||
pa->each, pa->each_user);
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ if (LWS_WITH_NETWORK)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_PLUGINS AND LWS_WITH_LIBUV)
|
||||
if (LWS_WITH_PLUGINS OR LWS_WITH_EVLIB_PLUGINS)
|
||||
list(APPEND SOURCES plat/unix/unix-plugins.c)
|
||||
endif()
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@ lws_sul_plat_unix(lws_sorted_usec_list_t *sul)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS)
|
||||
static int
|
||||
protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
|
||||
{
|
||||
|
@ -92,6 +93,7 @@ protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
lws_plat_init(struct lws_context *context,
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* libwebsockets - small server side websockets and web server implementation
|
||||
*
|
||||
* Copyright (C) 2010 - 2019 Andy Green <andy@warmcat.com>
|
||||
* Copyright (C) 2010 - 2020 Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to
|
||||
|
@ -27,15 +27,17 @@
|
|||
#endif
|
||||
#include "private-lib-core.h"
|
||||
|
||||
|
||||
int
|
||||
lws_plat_pipe_create(struct lws *wsi)
|
||||
{
|
||||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
|
||||
#if defined(LWS_HAVE_EVENTFD)
|
||||
pt->dummy_pipe_fds[0] = eventfd(0, EFD_CLOEXEC|EFD_NONBLOCK);
|
||||
pt->dummy_pipe_fds[0] = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
|
||||
pt->dummy_pipe_fds[1] = -1;
|
||||
return pt->dummy_pipe_fds[0]<0?-1:0;
|
||||
|
||||
return pt->dummy_pipe_fds[0] < 0 ? -1 : 0;
|
||||
|
||||
#elif defined(LWS_HAVE_PIPE2)
|
||||
return pipe2(pt->dummy_pipe_fds, O_NONBLOCK);
|
||||
#else
|
||||
|
@ -49,6 +51,7 @@ lws_plat_pipe_signal(struct lws *wsi)
|
|||
struct lws_context_per_thread *pt = &wsi->a.context->pt[(int)wsi->tsi];
|
||||
#if defined(LWS_HAVE_EVENTFD)
|
||||
eventfd_t value = 1;
|
||||
|
||||
return eventfd_write(pt->dummy_pipe_fds[0], value);
|
||||
#else
|
||||
char buf = 0;
|
||||
|
|
|
@ -30,10 +30,9 @@
|
|||
#include <pwd.h>
|
||||
#include <grp.h>
|
||||
|
||||
#ifdef LWS_WITH_PLUGINS
|
||||
#if defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include <dirent.h>
|
||||
|
||||
const lws_plugin_header_t *
|
||||
lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
|
||||
|
|
|
@ -55,6 +55,7 @@ lws_plat_context_early_init(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS)
|
||||
static int
|
||||
protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
|
||||
{
|
||||
|
@ -67,6 +68,7 @@ protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
lws_plat_init(struct lws_context *context,
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
#endif
|
||||
#include "private-lib-core.h"
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
|
||||
#if (defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)) && \
|
||||
(UV_VERSION_MAJOR > 0)
|
||||
|
||||
const lws_plugin_header_t *
|
||||
lws_plat_dlopen(struct lws_plugin **pplugin, const char *libpath,
|
||||
|
@ -116,11 +117,13 @@ protocol_plugin_cb(struct lws_plugin *pin, void *each_user)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
lws_plat_plugins_init(struct lws_context *context, const char * const *d)
|
||||
{
|
||||
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
|
||||
#if (defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)) && \
|
||||
(UV_VERSION_MAJOR > 0)
|
||||
if (info->plugin_dirs) {
|
||||
uv_loop_init(&context->uv.loop);
|
||||
lws_plugins_init(&context->plugin_list, info->plugin_dirs,
|
||||
|
@ -135,7 +138,8 @@ lws_plat_plugins_init(struct lws_context *context, const char * const *d)
|
|||
int
|
||||
lws_plat_plugins_destroy(struct lws_context * context)
|
||||
{
|
||||
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
|
||||
#if (defined(LWS_WITH_PLUGINS) || defined(LWS_WITH_EVLIB_PLUGINS)) && \
|
||||
(UV_VERSION_MAJOR > 0)
|
||||
if (lws_check_opt(context->options, LWS_SERVER_OPTION_LIBUV) &&
|
||||
context->plugin_list) {
|
||||
lws_plugins_destroy(&context->plugin_list, NULL, NULL);
|
||||
|
|
|
@ -66,6 +66,7 @@ lws_create_basic_wsi(struct lws_context *context, int tsi,
|
|||
const struct lws_role_ops *ops)
|
||||
{
|
||||
struct lws *new_wsi;
|
||||
size_t s = sizeof(*new_wsi);
|
||||
|
||||
if (!context->vhost_list)
|
||||
return NULL;
|
||||
|
@ -76,12 +77,20 @@ lws_create_basic_wsi(struct lws_context *context, int tsi,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
new_wsi = lws_zalloc(sizeof(*new_wsi), "new wsi");
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
s += vhost->context->event_loop_ops->evlib_size_wsi;
|
||||
#endif
|
||||
|
||||
new_wsi = lws_zalloc(s, "new wsi");
|
||||
if (new_wsi == NULL) {
|
||||
lwsl_err("Out of memory for new connection\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
new_wsi->evlib_wsi = (uint8_t *)new_wsi + sizeof(*new_wsi);
|
||||
#endif
|
||||
|
||||
new_wsi->tsi = tsi;
|
||||
new_wsi->a.context = context;
|
||||
new_wsi->pending_timeout = NO_PENDING_TIMEOUT;
|
||||
|
@ -324,7 +333,7 @@ windows_pipe_poll_hack(lws_sorted_usec_list_t *sul)
|
|||
*/
|
||||
} else
|
||||
if (br)
|
||||
wsi1->protocol->callback(wsi1,
|
||||
wsi1->a.protocol->callback(wsi1,
|
||||
LWS_CALLBACK_RAW_RX_FILE,
|
||||
NULL, NULL, 0);
|
||||
}
|
||||
|
@ -417,8 +426,8 @@ lws_spawn_piped(const struct lws_spawn_piped_info *i)
|
|||
}
|
||||
lsp->stdwsi[n]->lsp_channel = n;
|
||||
lws_vhost_bind_wsi(i->vh, lsp->stdwsi[n]);
|
||||
lsp->stdwsi[n]->protocol = pcol;
|
||||
lsp->stdwsi[n]->opaque_user_data = i->opaque;
|
||||
lsp->stdwsi[n]->a.protocol = pcol;
|
||||
lsp->stdwsi[n]->a.opaque_user_data = i->opaque;
|
||||
|
||||
lsp->stdwsi[n]->desc.filefd = lsp->pipe_fds[n][!n];
|
||||
lsp->stdwsi[n]->file_desc = 1;
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
static struct lws *
|
||||
__lws_shadow_wsi(struct lws_dbus_ctx *ctx, DBusWatch *w, int fd, int create_ok)
|
||||
{
|
||||
size_t s = sizeof(struct lws);
|
||||
struct lws *wsi;
|
||||
|
||||
if (fd < 0 || fd >= (int)ctx->vh->context->fd_limit_per_thread) {
|
||||
|
@ -68,12 +69,20 @@ __lws_shadow_wsi(struct lws_dbus_ctx *ctx, DBusWatch *w, int fd, int create_ok)
|
|||
if (!create_ok)
|
||||
return NULL;
|
||||
|
||||
wsi = lws_zalloc(sizeof(*wsi), "shadow wsi");
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
s += ctx->vh->context->event_loop_ops->evlib_size_wsi;
|
||||
#endif
|
||||
|
||||
wsi = lws_zalloc(s, "shadow wsi");
|
||||
if (wsi == NULL) {
|
||||
lwsl_err("Out of mem\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
wsi->evlib_wsi = (uint8_t *)wsi + sizeof(*wsi);
|
||||
#endif
|
||||
|
||||
lwsl_info("%s: creating shadow wsi\n", __func__);
|
||||
|
||||
wsi->a.context = ctx->vh->context;
|
||||
|
|
|
@ -271,10 +271,21 @@ done_list:
|
|||
goto deal;
|
||||
}
|
||||
|
||||
wsi = lws_zalloc(sizeof(struct lws), "listen wsi");
|
||||
if (wsi == NULL) {
|
||||
lwsl_err("Out of mem\n");
|
||||
goto bail;
|
||||
{
|
||||
size_t s = sizeof(struct lws);
|
||||
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
s += vhost->context->event_loop_ops->evlib_size_wsi;
|
||||
#endif
|
||||
|
||||
wsi = lws_zalloc(s, "listen wsi");
|
||||
if (wsi == NULL) {
|
||||
lwsl_err("Out of mem\n");
|
||||
goto bail;
|
||||
}
|
||||
#if defined(LWS_WITH_EVENT_LIBS)
|
||||
wsi->evlib_wsi = (uint8_t *)wsi + sizeof(*wsi);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LWS_WITH_UNIX_SOCK
|
||||
|
|
|
@ -30,8 +30,14 @@ rops_handle_POLLIN_pipe(struct lws_context_per_thread *pt, struct lws *wsi,
|
|||
{
|
||||
#if defined(LWS_HAVE_EVENTFD)
|
||||
eventfd_t value;
|
||||
if (eventfd_read(wsi->desc.sockfd, &value) < 0)
|
||||
int n;
|
||||
|
||||
n = eventfd_read(wsi->desc.sockfd, &value);
|
||||
if (n < 0) {
|
||||
lwsl_notice("%s: eventfd read %d bailed errno %d\n", __func__,
|
||||
wsi->desc.sockfd, LWS_ERRNO);
|
||||
return LWS_HPI_RET_PLEASE_CLOSE_ME;
|
||||
}
|
||||
#elif !defined(WIN32) && !defined(_WIN32)
|
||||
char s[100];
|
||||
int n;
|
||||
|
|
|
@ -780,7 +780,7 @@ done:
|
|||
|
||||
lws_struct_json_init_parse(&ctx, NULL, &a);
|
||||
|
||||
m = lejp_parse(&ctx, (uint8_t *)jig_conf, strlen(jig_conf));
|
||||
m = lejp_parse(&ctx, (uint8_t *)jig_conf, (int)strlen(jig_conf));
|
||||
|
||||
if (m < 0 || !a.dest) {
|
||||
lwsl_err("%s: line %d: JSON decode failed '%s'\n",
|
||||
|
|
|
@ -28,6 +28,7 @@ if (LWS_WITH_LIBUV)
|
|||
message("libuv libraries: ${LIBUV_LIBRARIES}")
|
||||
include_directories("${LIBUV_INCLUDE_DIRS}")
|
||||
set(extralibs ${extralibs} ${LIBUV_LIBRARIES})
|
||||
list(APPEND SRCS libuv.c)
|
||||
endif()
|
||||
if (LWS_WITH_LIBEVENT)
|
||||
find_path(LIBEVENT_INCLUDE_DIRS NAMES event2/event.h)
|
||||
|
@ -36,6 +37,7 @@ if (LWS_WITH_LIBEVENT)
|
|||
message("libevent libraries: ${LIBEVENT_LIBRARIES}")
|
||||
include_directories("${LIBEVENT_INCLUDE_DIRS}")
|
||||
set(extralibs ${extralibs} ${LIBEVENT_LIBRARIES})
|
||||
list(APPEND SRCS libevent.c)
|
||||
endif()
|
||||
if (LWS_WITH_LIBEV)
|
||||
find_path(LIBEV_INCLUDE_DIRS NAMES ev.h)
|
||||
|
@ -44,6 +46,7 @@ if (LWS_WITH_LIBEV)
|
|||
message("libev libraries: ${LIBEV_LIBRARIES}")
|
||||
include_directories("${LIBEV_INCLUDE_DIRS}")
|
||||
set(extralibs ${extralibs} ${LIBEV_LIBRARIES})
|
||||
list(APPEND SRCS libev.c)
|
||||
endif()
|
||||
if (LWS_WITH_GLIB)
|
||||
set(LWS_GLIB_INCLUDE_DIRS CACHE PATH "Path to the glib include directory")
|
||||
|
@ -67,6 +70,7 @@ if (LWS_WITH_GLIB)
|
|||
message("glib libraries: ${GLIB_LIBRARIES}")
|
||||
include_directories("${GLIB_INCLUDE_DIRS}")
|
||||
set(extralibs ${extralibs} ${GLIB_LIBRARIES})
|
||||
list(APPEND SRCS glib.c)
|
||||
endif()
|
||||
|
||||
message("Extra libs: ${extralibs}")
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* lws-minimal-http-server-eventlib-foreign
|
||||
*
|
||||
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* The glib specific code
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <glib-2.0/glib.h>
|
||||
#include <glib-unix.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
typedef struct lws_glib_tag {
|
||||
GSource *gs;
|
||||
guint tag;
|
||||
} lws_glib_tag_t;
|
||||
|
||||
#define lws_gs_valid(t) (t.gs)
|
||||
#define lws_gs_destroy(t) if (lws_gs_valid(t)) { \
|
||||
g_source_remove(t.tag); \
|
||||
g_source_unref(t.gs); \
|
||||
t.gs = NULL; t.tag = 0; }
|
||||
|
||||
static GMainLoop *loop_glib;
|
||||
static lws_glib_tag_t timer_outer_glib, sighandler_glib;
|
||||
|
||||
static int
|
||||
timer_cb_glib(void *p)
|
||||
{
|
||||
foreign_timer_service(loop_glib);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_glib(void *p)
|
||||
{
|
||||
signal_cb(SIGINT);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_glib(void)
|
||||
{
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
loop_glib = g_main_loop_new(NULL, 0);
|
||||
|
||||
sighandler_glib.gs = g_unix_signal_source_new(SIGINT);
|
||||
g_source_set_callback(sighandler_glib.gs, G_SOURCE_FUNC(signal_cb_glib),
|
||||
NULL, NULL);
|
||||
sighandler_glib.tag = g_source_attach(sighandler_glib.gs,
|
||||
g_main_loop_get_context(loop_glib));
|
||||
|
||||
timer_outer_glib.gs = g_timeout_source_new(1000);
|
||||
g_source_set_callback(timer_outer_glib.gs, timer_cb_glib, NULL, NULL);
|
||||
timer_outer_glib.tag = g_source_attach(timer_outer_glib.gs,
|
||||
g_main_loop_get_context(loop_glib));
|
||||
|
||||
g_main_loop_run(loop_glib);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_glib(void)
|
||||
{
|
||||
g_main_loop_quit(loop_glib);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_glib(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
lws_gs_destroy(sighandler_glib);
|
||||
lws_gs_destroy(timer_outer_glib);
|
||||
|
||||
g_main_loop_unref(loop_glib);
|
||||
loop_glib = NULL;
|
||||
}
|
||||
|
||||
const struct ops ops_glib = {
|
||||
foreign_event_loop_init_and_run_glib,
|
||||
foreign_event_loop_stop_glib,
|
||||
foreign_event_loop_cleanup_glib
|
||||
};
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* lws-minimal-http-server-eventlib-foreign
|
||||
*
|
||||
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* The libev specific code
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include <ev.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static struct ev_loop *loop_ev;
|
||||
static struct ev_timer timer_outer_ev;
|
||||
static struct ev_signal sighandler_ev;
|
||||
|
||||
static void
|
||||
timer_cb_ev(struct ev_loop *loop, struct ev_timer *watcher, int revents)
|
||||
{
|
||||
foreign_timer_service(loop_ev);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_ev(struct ev_loop *loop, struct ev_signal *watcher, int revents)
|
||||
{
|
||||
signal_cb(watcher->signum);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_libev(void)
|
||||
{
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
loop_ev = ev_loop_new(0);
|
||||
|
||||
ev_signal_init(&sighandler_ev, signal_cb_ev, SIGINT);
|
||||
ev_signal_start(loop_ev, &sighandler_ev);
|
||||
|
||||
ev_timer_init(&timer_outer_ev, timer_cb_ev, 0, 1);
|
||||
ev_timer_start(loop_ev, &timer_outer_ev);
|
||||
|
||||
ev_run(loop_ev, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_libev(void)
|
||||
{
|
||||
ev_break(loop_ev, EVBREAK_ALL);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_libev(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
ev_timer_stop(loop_ev, &timer_outer_ev);
|
||||
ev_signal_stop(loop_ev, &sighandler_ev);
|
||||
|
||||
ev_run(loop_ev, 0);
|
||||
ev_loop_destroy(loop_ev);
|
||||
}
|
||||
|
||||
const struct ops ops_libev = {
|
||||
foreign_event_loop_init_and_run_libev,
|
||||
foreign_event_loop_stop_libev,
|
||||
foreign_event_loop_cleanup_libev
|
||||
};
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* lws-minimal-http-server-eventlib-foreign
|
||||
*
|
||||
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* The libevent specific code
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include <event2/event.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static struct event_base *loop_event;
|
||||
static struct event *timer_outer_event;
|
||||
static struct event *sighandler_event;
|
||||
|
||||
static void
|
||||
timer_cb_event(int fd, short event, void *arg)
|
||||
{
|
||||
foreign_timer_service(loop_event);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_event(int fd, short event, void *arg)
|
||||
{
|
||||
signal_cb((int)(lws_intptr_t)arg);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_libevent(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
loop_event = event_base_new();
|
||||
|
||||
sighandler_event = evsignal_new(loop_event, SIGINT, signal_cb_event,
|
||||
(void*)SIGINT);
|
||||
|
||||
timer_outer_event = event_new(loop_event, -1, EV_PERSIST,
|
||||
timer_cb_event, NULL);
|
||||
//evtimer_new(loop_event, timer_cb_event, NULL);
|
||||
evtimer_add(timer_outer_event, &tv);
|
||||
|
||||
event_base_loop(loop_event, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_libevent(void)
|
||||
{
|
||||
event_base_loopexit(loop_event, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_libevent(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
evtimer_del(timer_outer_event);
|
||||
event_free(timer_outer_event);
|
||||
evsignal_del(sighandler_event);
|
||||
event_free(sighandler_event);
|
||||
|
||||
event_base_loop(loop_event, 0);
|
||||
event_base_free(loop_event);
|
||||
}
|
||||
|
||||
const struct ops ops_libevent = {
|
||||
foreign_event_loop_init_and_run_libevent,
|
||||
foreign_event_loop_stop_libevent,
|
||||
foreign_event_loop_cleanup_libevent
|
||||
};
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* lws-minimal-http-server-eventlib-foreign
|
||||
*
|
||||
* Written in 2010-2020 by Andy Green <andy@warmcat.com>
|
||||
*
|
||||
* This file is made available under the Creative Commons CC0 1.0
|
||||
* Universal Public Domain Dedication.
|
||||
*
|
||||
* The libuv specific code
|
||||
*/
|
||||
|
||||
#include <libwebsockets.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <uv.h>
|
||||
#ifdef LWS_HAVE_UV_VERSION_H
|
||||
#include <uv-version.h>
|
||||
#endif
|
||||
#ifdef LWS_HAVE_NEW_UV_VERSION_H
|
||||
#include <uv/version.h>
|
||||
#endif
|
||||
|
||||
#include "private.h"
|
||||
|
||||
static uv_loop_t loop_uv;
|
||||
static uv_timer_t timer_outer_uv;
|
||||
static uv_signal_t sighandler_uv;
|
||||
|
||||
static void
|
||||
timer_cb_uv(uv_timer_t *t)
|
||||
{
|
||||
foreign_timer_service(&loop_uv);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_uv(uv_signal_t *watcher, int signum)
|
||||
{
|
||||
signal_cb(signum);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_libuv(void)
|
||||
{
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
#if (UV_VERSION_MAJOR > 0) // Travis...
|
||||
uv_loop_init(&loop_uv);
|
||||
#endif
|
||||
uv_signal_init(&loop_uv, &sighandler_uv);
|
||||
uv_signal_start(&sighandler_uv, signal_cb_uv, SIGINT);
|
||||
|
||||
uv_timer_init(&loop_uv, &timer_outer_uv);
|
||||
#if (UV_VERSION_MAJOR > 0) // Travis...
|
||||
uv_timer_start(&timer_outer_uv, timer_cb_uv, 0, 1000);
|
||||
#else
|
||||
(void)timer_cb_uv;
|
||||
#endif
|
||||
|
||||
uv_run(&loop_uv, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_libuv(void)
|
||||
{
|
||||
uv_stop(&loop_uv);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_libuv(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
uv_timer_stop(&timer_outer_uv);
|
||||
uv_close((uv_handle_t*)&timer_outer_uv, NULL);
|
||||
uv_signal_stop(&sighandler_uv);
|
||||
uv_close((uv_handle_t *)&sighandler_uv, NULL);
|
||||
|
||||
uv_run(&loop_uv, UV_RUN_DEFAULT);
|
||||
#if (UV_VERSION_MAJOR > 0) // Travis...
|
||||
uv_loop_close(&loop_uv);
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct ops ops_libuv = {
|
||||
foreign_event_loop_init_and_run_libuv,
|
||||
foreign_event_loop_stop_libuv,
|
||||
foreign_event_loop_cleanup_libuv
|
||||
};
|
||||
|
|
@ -23,11 +23,12 @@
|
|||
#include <string.h>
|
||||
#include <signal.h>
|
||||
|
||||
struct lws_context_creation_info info;
|
||||
static struct lws_context *context;
|
||||
static int lifetime = 5, reported;
|
||||
#include "private.h"
|
||||
|
||||
static void foreign_timer_service(void *foreign_loop);
|
||||
static struct lws_context_creation_info info;
|
||||
static const struct ops *ops = NULL;
|
||||
struct lws_context *context;
|
||||
int lifetime = 5, reported;
|
||||
|
||||
enum {
|
||||
TEST_STATE_CREATE_LWS_CONTEXT,
|
||||
|
@ -57,7 +58,7 @@ static const struct lws_http_mount mount = {
|
|||
/* .basic_auth_login_file */ NULL,
|
||||
};
|
||||
|
||||
static void
|
||||
void
|
||||
signal_cb(int signum)
|
||||
{
|
||||
lwsl_notice("Signal %d caught, exiting...\n", signum);
|
||||
|
@ -73,268 +74,9 @@ signal_cb(int signum)
|
|||
lws_context_destroy(context);
|
||||
}
|
||||
|
||||
/*
|
||||
* The event-loop specific foreign loop code, one set for each event loop lib
|
||||
*
|
||||
* Only the code in this section is specific to the event library used.
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
|
||||
static uv_loop_t loop_uv;
|
||||
static uv_timer_t timer_outer_uv;
|
||||
static uv_signal_t sighandler_uv;
|
||||
|
||||
static void
|
||||
timer_cb_uv(uv_timer_t *t)
|
||||
{
|
||||
foreign_timer_service(&loop_uv);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_uv(uv_signal_t *watcher, int signum)
|
||||
{
|
||||
signal_cb(signum);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_libuv(void)
|
||||
{
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
#if (UV_VERSION_MAJOR > 0) // Travis...
|
||||
uv_loop_init(&loop_uv);
|
||||
#endif
|
||||
uv_signal_init(&loop_uv, &sighandler_uv);
|
||||
uv_signal_start(&sighandler_uv, signal_cb_uv, SIGINT);
|
||||
|
||||
uv_timer_init(&loop_uv, &timer_outer_uv);
|
||||
#if (UV_VERSION_MAJOR > 0) // Travis...
|
||||
uv_timer_start(&timer_outer_uv, timer_cb_uv, 0, 1000);
|
||||
#else
|
||||
(void)timer_cb_uv;
|
||||
#endif
|
||||
|
||||
uv_run(&loop_uv, UV_RUN_DEFAULT);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_libuv(void)
|
||||
{
|
||||
uv_stop(&loop_uv);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_libuv(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
uv_timer_stop(&timer_outer_uv);
|
||||
uv_close((uv_handle_t*)&timer_outer_uv, NULL);
|
||||
uv_signal_stop(&sighandler_uv);
|
||||
uv_close((uv_handle_t *)&sighandler_uv, NULL);
|
||||
|
||||
uv_run(&loop_uv, UV_RUN_DEFAULT);
|
||||
#if (UV_VERSION_MAJOR > 0) // Travis...
|
||||
uv_loop_close(&loop_uv);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
|
||||
static struct event_base *loop_event;
|
||||
static struct event *timer_outer_event;
|
||||
static struct event *sighandler_event;
|
||||
|
||||
static void
|
||||
timer_cb_event(int fd, short event, void *arg)
|
||||
{
|
||||
foreign_timer_service(loop_event);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_event(int fd, short event, void *arg)
|
||||
{
|
||||
signal_cb((int)(lws_intptr_t)arg);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_libevent(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
tv.tv_sec = 1;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
loop_event = event_base_new();
|
||||
|
||||
sighandler_event = evsignal_new(loop_event, SIGINT, signal_cb_event,
|
||||
(void*)SIGINT);
|
||||
|
||||
timer_outer_event = event_new(loop_event, -1, EV_PERSIST,
|
||||
timer_cb_event, NULL);
|
||||
//evtimer_new(loop_event, timer_cb_event, NULL);
|
||||
evtimer_add(timer_outer_event, &tv);
|
||||
|
||||
event_base_loop(loop_event, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_libevent(void)
|
||||
{
|
||||
event_base_loopexit(loop_event, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_libevent(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
evtimer_del(timer_outer_event);
|
||||
event_free(timer_outer_event);
|
||||
evsignal_del(sighandler_event);
|
||||
event_free(sighandler_event);
|
||||
|
||||
event_base_loop(loop_event, 0);
|
||||
event_base_free(loop_event);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
|
||||
#include <glib-2.0/glib.h>
|
||||
#include <glib-unix.h>
|
||||
|
||||
typedef struct lws_glib_tag {
|
||||
GSource *gs;
|
||||
guint tag;
|
||||
} lws_glib_tag_t;
|
||||
|
||||
#define lws_gs_valid(t) (t.gs)
|
||||
#define lws_gs_destroy(t) if (lws_gs_valid(t)) { \
|
||||
g_source_remove(t.tag); \
|
||||
g_source_unref(t.gs); \
|
||||
t.gs = NULL; t.tag = 0; }
|
||||
|
||||
static GMainLoop *loop_glib;
|
||||
static lws_glib_tag_t timer_outer_glib, sighandler_glib;
|
||||
|
||||
static int
|
||||
timer_cb_glib(void *p)
|
||||
{
|
||||
foreign_timer_service(loop_glib);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_glib(void *p)
|
||||
{
|
||||
signal_cb(SIGINT);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_glib(void)
|
||||
{
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
loop_glib = g_main_loop_new(NULL, 0);
|
||||
|
||||
sighandler_glib.gs = g_unix_signal_source_new(SIGINT);
|
||||
g_source_set_callback(sighandler_glib.gs, G_SOURCE_FUNC(signal_cb_glib),
|
||||
NULL, NULL);
|
||||
sighandler_glib.tag = g_source_attach(sighandler_glib.gs,
|
||||
g_main_loop_get_context(loop_glib));
|
||||
|
||||
timer_outer_glib.gs = g_timeout_source_new(1000);
|
||||
g_source_set_callback(timer_outer_glib.gs, timer_cb_glib, NULL, NULL);
|
||||
timer_outer_glib.tag = g_source_attach(timer_outer_glib.gs,
|
||||
g_main_loop_get_context(loop_glib));
|
||||
|
||||
g_main_loop_run(loop_glib);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_glib(void)
|
||||
{
|
||||
g_main_loop_quit(loop_glib);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_glib(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
lws_gs_destroy(sighandler_glib);
|
||||
lws_gs_destroy(timer_outer_glib);
|
||||
|
||||
g_main_loop_unref(loop_glib);
|
||||
loop_glib = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
|
||||
static struct ev_loop *loop_ev;
|
||||
static struct ev_timer timer_outer_ev;
|
||||
static struct ev_signal sighandler_ev;
|
||||
|
||||
static void
|
||||
timer_cb_ev(struct ev_loop *loop, struct ev_timer *watcher, int revents)
|
||||
{
|
||||
foreign_timer_service(loop_ev);
|
||||
}
|
||||
|
||||
static void
|
||||
signal_cb_ev(struct ev_loop *loop, struct ev_signal *watcher, int revents)
|
||||
{
|
||||
signal_cb(watcher->signum);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_init_and_run_libev(void)
|
||||
{
|
||||
/* we create and start our "foreign loop" */
|
||||
|
||||
loop_ev = ev_loop_new(0);
|
||||
|
||||
ev_signal_init(&sighandler_ev, signal_cb_ev, SIGINT);
|
||||
ev_signal_start(loop_ev, &sighandler_ev);
|
||||
|
||||
ev_timer_init(&timer_outer_ev, timer_cb_ev, 0, 1);
|
||||
ev_timer_start(loop_ev, &timer_outer_ev);
|
||||
|
||||
ev_run(loop_ev, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_stop_libev(void)
|
||||
{
|
||||
ev_break(loop_ev, EVBREAK_ALL);
|
||||
}
|
||||
|
||||
static void
|
||||
foreign_event_loop_cleanup_libev(void)
|
||||
{
|
||||
/* cleanup the foreign loop assets */
|
||||
|
||||
ev_timer_stop(loop_ev, &timer_outer_ev);
|
||||
ev_signal_stop(loop_ev, &sighandler_ev);
|
||||
|
||||
ev_run(loop_ev, 0);
|
||||
ev_loop_destroy(loop_ev);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* this is called at 1Hz using a foreign loop timer */
|
||||
|
||||
static void
|
||||
void
|
||||
foreign_timer_service(void *foreign_loop)
|
||||
{
|
||||
void *foreign_loops[1];
|
||||
|
@ -377,22 +119,7 @@ foreign_timer_service(void *foreign_loop)
|
|||
|
||||
case TEST_STATE_EXIT:
|
||||
lwsl_user("Deciding to exit foreign loop too\n");
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBUV)
|
||||
foreign_event_loop_stop_libuv();
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBEVENT)
|
||||
foreign_event_loop_stop_libevent();
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBEV)
|
||||
foreign_event_loop_stop_libev();
|
||||
#endif
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
if (info.options & LWS_SERVER_OPTION_GLIB)
|
||||
foreign_event_loop_stop_glib();
|
||||
#endif
|
||||
ops->stop();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -437,23 +164,45 @@ int main(int argc, const char **argv)
|
|||
info.ssl_private_key_filepath = "localhost-100y.key";
|
||||
}
|
||||
|
||||
if (lws_cmdline_option(argc, argv, "--uv"))
|
||||
/*
|
||||
* We configure lws to use the chosen event loop, and select the
|
||||
* matching event-lib specific code for our demo operations
|
||||
*/
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
if (lws_cmdline_option(argc, argv, "--uv")) {
|
||||
info.options |= LWS_SERVER_OPTION_LIBUV;
|
||||
else
|
||||
if (lws_cmdline_option(argc, argv, "--event"))
|
||||
ops = &ops_libuv;
|
||||
lwsl_notice("%s: using libuv event loop\n", __func__);
|
||||
} else
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
if (lws_cmdline_option(argc, argv, "--event")) {
|
||||
info.options |= LWS_SERVER_OPTION_LIBEVENT;
|
||||
else
|
||||
if (lws_cmdline_option(argc, argv, "--ev"))
|
||||
ops = &ops_libevent;
|
||||
lwsl_notice("%s: using libevent loop\n", __func__);
|
||||
} else
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
if (lws_cmdline_option(argc, argv, "--ev")) {
|
||||
info.options |= LWS_SERVER_OPTION_LIBEV;
|
||||
else
|
||||
if (lws_cmdline_option(argc, argv, "--glib"))
|
||||
ops = &ops_libev;
|
||||
lwsl_notice("%s: using libev loop\n", __func__);
|
||||
} else
|
||||
#endif
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
if (lws_cmdline_option(argc, argv, "--glib")) {
|
||||
info.options |= LWS_SERVER_OPTION_GLIB;
|
||||
else {
|
||||
ops = &ops_glib;
|
||||
lwsl_notice("%s: using glib loop\n", __func__);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
lwsl_err("This app only makes sense when used\n");
|
||||
lwsl_err(" with a foreign loop, --uv, --event, --glib, or --ev\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
lwsl_user(" This app creates a foreign event loop with a timer +\n");
|
||||
lwsl_user(" signalhandler, and performs a test in three phases:\n");
|
||||
|
@ -469,43 +218,13 @@ int main(int argc, const char **argv)
|
|||
|
||||
/* foreign loop specific startup and run */
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBUV)
|
||||
foreign_event_loop_init_and_run_libuv();
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBEVENT)
|
||||
foreign_event_loop_init_and_run_libevent();
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBEV)
|
||||
foreign_event_loop_init_and_run_libev();
|
||||
#endif
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
if (info.options & LWS_SERVER_OPTION_GLIB)
|
||||
foreign_event_loop_init_and_run_glib();
|
||||
#endif
|
||||
ops->init_and_run();
|
||||
|
||||
lws_context_destroy(context);
|
||||
|
||||
/* foreign loop specific cleanup and exit */
|
||||
|
||||
#if defined(LWS_WITH_LIBUV)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBUV)
|
||||
foreign_event_loop_cleanup_libuv();
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEVENT)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBEVENT)
|
||||
foreign_event_loop_cleanup_libevent();
|
||||
#endif
|
||||
#if defined(LWS_WITH_LIBEV)
|
||||
if (info.options & LWS_SERVER_OPTION_LIBEV)
|
||||
foreign_event_loop_cleanup_libev();
|
||||
#endif
|
||||
#if defined(LWS_WITH_GLIB)
|
||||
if (info.options & LWS_SERVER_OPTION_GLIB)
|
||||
foreign_event_loop_cleanup_glib();
|
||||
#endif
|
||||
ops->cleanup();
|
||||
|
||||
lwsl_user("%s: exiting...\n", __func__);
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
|
||||
struct ops {
|
||||
void (*init_and_run)(void);
|
||||
void (*stop)(void);
|
||||
void (*cleanup)(void);
|
||||
};
|
||||
|
||||
extern struct lws_context *context;
|
||||
extern int lifetime, reported;
|
||||
|
||||
void foreign_timer_service(void *foreign_loop);
|
||||
void signal_cb(int signum);
|
||||
|
||||
extern const struct ops ops_libuv, ops_libevent, ops_glib, ops_libev;
|
|
@ -396,7 +396,7 @@ myss_state(void *userobj, void *sh, lws_ss_constate_t state,
|
|||
/* provide a hint about the payload size */
|
||||
m->pos = 0;
|
||||
m->len = strlen(postbody);
|
||||
lws_ss_request_tx_len(m->ss, strlen(postbody));
|
||||
lws_ss_request_tx_len(m->ss, (unsigned long)strlen(postbody));
|
||||
break;
|
||||
case LWSSSCS_CONNECTED:
|
||||
lws_ss_request_tx(m->ss);
|
||||
|
|
|
@ -199,8 +199,9 @@ myss_srv_state(void *userobj, void *sh, lws_ss_constate_t state,
|
|||
/*
|
||||
* ...it's going to be whatever size it is (and request tx)
|
||||
*/
|
||||
lws_ss_request_tx_len(m->ss, multipart ? strlen(multipart_html) :
|
||||
strlen(html));
|
||||
lws_ss_request_tx_len(m->ss, (unsigned long)
|
||||
(multipart ? strlen(multipart_html) :
|
||||
strlen(html)));
|
||||
break;
|
||||
|
||||
case LWSSSCS_SERVER_UPGRADE:
|
||||
|
|
|
@ -72,6 +72,7 @@
|
|||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
struct per_vhost_data__raw_test {
|
||||
struct lws_context *context;
|
||||
|
|
Loading…
Add table
Reference in a new issue