[libmicrohttpd] running in main thread
Hi all, I searched in examples how to "block" in main thread on serving files but I only found examples with the sequence summarized here: MHD_start_daemon ... getc ... MHD_stop_daemon For my use I'm searching to just run the server without having to wait for a key or anything except ctrl+C or killed. It leads me to the question: "is there an easy way to serve in main thread?" (by easy I mean without rewriting an external polling loop as shown in example fileserver_example_external_select.c) Did I missed some option? Best regards José Bollo
Re: [libmicrohttpd] running in main thread
On Mon, 2 Dec 2019 15:04:52 +0100 José Bollo wrote: rereading comment of MHD_USE_INTERNAL_POLLING_THREAD my question looks stupid sorry for the noise > Hi all, > > I searched in examples how to "block" in main thread on serving files > but I only found examples with the sequence summarized here: > >MHD_start_daemon ... getc ... MHD_stop_daemon > > For my use I'm searching to just run the server without having to wait > for a key or anything except ctrl+C or killed. > > It leads me to the question: "is there an easy way to serve in main > thread?" (by easy I mean without rewriting an external polling loop as > shown in example fileserver_example_external_select.c) Did I missed > some option? > > Best regards > José Bollo >
Re: [libmicrohttpd] running in main thread
On Mon, 2 Dec 2019 15:08:39 +0100 José Bollo wrote: > On Mon, 2 Dec 2019 15:04:52 +0100 > José Bollo wrote: > > rereading comment of MHD_USE_INTERNAL_POLLING_THREAD my question looks > stupid No in fact the question is serious. There is no simple way to let run MHD on the main thread. It requires implementing an external poll/select loop. Can you provide an integrated main that serves and doesn't return until stopped? Best regards José Bollo > > sorry for the noise > > > Hi all, > > > > I searched in examples how to "block" in main thread on serving > > files but I only found examples with the sequence summarized here: > > > >MHD_start_daemon ... getc ... MHD_stop_daemon > > > > For my use I'm searching to just run the server without having to > > wait for a key or anything except ctrl+C or killed. > > > > It leads me to the question: "is there an easy way to serve in main > > thread?" (by easy I mean without rewriting an external polling loop > > as shown in example fileserver_example_external_select.c) Did I > > missed some option? > > > > Best regards > > José Bollo > > > >
Re: [libmicrohttpd] running in main thread
On 12/2/19 4:49 PM, José Bollo wrote: > On Mon, 2 Dec 2019 15:08:39 +0100 > José Bollo wrote: > >> On Mon, 2 Dec 2019 15:04:52 +0100 >> José Bollo wrote: >> >> rereading comment of MHD_USE_INTERNAL_POLLING_THREAD my question looks >> stupid > > No in fact the question is serious. There is no simple way to let run > MHD on the main thread. It requires implementing an external > poll/select loop. > > Can you provide an integrated main that serves and doesn't return until > stopped? That doesn't make sense to me, as then we don't have a 'stop' condition. With the internal polling thread, you can simply implement a while (! stop); yourself, and if you never want to stop, "while(1) sleep(1);" would do. But usually you then _must_ do something else until you encounter your stop condition, and so that is what you should implement. Or you have an existing event loop, in which case you should use MHD's external event loop. signature.asc Description: OpenPGP digital signature
Re: [libmicrohttpd] running in main thread
Dear friends. On Mon, Dec 2, 2019 at 12:49 PM José Bollo wrote: > No in fact the question is serious. There is no simple way to let run > MHD on the main thread. It requires implementing an external > poll/select loop. > > Can you provide an integrated main that serves and doesn't return until > stopped? > IMHO, it would be really very useful. Unfortunately, without this feature, we need to implement hard logic using select()/epoll() by hand in our console applications. In Rust and Pascal we generally call some locking function to stay "running" application, in those cases, it would be nice to call something like this: static int my_awesome_callback(void *cls) { return *application_terminated* ? MHD_YES : MHD_NO; } MHD_main_loop(my_awesome_callback, NULL); so the MHD_main_loop() would hold the console application without exiting, something like getchar() does. Many other C/Rust libraries implements this loop, for example: 1. libsoup / C: https://gitlab.gnome.org/GNOME/libsoup/blob/master/examples/simple-httpd.c#L300 2. mongoose / C: https://github.com/cesanta/mongoose/blob/master/examples/simplest_web_server/simplest_web_server.c#L33 3. warp / Rust: https://github.com/seanmonstar/warp/blob/master/examples/hello.rs#L9 4. actix-web / Rust: https://github.com/actix/actix-web/blob/master/examples/basic.rs#L46 This is a very appreciated feature in many other libraries/frameworks. Best regards > José Bollo -- Silvio Clécio
Re: [libmicrohttpd] running in main thread
On Mon, Dec 2, 2019 at 2:22 PM silvioprog wrote: > In Rust and Pascal we generally call some locking function to stay > "running" application, in those cases, it would be nice to call something > like this: > > static int my_awesome_callback(void *cls) { > return *application_terminated* ? MHD_YES : MHD_NO; > } > > MHD_main_loop(my_awesome_callback, NULL); > Another (possible?) option (supposing a function named "MHD_poll"): int main(void) { /* some MHD deamon initialization */ while (!terminated) { /* terminated -> e.g.: some termination condition handle by signal */ MHD_poll(); // something similar too: https://github.com/cesanta/mongoose/blob/master/examples/simplest_web_server/simplest_web_server.c#L33 } } So the MHD_poll() would allow to reuse the built in MHD's select/epoll in any external thread (for example, in the main thread of a console application). Maybe a MHD_poll() is already implemented in MHD in some private function. If so, that function would be very appreciated as an external function. :-) -- Silvio Clécio
Re: [libmicrohttpd] running in main thread
On Mon, 2 Dec 2019 17:41:09 +0100 Christian Grothoff wrote: > On 12/2/19 4:49 PM, José Bollo wrote: > > On Mon, 2 Dec 2019 15:08:39 +0100 > > José Bollo wrote: > > > >> On Mon, 2 Dec 2019 15:04:52 +0100 > >> José Bollo wrote: > >> > >> rereading comment of MHD_USE_INTERNAL_POLLING_THREAD my question > >> looks stupid > > > > No in fact the question is serious. There is no simple way to let > > run MHD on the main thread. It requires implementing an external > > poll/select loop. > > > > Can you provide an integrated main that serves and doesn't return > > until stopped? > > That doesn't make sense to me, as then we don't have a 'stop' > condition. With the internal polling thread, you can simply implement > a while (! stop); yourself, and if you never want to stop, "while(1) > sleep(1);" would do. > > But usually you then _must_ do something else until you encounter your > stop condition, and so that is what you should implement. Or you have > an existing event loop, in which case you should use MHD's external > event loop. > I tried to write something like "while(true) MHD_run();" but strace showed its inefficiency. IMHO it can make sense: "1. setup 2. run" without exit conditon and not bound to any stdin, i.e. a normal unix daemon.
Re: [libmicrohttpd] running in main thread
On 12/2/19 9:55 PM, José Bollo wrote: > > I tried to write something like "while(true) MHD_run();" but strace > showed its inefficiency. Oh my. Yes, that'd be bad. > IMHO it can make sense: "1. setup 2. run" without exit conditon and not > bound to any stdin, i.e. a normal unix daemon. > Well, that's trivial. Please consider the attached fragment (not tested, but should be very close to what you need, modulo error handling). // launch MHD with MHD_USE_EPOLL (and NOT any "INTERNAL_THREAD") { int fd; fd = MHD_get_daemon_info (daemon, MHD_DAEMON_INFO_EPOLL_FD)->epoll_fd; while (1) { fd_set r; MHD_UNSIGNED_LONG_LONG to; struct timeval tv; FD_ZERO (&r); FD_SET (fd, &r); MHD_get_timeout (daemon, &to); tv.tv_sec = (to / 1000LLU); tv.tv_usec = (to % 1000LLU) * 1000; select (r + 1, &r, NULL, NULL, NULL); MHD_run (daemon); } } signature.asc Description: OpenPGP digital signature
Re: [libmicrohttpd] running in main thread
On Mon, 2 Dec 2019 22:03:51 +0100 Christian Grothoff wrote: > On 12/2/19 9:55 PM, José Bollo wrote: > > > > I tried to write something like "while(true) MHD_run();" but strace > > showed its inefficiency. > > Oh my. Yes, that'd be bad. > > > IMHO it can make sense: "1. setup 2. run" without exit conditon and > > not bound to any stdin, i.e. a normal unix daemon. > > > > Well, that's trivial. Please consider the attached fragment (not > tested, but should be very close to what you need, modulo error > handling). I know it is trivial (my implementation below) but I advocate to offer a facility that does the job. It avoids tricky aspects like EPOLL and get_daemon_info (is working for windows???) mhd = MHD_start_daemon(MHD_USE_EPOLL, ... if (!mhd) return 1; info = MHD_get_daemon_info(mhd, MHD_DAEMON_INFO_EPOLL_FD); if (info == NULL) { MHD_stop_daemon(mhd); return 2; } pfd.fd = info->epoll_fd; pfd.events = POLLIN; for(;;) { if (MHD_get_timeout(mhd, &to) == MHD_NO) i = -1; else i = (int)to; poll(&pfd, 1, i); MHD_run(mhd); } MHD_stop_daemon (mhd); return 0;
Re: [libmicrohttpd] running in main thread
On 12/2/19 10:18 PM, José Bollo wrote: >> Well, that's trivial. Please consider the attached fragment (not >> tested, but should be very close to what you need, modulo error >> handling). > I know it is trivial (my implementation below) but I advocate to offer > a facility that does the job. It avoids tricky aspects like EPOLL and > get_daemon_info (is working for windows???) AFAIK on the Windows Subsystem for Linux it should work, and everything else is a mess to do in a portable way. Regardless, these loops are usually pretty simple, hence I do still think that they don't belong into the library. What we could do is at sample loops into the documentation (tutorial?). signature.asc Description: OpenPGP digital signature