lwsws conf and plugins convert to libuv apis
After discussion here https://libwebsockets.org/pipermail/libwebsockets/2016-April/002268.html scandir usage in - lwsws conf.c - lws plugin support and - lws plugin apis for dl are converted to us libuv apis so they can work cross-platform easily. lws itself remains not requiring libuv, although it's an option. - LWS_WITH_LWSWS - LWS_WITH_PLUGINS now force LWS_WITH_LIBUV if selected... both of these are new features only in master atm and both are off by default in CMake. There's a complication libuv can be too old to offer the necessary apis, this is the case in Travis Trusty instance. In that case, UV_VERSION_MAJOR ==0, then the unix-only plugin implementation is used instead. Signed-off-by: Andy Green <andy@warmcat.com>
This commit is contained in:
parent
e01a551a17
commit
0a183545b2
6 changed files with 198 additions and 4 deletions
|
@ -100,6 +100,11 @@ if (LWS_WITH_LWSWS)
|
|||
set(LWS_WITH_LIBUV 1)
|
||||
endif()
|
||||
|
||||
if (LWS_WITH_PLUGINS AND NOT LWS_WITH_LIBUV)
|
||||
message(STATUS "LWS_WITH_PLUGINS --> Enabling LWS_WITH_LIBUV")
|
||||
set(LWS_WITH_LIBUV 1)
|
||||
endif()
|
||||
|
||||
if (DEFINED YOTTA_WEBSOCKETS_VERSION_STRING)
|
||||
|
||||
set(LWS_WITH_SHARED OFF)
|
||||
|
@ -118,9 +123,6 @@ endif()
|
|||
if (WIN32)
|
||||
# this implies no pthreads in the lib
|
||||
set(LWS_MAX_SMP 1)
|
||||
|
||||
# plugin stuff not implemented in win32 plat
|
||||
set (LWS_WITH_PLUGINS OFF)
|
||||
endif()
|
||||
|
||||
|
||||
|
|
131
lib/libuv.c
131
lib/libuv.c
|
@ -408,3 +408,134 @@ lws_libuv_closehandle(struct lws *wsi)
|
|||
if (context->requested_kill && context->count_wsi_allocated == 0)
|
||||
lws_libuv_kill(context);
|
||||
}
|
||||
|
||||
#if defined(LWS_WITH_PLUGINS) && (UV_VERSION_MAJOR > 0)
|
||||
|
||||
LWS_VISIBLE int
|
||||
lws_plat_plugins_init(struct lws_context * context, const char *d)
|
||||
{
|
||||
struct lws_plugin_capability lcaps;
|
||||
struct lws_plugin *plugin;
|
||||
lws_plugin_init_func initfunc;
|
||||
int m, ret = 0;
|
||||
void *v;
|
||||
uv_dirent_t dent;
|
||||
uv_fs_t req;
|
||||
char path[256];
|
||||
uv_loop_t loop;
|
||||
uv_lib_t lib;
|
||||
|
||||
lib.errmsg = NULL;
|
||||
lib.handle = NULL;
|
||||
|
||||
uv_loop_init(&loop);
|
||||
|
||||
if (!uv_fs_scandir(&loop, &req, d, 0, NULL)) {
|
||||
lwsl_err("Scandir on %s failed\n", d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lwsl_notice(" Plugins:\n");
|
||||
|
||||
while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
|
||||
if (strlen(dent.name) < 7)
|
||||
continue;
|
||||
|
||||
lwsl_notice(" %s\n", dent.name);
|
||||
|
||||
snprintf(path, sizeof(path) - 1, "%s/%s", d, dent.name);
|
||||
if (uv_dlopen(path, &lib)) {
|
||||
uv_dlerror(&lib);
|
||||
lwsl_err("Error loading DSO: %s\n", lib.errmsg);
|
||||
goto bail;
|
||||
}
|
||||
/* we could open it, can we get his init function? */
|
||||
m = snprintf(path, sizeof(path) - 1, "init_%s",
|
||||
dent.name + 3 /* snip lib... */);
|
||||
path[m - 3] = '\0'; /* snip the .so */
|
||||
if (uv_dlsym(&lib, path, &v)) {
|
||||
uv_dlerror(&lib);
|
||||
lwsl_err("Failed to get init on %s: %s",
|
||||
dent.name, lib.errmsg);
|
||||
goto bail;
|
||||
}
|
||||
initfunc = (lws_plugin_init_func)v;
|
||||
lcaps.api_magic = LWS_PLUGIN_API_MAGIC;
|
||||
m = initfunc(context, &lcaps);
|
||||
if (m) {
|
||||
lwsl_err("Initializing %s failed %d\n", dent.name, m);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
plugin = lws_malloc(sizeof(*plugin));
|
||||
if (!plugin) {
|
||||
lwsl_err("OOM\n");
|
||||
goto bail;
|
||||
}
|
||||
plugin->list = context->plugin_list;
|
||||
context->plugin_list = plugin;
|
||||
strncpy(plugin->name, dent.name, sizeof(plugin->name) - 1);
|
||||
plugin->name[sizeof(plugin->name) - 1] = '\0';
|
||||
plugin->lib = lib;
|
||||
plugin->caps = lcaps;
|
||||
context->plugin_protocol_count += lcaps.count_protocols;
|
||||
context->plugin_extension_count += lcaps.count_extensions;
|
||||
|
||||
continue;
|
||||
|
||||
skip:
|
||||
uv_dlclose(&lib);
|
||||
}
|
||||
|
||||
bail:
|
||||
uv_fs_req_cleanup(&req);
|
||||
uv_loop_close(&loop);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
LWS_VISIBLE int
|
||||
lws_plat_plugins_destroy(struct lws_context * context)
|
||||
{
|
||||
struct lws_plugin *plugin = context->plugin_list, *p;
|
||||
lws_plugin_destroy_func func;
|
||||
char path[256];
|
||||
void *v;
|
||||
int m;
|
||||
|
||||
if (!plugin)
|
||||
return 0;
|
||||
|
||||
lwsl_notice("%s\n", __func__);
|
||||
|
||||
while (plugin) {
|
||||
p = plugin;
|
||||
m = snprintf(path, sizeof(path) - 1, "destroy_%s", plugin->name + 3);
|
||||
path[m - 3] = '\0';
|
||||
|
||||
if (uv_dlsym(&plugin->lib, path, &v)) {
|
||||
uv_dlerror(&plugin->lib);
|
||||
lwsl_err("Failed to get init on %s: %s",
|
||||
plugin->name, plugin->lib.errmsg);
|
||||
} else {
|
||||
func = (lws_plugin_destroy_func)v;
|
||||
m = func(context);
|
||||
if (m)
|
||||
lwsl_err("Destroying %s failed %d\n",
|
||||
plugin->name, m);
|
||||
}
|
||||
|
||||
uv_dlclose(&p->lib);
|
||||
plugin = p->list;
|
||||
p->list = NULL;
|
||||
free(p);
|
||||
}
|
||||
|
||||
context->plugin_list = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1305,6 +1305,11 @@ struct lws_extension {
|
|||
* This is part of the ABI, don't needlessly break compatibility */
|
||||
};
|
||||
|
||||
|
||||
#ifdef LWS_WITH_PLUGINS
|
||||
|
||||
/* PLUGINS implies LIBUV */
|
||||
|
||||
#define LWS_PLUGIN_API_MAGIC 180
|
||||
|
||||
struct lws_plugin_capability {
|
||||
|
@ -1320,11 +1325,17 @@ typedef int (*lws_plugin_init_func)(struct lws_context *,
|
|||
typedef int (*lws_plugin_destroy_func)(struct lws_context *);
|
||||
struct lws_plugin {
|
||||
struct lws_plugin *list;
|
||||
#if (UV_VERSION_MAJOR > 0)
|
||||
uv_lib_t lib;
|
||||
#else
|
||||
void *l;
|
||||
#endif
|
||||
char name[64];
|
||||
struct lws_plugin_capability caps;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The internal exts are part of the public abi
|
||||
* If we add more extensions, publish the callback here ------v
|
||||
|
|
|
@ -300,6 +300,12 @@ lws_plat_drop_app_privileges(struct lws_context_creation_info *info)
|
|||
|
||||
#ifdef LWS_WITH_PLUGINS
|
||||
|
||||
#if defined(LWS_USE_LIBUV) && UV_VERSION_MAJOR > 0
|
||||
|
||||
/* libuv.c implements these in a cross-platform way */
|
||||
|
||||
#else
|
||||
|
||||
static int filter(const struct dirent *ent)
|
||||
{
|
||||
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||
|
@ -322,7 +328,7 @@ lws_plat_plugins_init(struct lws_context * context, const char *d)
|
|||
|
||||
n = scandir(d, &namelist, filter, alphasort);
|
||||
if (n < 0) {
|
||||
lwsl_err("Scandir on %d failed\n", d);
|
||||
lwsl_err("Scandir on %s failed\n", d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -431,6 +437,7 @@ next:
|
|||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
|
|
|
@ -763,6 +763,12 @@ lws_close_free_wsi_final(struct lws *wsi);
|
|||
LWS_EXTERN void
|
||||
lws_libuv_closehandle(struct lws *wsi);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_plat_plugins_init(struct lws_context * context, const char *d);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN int
|
||||
lws_plat_plugins_destroy(struct lws_context * context);
|
||||
|
||||
enum {
|
||||
LWS_EV_READ = (1 << 0),
|
||||
LWS_EV_WRITE = (1 << 1),
|
||||
|
|
37
lwsws/conf.c
37
lwsws/conf.c
|
@ -345,6 +345,41 @@ lwsws_get_config(void *user, const char *f, const char * const *paths,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(LWS_USE_LIBUV) && UV_VERSION_MAJOR > 0
|
||||
|
||||
static int
|
||||
lwsws_get_config_d(void *user, const char *d, const char * const *paths,
|
||||
int count_paths, lejp_callback cb)
|
||||
{
|
||||
uv_dirent_t dent;
|
||||
uv_fs_t req;
|
||||
char path[256];
|
||||
int ret = 0;
|
||||
uv_loop_t loop;
|
||||
|
||||
uv_loop_init(&loop);
|
||||
|
||||
if (!uv_fs_scandir(&loop, &req, d, 0, NULL)) {
|
||||
lwsl_err("Scandir on %s failed\n", d);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
|
||||
snprintf(path, sizeof(path) - 1, "%s/%s", d, dent.name);
|
||||
ret = lwsws_get_config(user, path, paths, count_paths, cb);
|
||||
if (ret)
|
||||
goto bail;
|
||||
}
|
||||
|
||||
bail:
|
||||
uv_fs_req_cleanup(&req);
|
||||
uv_loop_close(&loop);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifndef _WIN32
|
||||
static int filter(const struct dirent *ent)
|
||||
{
|
||||
|
@ -390,6 +425,8 @@ bail:
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int
|
||||
lwsws_get_config_globals(struct lws_context_creation_info *info, const char *d,
|
||||
char **cs, int *len)
|
||||
|
|
Loading…
Add table
Reference in a new issue