View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0001662 | libmicrohttpd | portability | public | 2011-02-23 15:58 | 2011-03-04 10:57 |
Reporter | bplant | Assigned To | Christian Grothoff | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | 0.9.5 | ||||
Summary | 0001662: Shutdown server without killing threads | ||||
Description | The current shutdown function kills all in progress connections. This is fine since a normal OS will free any held memory and/or locks. Other OS' (such an as RTOS) don't offer this feature and killing threads/tasks does not release memory and/or locks. The attached patch provides the option to make the MHD_close_connections() function non-static so that a custom shutdown function can be implemented. | ||||
Tags | No tags attached. | ||||
Attached Files | mhd_ext_shutdown.patch (1,195 bytes)
Index: D:/svn/dspy/NEW/libmicrohttpd/tags/0.9.5-r1/src/daemon/daemon.c =================================================================== --- D:/svn/dspy/NEW/libmicrohttpd/tags/0.9.5-r1/src/daemon/daemon.c (revision 694) +++ D:/svn/dspy/NEW/libmicrohttpd/tags/0.9.5-r1/src/daemon/daemon.c (revision 769) @@ -2131,7 +2131,7 @@ /** * Close all connections for the daemon */ -static void +void MHD_close_connections (struct MHD_Daemon *daemon) { while (daemon->connections != NULL) Index: D:/svn/dspy/NEW/libmicrohttpd/tags/0.9.5-r1/src/include/microhttpd.h =================================================================== --- D:/svn/dspy/NEW/libmicrohttpd/tags/0.9.5-r1/src/include/microhttpd.h (revision 694) +++ D:/svn/dspy/NEW/libmicrohttpd/tags/0.9.5-r1/src/include/microhttpd.h (revision 769) @@ -1110,6 +1110,13 @@ ssize_t send_param_adapter (struct MHD_Connection *connection, const void *other, size_t i); #endif +#ifdef MHD_ALLOW_EXTERNAL_STOP +/** + * Close all connections for the daemon + */ +void +MHD_close_connections (struct MHD_Daemon *daemon); +#endif /* **************** Connection handling functions ***************** */ | ||||
|
Eh, why don't you call 'MHD_stop_daemon'? That function DOES call 'MHD_close_connections'. MHD *does* terminate all of its threads and closes all of its sockets and releases all of its memory/locks properly if 'MHD_close_connections' is called, so I really do not understand your problem. |
|
I did try calling MHD_stop_daemon. It was a race condition. From memory, I think it was the following: 1. main daemon thread calls select on daemon->socket_fd 2. select adds the calling thread to a queue and sleeps 3. MHD_stop_daemon calls close on daemon->socket_fd 4. MHD_stop_daemon kills the main daemon thread 5. The main daemon thread has not woken up yet and so the call to select never removed the main daemon thread from the queue. I'm not suggesting for a second that there is anything wrong with MHD. This issue is caused by limitations of the RTOS and TCP/IP stack that I'm using. Unfortunately I can't run a fully fledged OS on a 80MHz MCU with 96KB of memory so I've got to work with what I have. Having the ability to write a custom stop function allows for these odd limitations to be worked around. |
|
You're wrong about step (4): MHD does never 'kill' the daemon thread, it just waits for it to terminate (normally!). We use 'pthread_join' here, 'pthread_kill' is not killing the thread but merely sending it a signal asking it to wake up (not to die!). Could you investigate some more as to what is actually going on? |
|
Hmmm, the platform I'm using doesn't have the concept of signals so pthread_kill is, well, killing. I'll look into what options I have. Thanks for the info. Feel free to close the bug. |
|
We can avoid the use of pthread_kill by using a pipe instead. Do you have pipes? |
|
I'm afraid not. The OS (freertos based) fits into 4-9KB of ROM so it doesn't do much other than provide multi-tasking, mutexes, semaphores and queues. |
|
So how do you get TCP!? Btw, switching to pipes (which I'm still thinking of doing) would also have advantages in terms of energy consumption (no more waking up from select if idle). |
|
Oh, and we'd not need a big pipe, just 1 byte to transmit via a selectable thingy to stop the select loop. So emulating it using a 1-byte-buffered TCP stream would also work. |
|
I have thread-safe queues and semaphores that can be used for thread synchronisation. I don't have conditional variables though (unlike pthread). A semaphore would seem to be much more lightweight than a TCP socket. |
|
But you cannot 'select' on a semaphore! What constructs do you have that you can 'select' on? I was suggesting a TCP socket because that way you at least don't have to add anything extra to the OS. |
|
Haha, the semaphores available to me take a timeout option similar to that of select. In my OS (freeRTOS), semaphores implemented using queues, so queues also take a timeout option. Do you need to send a signal to the main select thread to wake it? The daemon checks daemon->shutdown every loop and the main select thread exits when it is set. select() will surely return almost immediately after the listening TCP socket is closed so the main select thread should wake and exit almost immediately without needing to send a signal using pthread_kill(). |
|
Well, there was one case where this would have been nice: if you have a thread per connection, that thread would typically not notice the listen socket going away. But I can fix that by having those threads select on the listen socket as well (but not process the listen socket there). That leads to unnecessary wake-ups of those threads (on incoming connections, they may wake up needlessly), but otherwise similar to using a pipe (2 FDs in select/poll sets) and, no more need for pipes or signals. |
|
Select is already used in MHD_handle_connection which means the threads are already waking up periodically (every 1 second?). The while loop containing the select call appears to check con->daemon->shutdown so the per connection thread should already wake up, see that the daemon has been told to shutdown and then shut itself down if I'm not mistaken. |
|
pipe is now also gone, so this should now be fixed (SVN 14584). This version now uses neither signals nor pipes but just shutdown of the server socket to terminate all loops. |
Date Modified | Username | Field | Change |
---|---|---|---|
2011-02-23 15:58 | bplant | New Issue | |
2011-02-23 15:58 | bplant | File Added: mhd_ext_shutdown.patch | |
2011-02-24 13:57 | root | Note Added: 0004261 | |
2011-02-24 13:57 | root | Status | new => feedback |
2011-02-24 15:41 | bplant | Note Added: 0004268 | |
2011-02-27 00:39 | Christian Grothoff | Note Added: 0004269 | |
2011-02-28 08:41 | bplant | Note Added: 0004270 | |
2011-02-28 13:50 | Christian Grothoff | Note Added: 0004271 | |
2011-02-28 14:12 | bplant | Note Added: 0004274 | |
2011-03-02 16:57 | Christian Grothoff | Note Added: 0004275 | |
2011-03-02 17:08 | Christian Grothoff | Note Added: 0004277 | |
2011-03-02 17:49 | bplant | Note Added: 0004279 | |
2011-03-03 21:46 | Christian Grothoff | Note Added: 0004282 | |
2011-03-03 22:40 | bplant | Note Added: 0004283 | |
2011-03-04 09:33 | Christian Grothoff | Note Added: 0004285 | |
2011-03-04 10:00 | bplant | Note Added: 0004286 | |
2011-03-04 10:10 | Christian Grothoff | Note Added: 0004287 | |
2011-03-04 10:10 | Christian Grothoff | Status | feedback => resolved |
2011-03-04 10:10 | Christian Grothoff | Resolution | open => fixed |
2011-03-04 10:10 | Christian Grothoff | Assigned To | => Christian Grothoff |
2011-03-04 10:57 | Christian Grothoff | Status | resolved => closed |