Threading modelAs of version 2.5, Mongoose implements adaptive thread pool functionality. There is a master thread which opens all configured ports and waits for connections. Once new connection arrives, master thread spawns a new thread to serve that connection. When spawned thread has finished handling the connection, it stays idle for some time (controllable by -idle_time <seconds> option), during which master thread may pass another connection to serve. Thus, each connection is executed in its own thread, and the number of threads varies with the actual web server load. Total number of active threads, however, is limited by -max_threads <number> option. If total number of active threads reaches threshold, and new connection arrives, master thread waits until some of the threads becomes idle. Meanwhile, TCP listening queue builds up. If no thread becomes idle, and TCP queue overloads, TCP starts to reject new connections. User callback functionsIn embedded environment, URI handler may do blocking calls without any fear to affect other connections. Also, it can output as many data back to the client as necessary. All writes are done in synchronous (blocking) way. If handler function modifies some internal data within the application, make sure that modification are properly synchronized, since more that one connection may execute the same function in parallel. Porting from SHTTPDAlthough the API and the basic ideas are similar, there some architectural differences between SHTTPD and Mongoose. A table below describes those. | | SHTTPD | Mongoose | | Threading model | Single-threaded. An application must explicitely call shttpd_poll() | Multi-threaded. Server is started in detached thread, there is no need for polling | | HTTP request information | Different pieces of information must be retrieved by means of different functions | All request information is put together in one structure, struct mg_request_info, which is passed to the callback | | Reading and writing data | Input and output buffers are passed into the callback. POST data is in input buffer, and the reply must be written into the output buffer. POST data may be incomplete in the input buffer | No input and output buffers. POST data is always complete and is accessible via request_info. There is no output buffer, data is written back to the browser by means of mg_write() or mg_printf() | | Limits on written data | There is a limit on number of bytes callback can send in one go, this is the size of the output buffer. If callback cannot fit all the data in the ouptut buffer, it sends as much as it can and returns. SHTTPD will call it again when it sends some data to the browser and therefore release some space. Thus, in SHTTPD a callback may be called many times per one request | No limits on the size of written data | | Calling callbacks | One ore more times per request. If callback may be called more then one time, it must implement a state machine | Exactly once per request | | Restrictions | Callback is not allowed to call any blocking functions, like sleep(), block on mutex, etcetera. Sometimes even functions like read() may block (think NFS) and the entire program can be stuck | No restrictions |
|