I'm not sure about this being in 0.9.14, but if you're actually using SVN HEAD, the attached patch might help (I think my 'early' response cleanup code was a bit eager...).
Happy hacking. -Christian On Monday, September 19, 2011 01:24:14 PM Regis Louge wrote: > You made yourself clear on that I removed all struct MHD_Connections in my > structures and never use MHD_close_connection. > > I am running the program on Linux. I tested a lot of scenarios with 0.9.13, > closed and reopened 20 connections with 2 different clients etc... and > things work fine. > > Whereas with the 0.9.14 I followed the Segmentation fault in debug with > Anjuta and as I told you it appears : > > int MHD_connection_handle_write (struct MHD_Connection *connection) > > |_switch (connection->state) > | > |_case MHD_CONNECTION_CHUNKED_BODY_READY: > |_check_write_done (connection, > > (connection->response->total_size == > connection->response_write_position) ? > MHD_CONNECTION_BODY_SENT : > MHD_CONNECTION_CHUNKED_BODY_UNREADY); > > Valgrind says : > > ==24566== Thread 4: > ==24566== Invalid read of size 8 > ==24566== at 0x4E33DD3: MHD_connection_handle_write (connection.c:1899) > ==24566== by 0x4E36E78: MHD_handle_connection (daemon.c:624) > ==24566== by 0x626CD8B: start_thread (pthread_create.c:304) > ==24566== by 0x5A9D04C: clone (clone.S:112) > ==24566== Address 0x50 is not stack'd, malloc'd or (recently) free'd > > > > > On Fri, Sep 16, 2011 at 1:41 PM, Christian Grothoff > > <christ...@grothoff.org>wrote: > > On Friday, September 16, 2011 11:46:15 AM Regis Louge wrote: > > > Christian, > > > > > > The purpose of the Web Server is to manage Services, as it is now it > > > provides an interface for the clients for them to interact with those > > > services, for example a performing a HTTP GET request on a Service will > > > return its value and performing a HTTP PUT request will set this value > > > to the given one. The Web Server can contain a lot of Services and > > > have a > > > > lot > > > > > of clients. > > > > > > In addition to that, one of the feature that I want to add is to be > > > able > > > > to > > > > > receive notifications on value changes of certain services. To do so, > > > > each > > > > > client should be able to perform a GET on the URI "/events" in order to > > > engage the connection to these notifications. Then, whenever a Service > > > changes value, the server checks if the client has subscribed to that > > > service's notifications, and if so, it sends him a notification of the > > > value change with the new value. > > > > > > For now on, this works well thanks to > > > MHD_create_response_from_callback. All clients receive notifications > > > of the services that they subscribed to etc... > > > > > > I have to admit that the choice of defining clients with IP addresses > > > was not well thought,indeed I used IP address as unique identifiers > > > for each client and didn't think of all the scenarios (even though the > > > web server aims at being run in a Local Area Network) I remodeled the > > > notifications part on the web server using Sessions, thank you for the > > > advice ! > > > > > > Nevertheless, the segmentation fault still appears when I close and > > > > reopen > > > > > another connection, MHD tells me that it is impossible to send data due > > > > to > > > > > a "Broken Pipe", and goes into the request_completed callback. (the > > > same segmentation fault in my previous mail) > > > > > > I just downgraded my MHD to 0.9.13 and it works like a charm ! (tried > > > > with > > > > > 0.9.14 and SVN HEAD) Any idea why ? > > > > I doubt it is the different version, you might just have gotten lucky > > (memory > > corruption can cause non-deterministic bugs...). In any case, let me > > again say that if your code still does (as you wrote earlier): > > > > if(client->connection != NULL) > > > > MHD_connection_close(client->connection, > > > > MHD_REQUEST_TERMINATED_WITH_ERROR); > > > > you will have problems. MHD_connection_close is not in microhttpd.h and > > not an > > exported symbol so client code must not use it or face the music (i.e. > > crashes). > > > > As for 'broken pipe' -- did you ever read this? > > > > http://www.gnu.org/s/libmicrohttpd/microhttpd.html#SIGPIPE > > > > If not, this might be your problem (even though it is not a SIGSEGV in > > that case, but a SIGPIPE), unless you're on GNU/Linux. If this is not > > the issue, > > try using valgrind to find out more about your segfault... > > > > Happy hacking, > > > > Christian > > > > > On Thu, Sep 15, 2011 at 2:57 PM, Christian Grothoff > > > > > > <christ...@grothoff.org>wrote: > > > > Eh, MHD_connection_close is NOT part of the public API for good > > > > reasons. > > > > > > You MUST not use it, the symbol is not even exported by the library. > > > > > > > > Getting segmentation faults from using it yourself is expected. Do > > > > not do that. > > > > > > > > Also, I am getting more an more confused about what you're trying to > > > > do. > > > > > > Naturally you CAN get two connections from the same source IP address > > > > at > > > > > > the same time, and your server should support that (otherwise it is > > > > simply broken). MHD has no problem handling more than one connection > > > > per IP at a time either. > > > > > > > > > > > > I currently can only conclude that you're trying to do something with > > > > IP > > > > > > addresses that you should manage with sessions/cookies and that your > > > > application logic is most likely severely broken (based on not > > > > understanding TCP/IP and/or HTTP) and thus you're trying to do these > > > > strange things and come up with odd requirements like the 'instant' > > > > cleanup on connection closure. > > > > > > > > TCP-FIN is not 'instant' and a browser may send us a TCP-SYN before > > > > we get the FIN, right? Not to mention, what would your system do > > > > with two users behind NAT using the same IP address? > > > > > > > > With SVN HEAD, MHD is now calling the response destroy handler (as > > > > well as the 'connection completed' handlers) as soon as the OS tells > > > > us that the connection is dead. More cannot be done, and mucking > > > > around with MHD internals is not going to improve the situation. > > > > Also, you should NEVER EVER store a 'struct MHD_Connection' in your > > > > own data structures, that's virtually always a bug. Instead, store > > > > a pointer to your data structures in the 'void**' you're provided by > > > > MHD. > > > > > > > > Happy hacking! > > > > > > > > Christian > > > > > > > > On 09/15/2011 09:15 AM, Regis Louge wrote: > > > >> Hi, > > > >> > > > >> I have updated my version to the 0.9.14 that contains this patch > > > >> (without compilation error :) ). I managed to handle the > > > >> disconnection reconnection of the client by storing the > > > >> MHD_Connection in my > > > > structure > > > > > >> and closing it manually whenever a call on "/push" is made from the > > > > same > > > > > >> IP address and a previous connection was stored : > > > >> > > > >> if(client->connection != NULL) > > > >> MHD_connection_close(client->**connection, > > > >> MHD_REQUEST_TERMINATED_WITH_**ERROR); > > > >> client->connection = connection; > > > >> > > > >> Now I encounter something really weird, indeed, if a client > > > > disconnects, > > > > > >> I can "send" him a push notification without anything happening on > > > >> my web server, but when I "send" him a second one I have this weird > > > >> segmentation fault in : > > > >> > > > >> int MHD_connection_handle_write (struct MHD_Connection *connection) > > > >> > > > >> |_switch (connection->state) > > > >> | > > > >> |_case MHD_CONNECTION_CHUNKED_BODY_**READY: > > > >> |_check_write_done (connection, > > > >> | > > > >> (connection->response->total_**size == > > > >> > > > >> connection->response_write_**position) > > > >> ? > > > >> > > > >> MHD_CONNECTION_BODY_SENT : > > > >> MHD_CONNECTION_CHUNKED_BODY_**UNREADY); > > > >> > > > >> It is right after the connection closes so connection->state is > > > > supposed > > > > > >> to be MHD_CONNECTION_CLOSED ? > > > >> > > > >> Any idea what that would happen ? And why does the first push > > > >> notification attempt don't fail ? > > > >> > > > >> Thanks a lot
Index: connection.c =================================================================== --- connection.c (revision 16953) +++ connection.c (working copy) @@ -311,11 +311,6 @@ &connection->client_context, termination_code); connection->client_aware = MHD_NO; - if (connection->response != NULL) - { - MHD_destroy_response (connection->response); - connection->response = NULL; - } } @@ -2291,6 +2286,11 @@ } continue; case MHD_CONNECTION_CLOSED: + if (connection->response != NULL) + { + MHD_destroy_response (connection->response); + connection->response = NULL; + } daemon = connection->daemon; if (0 != pthread_mutex_lock(&daemon->cleanup_connection_mutex)) {