{"schema":"libjg2-1",
"vpath":"/git/",
"avatar":"/git/avatar/",
"alang":"",
"gen_ut":1745821944,
"reponame":"libwebsockets",
"desc":"libwebsockets lightweight C networking library",
"owner": { "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },"url":"https://libwebsockets.org/repo/libwebsockets",
"f":3,
"items": [
{"schema":"libjg2-1",
"cid":"cbb4a9e97b06f396e8e599ecfe176a0b",
"commit": {"type":"commit",
"time": 1552176122,
"time_ofs": 480,
"oid_tree": { "oid": "7ce3608041e251ad57efbe6b2ec9522dd7d6e2f4", "alias": []},
"oid":{ "oid": "a57d13cb1ba874e4808c70eaea89721499af3942", "alias": []},
"msg": "smp: adopt: deal with load balancing init window",
"sig_commit": { "git_time": { "time": 1552176122, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" },
"sig_author": { "git_time": { "time": 1550871690, "offset": 480 }, "name": "Andy Green", "email": "andy@warmcat.com", "md5": "c50933ca2aa61e0fe2c43d46bb6b59cb" }},
"body": "smp: adopt: deal with load balancing init window\n\nWith SMP as soon as we add the new sockfd to the fds table, in the\ncase we load-balanced the fd on to a different pt, service on it\nbecomes live immediately and concurrently. This can lead to the\nunexpected situation that while we think we're still initing the\nnew wsi from our thread, it can have lived out its whole life\nconcurrently from another service thread.\n\nAdd a volatile flag to inform the owning pt that if it wants to\nservice the wsi during this init window, it must wait and retry\nnext time around the event loop."
,
"diff": "diff --git a/lib/core-net/adopt.c b/lib/core-net/adopt.c\nindex 03bad83..a9d2d6d 100644\n--- a/lib/core-net/adopt.c\n+++ b/lib/core-net/adopt.c\n@@ -132,6 +132,12 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,\n \t}\n #endif\n \n+\t/*\n+\t * Notice that in SMP case, the wsi may being being created on an\n+\t * entirely different pt / tsi for load balancing. In that case as\n+\t * we initialize it, it may become \u0022live\u0022 concurrently unexpectedly...\n+\t */\n+\n \tn \u003d -1;\n \tif (parent)\n \t\tn \u003d parent-\u003etsi;\n@@ -194,6 +200,15 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,\n \t\tif (context-\u003eevent_loop_ops-\u003eaccept(new_wsi))\n \t\t\tgoto fail;\n \n+#if LWS_MAX_SMP \u003e 1\n+\t/*\n+\t * Caution: after this point the wsi is live on its service thread\n+\t * which may be concurrent to this. We mark the wsi as still undergoing\n+\t * init in another pt so the assigned pt leaves it alone.\n+\t */\n+\tnew_wsi-\u003eundergoing_init_from_other_pt \u003d 1;\n+#endif\n+\n \tif (!(type \u0026 LWS_ADOPT_ALLOW_SSL)) {\n \t\tlws_pt_lock(pt, __func__);\n \t\tif (__insert_wsi_socket_into_fds(context, new_wsi)) {\n@@ -224,6 +239,12 @@ lws_adopt_descriptor_vhost(struct lws_vhost *vh, lws_adoption_type type,\n \tlws_role_call_adoption_bind(new_wsi, type | _LWS_ADOPT_FINISH,\n \t\t\t\t vh_prot_name);\n \n+#if LWS_MAX_SMP \u003e 1\n+\t/* its actual pt can service it now */\n+\n+\tnew_wsi-\u003eundergoing_init_from_other_pt \u003d 0;\n+#endif\n+\n \tlws_cancel_service_pt(new_wsi);\n \n \treturn new_wsi;\ndiff --git a/lib/core-net/private.h b/lib/core-net/private.h\nindex 3d4b4c4..6048e3b 100644\n--- a/lib/core-net/private.h\n+++ b/lib/core-net/private.h\n@@ -623,6 +623,10 @@ struct lws {\n \t/* volatile to make sure code is aware other thread can change */\n \tvolatile char handling_pollout;\n \tvolatile char leave_pollout_active;\n+#if LWS_MAX_SMP \u003e 1\n+\tvolatile char undergoing_init_from_other_pt;\n+#endif\n+\n };\n \n #define lws_is_flowcontrolled(w) (!!(wsi-\u003erxflow_bitmap))\ndiff --git a/lib/core-net/service.c b/lib/core-net/service.c\nindex f4014a7..4811415 100644\n--- a/lib/core-net/service.c\n+++ b/lib/core-net/service.c\n@@ -960,6 +960,15 @@ lws_service_fd_tsi(struct lws_context *context, struct lws_pollfd *pollfd,\n \t\t/* not lws connection ... leave revents alone and return */\n \t\treturn 0;\n \n+#if LWS_MAX_SMP \u003e 1\n+\tif (wsi-\u003eundergoing_init_from_other_pt)\n+\t\t/*\n+\t\t * Temporary situation that other service thread is initializing\n+\t\t * this wsi right now for use on our service thread.\n+\t\t */\n+\t\treturn 0;\n+#endif\n+\n \t/*\n \t * so that caller can tell we handled, past here we need to\n \t * zero down pollfd-\u003erevents after handling\ndiff --git a/lib/roles/listen/ops-listen.c b/lib/roles/listen/ops-listen.c\nindex a1661ca..6624345 100644\n--- a/lib/roles/listen/ops-listen.c\n+++ b/lib/roles/listen/ops-listen.c\n@@ -136,7 +136,7 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,\n \t\t\t/* already closed cleanly as necessary */\n \t\t\treturn LWS_HPI_RET_WSI_ALREADY_DIED;\n \t\t}\n-\n+/*\n \t\tif (lws_server_socket_service_ssl(cwsi, accept_fd)) {\n \t\t\tlws_close_free_wsi(cwsi, LWS_CLOSE_STATUS_NOSTATUS,\n \t\t\t\t\t \u0022listen svc fail\u0022);\n@@ -145,6 +145,7 @@ rops_handle_POLLIN_listen(struct lws_context_per_thread *pt, struct lws *wsi,\n \n \t\tlwsl_info(\u0022%s: new wsi %p: wsistate 0x%x, role_ops %s\u005cn\u0022,\n \t\t\t __func__, cwsi, cwsi-\u003ewsistate, cwsi-\u003erole_ops-\u003ename);\n+*/\n \n \t} while (pt-\u003efds_count \u003c context-\u003efd_limit_per_thread - 1 \u0026\u0026\n \t\t wsi-\u003eposition_in_fds_table !\u003d LWS_NO_FDS_POS \u0026\u0026\n","s":{"c":1745821944,"u": 3878}}
],"g": 5021,"chitpc": 0,"ehitpc": 0,"indexed":0
,
"ab": 0, "si": 0, "db":0, "di":0, "sat":0, "lfc": "0000"}