Project homepage Mailing List  API Docs  Github Mirror 
{"schema":"libjg2-1", "vpath":"/git/", "avatar":"/git/avatar/", "alang":"en-US,en;q\u003d0.5", "gen_ut":1600827066, "reponame":"libwebsockets", "desc":"libwebsockets lightweight C networking library", "owner": { "name": "Andy Green", "email": "", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"", "f":3, "items": [ { "schema":"libjg2-1", "oid":{ "oid": "9bff4d84eddb7f793c04947c259a948523641920", "alias": [ "refs/heads/master"]},"tree": [ { "name": "glib","mode": "16384", "size":0}, { "name": "libev","mode": "16384", "size":0}, { "name": "libevent","mode": "16384", "size":0}, { "name": "libuv","mode": "16384", "size":0}, { "name": "poll","mode": "16384", "size":0}, { "name": "CMakeLists.txt","mode": "33188", "size":3353}, { "name": "","mode": "33188", "size":6190}, { "name": "private-lib-event-libs.h","mode": "33188", "size":2784}],"s":{"c":1600768960,"u": 334}} ,{"schema":"libjg2-1", "cid":"288237086aa5f965212a3ca8c33d28d8", "oid":{ "oid": "9bff4d84eddb7f793c04947c259a948523641920", "alias": [ "refs/heads/master"]},"blobname": "lib/event-libs/", "blob": "## Information for new event lib implementers\n\n### Introduction\n\nBy default lws has built-in support for POSIX poll() as the event loop on unix,\nand native WSA on windows.\n\nTo get access to epoll() or other platform specific better poll waits, or to\nintegrate with existing applications already using a specific event loop, it can\nbe desirable for lws to use another external event library, like libuv, glib,\nlibevent or libev.\n\nLws supports wholesale replacement of its wait selectable at runtime, either by\nbuilding support for one or more event lib into the libwebsockets library, or by\nbuilding runtime-loadable plugins. CMake symbol `LWS_WITH_EVLIB_PLUGINS`\ndecides if the support is built as plugins or included into the lws lib.\n\nDue to their history libevent and libev have conflicting defines in the same\nnamespace and cannot be built together if included into the lib, however when\nbuilt as plugins they are built separately without problems.\nSee ./READMEs/ for more details.\n\nDespite it may be more work, lws event lib implementations must support\n\u0022foreign\u0022 loops cleanly, that is integration with an already-existing loop and\nthe ability to destroy the lws_context without stopping or leaving the foreign\nloop in any different state than when lws found it. For most loops this is\nfairly simple, but with libuv async close, it required refcounting lws libuv\nhandles and deferring the actual destroy until they were all really closed.\n\n### Code placement\n\nThe code specific to the event library should live in `./lib/event-libs/**lib name**`\n\n### Allowing control over enabling event libs\n\nAll event libs should add a cmake define `LWS_WITH_**lib name**` and make its\nbuild dependent on it in CMakeLists.txt. Export the cmakedefine in\n`./cmake/` as well so user builds can understand if the event\nlib is available in the lws build it is trying to bind to.\n\nIf the event lib is disabled in cmake, nothing in its directory is built or\nreferenced.\n\n### Event loop ops struct\n\nThe event lib support is defined by `struct lws_event_loop_ops` in\n`lib/event-libs/private-lib-event-libs.h`,\neach event lib support instantiates one of these and fills in the appropriate\nops callbacks to perform its job. By convention that lives in\n`./lib/event-libs/**lib name**/**lib_name**.c`.\n\nThe ops struct must be public, not static, and must be named using `**lib_name**`,\neg\n\n```\n```\n\n### Private event lib declarations\n\nTruly private declarations for the event lib support that are only referenced by\nthat code can go in the event-libs directory as you like. The convention is\nthey should be in the event lib support directory in a file\n`private-lib-event-libs-**lib name**.h`.\n\n### Integration with lws\n\nThere are a couple of places to add refererences in ./lib/core/context.c, in a\ntable of context creation time server option flags mapped to the **lib_name**,\nused for plugin mode, like this...\n\n```\n#if defined(LWS_WITH_EVLIB_PLUGINS) \u0026\u0026 defined(LWS_WITH_EVENT_LIBS)\nstatic const struct lws_evlib_map {\n\tuint64_t\tflag;\n\tconst char\t*name;\n} map[] \u003d {\n\t{ LWS_SERVER_OPTION_LIBUV, \u0022evlib_uv\u0022 },\n\t{ LWS_SERVER_OPTION_LIBEVENT, \u0022evlib_event\u0022 },\n\t{ LWS_SERVER_OPTION_GLIB, \u0022evlib_glib\u0022 },\n\t{ LWS_SERVER_OPTION_LIBEV, \u0022evlib_ev\u0022 },\n};\n```\n\nand for backwards compatibility add a stanza to the built-in checks like this\n\n```\n#if defined(LWS_WITH_LIBUV)\n\tif (lws_check_opt(info-\u003eoptions, LWS_SERVER_OPTION_LIBUV)) {\n\t\textern const lws_plugin_evlib_t evlib_uv;\n\t\tplev \u003d \u0026evlib_uv;\n\t}\n#endif\n```\n\nBoth entries are the way the main libs hook up to the selected event lib ops\nstruct at runtime.\n\n### Integrating event lib assets to lws\n\nDeclare \u0022container structs\u0022 in your private....h for anything you need at\nwsi, pt, vhost and context levels, eg, the libuv event lib support need to\nadd its own assets in the perthread struct, it declares in its private....h\n\n```\nstruct lws_pt_eventlibs_libuv {\n\tuv_loop_t *io_loop;\n\tstruct lws_context_per_thread *pt;\n\tuv_signal_t signals[8];\n\tuv_timer_t sultimer;\n\tuv_idle_t idle;\n\tstruct lws_signal_watcher_libuv w_sigint;\n};\n```\n\nthis is completely private and opaque, but in the ops struct there are provided\nfour entries to export the sizes of these event-lib specific objects\n\n```\n...\n\t/* evlib_size_ctx */\tsizeof(struct lws_context_eventlibs_libuv),\n\t/* evlib_size_pt */\tsizeof(struct lws_pt_eventlibs_libuv),\n\t/* evlib_size_vh */\t0,\n\t/* evlib_size_wsi */\tsizeof(struct lws_io_watcher_libuv),\n};\n```\n\nIf the particular event lib doesn't need to have a private footprint in an\nobject, it can just set the size it needs there to 0.\n\nWhen the context, pts, vhosts or wsis are created in lws, they over-allocate\nto also allow for the event lib object, and set a pointer in the lws object\nbeing created to point at the over-allocation. For example for the wsi\n\n```\n#if defined(LWS_WITH_EVENT_LIBS)\n\tvoid\t\t\t\t*evlib_wsi; /* overallocated */\n#endif\n```\n\nand similarly there are `evlib_pt` and so on for those objects, usable by the\nevent lib and opaque to everyone else. Once the event lib is selected at\nruntime, all of these objects are guaranteed to have the right size object at\n`wsi-\u003eevlib_wsi` initialized to zeroes.\n\n### Enabling event lib adoption\n\nYou need to add a `LWS_SERVER_OPTION...` flag as necessary in `./lib/libwebsockets.h`\n`enum lws_context_options`, and follow the existing code in `lws_create_context()`\nto convert the flag into binding your ops struct to the context.\n\n### Implementation of the event lib bindings\n\nStudy eg libuv implementation, using the available ops in the struct lws_event_loop_ops\nas a guide.\n\n### Destruction\n\nEnding the event loop is generally a bit tricky, because if the event loop is\ninternal to the lws context, you cannot destroy it while the event loop is\nrunning.\n\nDon't add special exports... we tried that, it's a huge mess. The same user\ncode should be able work with any of the event loops including poll.\n\nThe solution we found was hide the different processing necessary for the\ndifferent cases in `lws_destroy_context()`. To help with that there are event\nlib ops available that will be called at two different places in the context\ndestroy processing.\n\n","s":{"c":1600768960,"u": 319}} ],"g": 923,"chitpc": 0,"ehitpc": 0,"indexed":0 , "ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "7d0a"}