-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
epoll_fd set CLOEXEC? #2369
Comments
Can you please honor the issue template and fill it ? "ARM" in my head means a microcontroller but I guess in yours perhaps includes Linux/WIndows/MacOS/other |
oops, yeah this is on Linux 5.15. |
We don't set Lines 5742 to 5771 in d5b5cec
What you post is executed only once when calling Lines 3806 to 3812 in d5b5cec
and then for EPOLL, we do this: Lines 5880 to 5891 in d5b5cec
You know, the issue template exists for a reason, to save yours and our time, so please tell us exactly what are you doing. WRT
my best guess would be:
If you absolutely need multi-threading, take the time to go through the user guide (linked above) and tutorials, there is one that shows you how to do multi-threading. |
sorry, your reply does not make much sense to me, let me attempt to clarify. given the following test program, which is taken from the #include <err.h>
#include "mongoose.h"
static void
fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{
if (ev == MG_EV_HTTP_MSG) {
struct mg_http_message *hm = ev_data;
if (mg_http_match_uri(hm, "/api/hello")) {
mg_http_reply(c, 200, "", "{%m:%d}\n", MG_ESC("status"), 1);
}
else {
struct mg_http_serve_opts opts = { .root_dir = "." };
mg_http_serve_dir(c, hm, &opts);
}
}
}
int
main(int argc, char *argv[])
{
struct mg_mgr mgr;
mg_mgr_init(&mgr);
mg_http_listen(&mgr, "http://0.0.0.0:8000", fn, &mgr);
while (1) {
mg_mgr_poll(&mgr, 1000);
if (execl(argv[0], argv[0], NULL) == -1)
err(1, "execl(%s)", argv[0]);
}
mg_mgr_free(&mgr);
return 0;
} i have made a simple modification: every time the compile and run via:
Now the easiest way to see the problem is to introspect the amount of open file descriptors, one way is via /proc (with
if i then instrument the mongoose codebase with the following diff:
you can see the output of
you can clearly see the fd 3 does not have no multithreading here. |
I fail to grasp why you might want to do something like that. I don't see a usage model like that in any of our examples nor the user guide, I wouldn't call yours "a simple modification". |
Thanks @scaprile @kylemilz , the change looks reasonable. We missed the fact that the epoll descriptors are also inherited. By the way, we also don't set CLOSEXEC on the static UI files opened by the HTTP server - a standard Quick question. Are your child processes not getting closed? |
This has broken the Windows version. Dr. Watson kicks in. I fixed it by: --- a/src/fs_posix.c 2023-09-08 07:15:48
+++ b/src/fs_posix.c 2023-09-09 09:06:12
@@ -166,13 +166,14 @@
}
static void *p_open(const char *path, int flags) {
- const char *mode = flags == MG_FS_READ ? "rbe" : "a+be"; // e for CLOEXEC
#if MG_ARCH == MG_ARCH_WIN32
+ const char *mode = flags == MG_FS_READ ? "rb" : "a+b";
wchar_t b1[MG_PATH_MAX], b2[10];
MultiByteToWideChar(CP_UTF8, 0, path, -1, b1, sizeof(b1) / sizeof(b1[0]));
MultiByteToWideChar(CP_UTF8, 0, mode, -1, b2, sizeof(b2) / sizeof(b2[0]));
return (void *) _wfopen(b1, b2);
#else
+ const char *mode = flags == MG_FS_READ ? "rbe" : "a+be"; // e for CLOEXEC
return (void *) fopen(path, mode);
#endif
} |
Oops. Our CI did not complain about windows tests. @gvanem could you elaborate a bit more what exactly do you observe? An antivirus pops up? |
Not here.
No. My JIT-debugger (WinDbg) jumps in with this call-stack when running e.g.
Plain and simply an illegal |
We only test examples for build, and that one is not in the main list so I'm not sure we actually test it. Plus, we are not building with every combination, we either build with POLL or EPOLL. However, we should catch that in the unit tests. Lines 353 to 357 in bd59185
So Linux defaults to EPOLL and MacOS defaults to poll() MG_ARCH_WIN32 has no macros so it defaults to select() |
Our use case is quite valid. What we have is a configuration update coming from http, ie we have a user dashboard where they can set some values, then these are sent to mongoose. Upon validation of the configuration, it gets written to a database and then we use What happened is we have tests that write many permutations of configuration, and we noticed after a while the tests would fail. The tests failed because the configuration database could not be opened, because the process had too many open file descriptors. That lead us to discover this leak.
Unix process management is kind of weird. IIRC all other resources except file descriptors get free'd across an |
We are not doing a
I believe your analysis above is correct, but we do not have that situation here. |
Thanks, presuming this fix is in 7.12 i'll give it a try when it's released. |
Yes, it will be included in 7.12 |
Hi,
We are using Mongoose 7.11 on ARM using GCC, and epoll.
We have an application that does many
exec(3)
. I noticed that after a while, the program runs out of file descriptors. I have tracked the descriptor leak down to the mongoosemgr->epoll_fd
. It looks like it's being created without theEPOLL_CLOEXEC
flag.I don't think this is desired behavior, and indeed some of the other file descriptors created by mongoose are setting CLOEXEC, notably in
mg_set_non_blocking_mode()
. What do you think of this diff?The text was updated successfully, but these errors were encountered: