Comments (10)
I think there has never been a mg_poll_server interface in Civetweb. Civetweb was forked from Mongoose in summer 2013 - since then they are two different webservers with different developers who have different ideas and priorities. Probably mg_poll_server has been added later?
What is this function actually supposed to do?
from civetweb.
That is mongoose "hello world":
int main(void) {
struct mg_server *server = mg_create_server(NULL, NULL);
mg_set_option(server, "document_root", "."); // Serve current directory
mg_set_option(server, "listening_port", "8080"); // Open port 8080
for (;;) {
mg_poll_server(server, 1000); // Infinite loop, Ctrl-C to stop
}
mg_destroy_server(&server);
return 0;
}
And from the docs:
"void mg_poll_server(struct mg_server *server, int milliseconds);
Performs one iteration of IO loop by iterating over all active connections, performing select() syscall on all sockets with a timeout of milliseconds. When select() returns, Mongoose does an IO for each socket that has data to be sent or received. Application code must call mg_poll_server() in a loop."
So basically its api allows to handle server requests in the thread of users choosing - for example from the main thread. Civetweb does not currently allow it. Poll api could be added to Civetweb quite easily imho: when number of threads passed to mq_start() is 0 (zero) then user has to explicitly call mg_poll_server() to process all pending requests in that thread.
It would be very useful for applications that already run in a loop constantly - like a game in my example.
from civetweb.
I once planned to provide a way to run the server in a single threaded environment - with the focus to small embedded devices, not game engines, but it would basically work for you as well. It is also useful for debugging, but I don't thing it is really simple. We can not take any code from mongoose, since it has an incompatible license. I did not do this yet, because I always considered it "nice to have", but not as essentially necessary - up to now I could afford the extra threads and I managed to debug it also as a multi-threaded application.
Why do you think you can not use the multi-threaded version?
from civetweb.
It is problematic when you want to embed it in already functional application. Because server request handlers are always called from new thread, all the objects that will be accessed from it suddenly have to be thread safe. This bad idea for several reasons. Also, current design is also not very efficient as it should use tasking and not thread-per-request and that could also be fixed by moving threading model to the user.
Civetweb must have client processing loop implemented already, why not expose it to the user? Why would Mongoose code be needed?
I will survive as I already made my C++ version of HttpServer poll-based. Requests from handler thread are added to internal queue, then thread blocks, waits for a call to poll() from main thread, poll() fullfills queued requests and wakes handler thread to resume client processing.
from civetweb.
I recently added functions to protect objects that are not thread safe:
https://github.com/bel2125/civetweb/blob/master/include/civetweb.h#L341
I agree, the current "thread-per-connection" design is not very efficient. We discussed that since October 2013: https://groups.google.com/forum/#!topic/civetweb/sFHF75IDSH0
The initial discussion was to do this for V1.6, but later I decided that V1.6 should be mainly about Lua redesign. V1.6 is released since about 3 weeks (and I took some holidays afterwards). So we can continue the discussion for V1.7 right now.
The is some more threading discussion here:
https://groups.google.com/forum/#!topic/civetweb/jQMC-okP2xk
from civetweb.
mg_(un)lock_context(struct mg_context* ctx) seem ok to sync all worker threads but what about main application thread (and others)?
Imagine you have a GUI application, user interacts with it the usual way, clicks widgets, edits with keyboard etc, lets say it is an spreadsheet app. In the background there is civetweb server running handling a request to print webpage based on the current state of the spreadsheet, now the spreadsheet has to locked every time it is accessed by civetweb or the user. But if there was poll interface, civetweb could be polled in the GUI thread explicitly or in some kind of Timer object that also triggers code in man/UI thread making everything just work correctly and integration of a server a breeze.
from civetweb.
Actually it can be done with the present lock mechanisms in the API as well.
However, I agree that when we rewrite the threading mechanism, we should also support that civetweb does not create any thread at all - so you would have to use a poll interface like the one you need.
Changing the threading mechanism is not something that can be done quickly over the weekend, so it might take some weeks until I find time to look at this more closely.
from civetweb.
This issue is now open for a while, so I want to update the status:
The issue is a request for an interface to use the web server in a way it does not create any thread, but only works as a callback called from an external thread.
It was reported when we planned to rewrite the threading model used within the server. Civetweb uses one thread per open connection, which in theory appears to be a bad idea since it uses a lot of threads, and threads are in theory expensive. Now, meanwhile we tested >32000 clients with one Civetweb instance by just creating 32000 threads, and in practice did not have any problems on a 5 year old standard desktop computer (see #50). It was not even a special server hardware but something you might even get second hand for <100$ nowadays.
So the original reason to restructure the threading model is no longer true (it was never true, but now there is an experimental evidence).
Thus, I think I will not restructure the threading model any time soon.
Still, I do understand the problem and probably make a short example how you could use the multi-threaded server in an otherwise single-threaded application without taking care about locks there.
Internally it will be some kind of lock or message queue, but not a really single threaded server.
Also I will start with this example not before the next release.
from civetweb.
It is not just a matter of performance, threading model should not be part of library or should be configurable at very least (whether task scheduler is single threaded or a pool of threads or just blocking etc.). For example boost.asio which is de-facto standard high performance networking / asynchronous request handling does not create threads for handling messages but lets the user decide how it should be handled. This way if user wants to create thread-per-connection it is perfectly fine (and often the choice) but still allows to customize things enough to be able to handle requests from very specific thread (like UI thread). If it wont happen for civetweb that's fine, I am syncing it manually now anyway but configurability is a good thing.
from civetweb.
I technically agree.
But boost is a C++ library and civetweb is and should remain pure C.
Changing the threading model and stabilizing the server again is a lot of work, and I can currently not take this effort.
I just wanted to state the original reason to restructure the threading model, the expected limit for a high number of connections, turned out to be not really a problem.
from civetweb.
Related Issues (20)
- [Security] lua used in this project is vulnerable HOT 1
- CSP HOT 1
- Errors in Lua scripts and Lua Server Pages not handled well HOT 2
- Cannot make 1.16 civetweb working as WS Client / Server solution HOT 6
- error in URI mapping? HOT 1
- Adding .wasm MIME type to civetweb.c
- mg_websocket_write() returns different size than what I try to send HOT 1
- Any comparisons to Nginx, Apache or libmicrohttpd?
- websocket client - "magic" key should be random
- Lua mg.send_file() is broken in the code cloned from github.com/civetweb/civetweb HOT 2
- Android's W^X problem and the executable version of civetweb HOT 1
- Docs: "Often the easiest way to embed CivetWeb is to add the civetweb.c file into your existing C project (see below).". This is not enough, right? HOT 1
- What tools (curl etc.) work for testing the test server externally (e.g. via adb shell)? HOT 1
- Missing `WITH_ALL` flag in cmake
- build example error: openssl3.0 HOT 1
- compile error
- Why are the test examples in .xhtml? HOT 1
- Are there recommended ways to get OpenSSL support for Android? HOT 4
- CodeQL not working HOT 1
- Manual did not mention preparations for OpenSSL support?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from civetweb.