libmicrohttpd

HTTP/1.x server C library (MHD 1.x, stable)
Log | Files | Refs | Submodules | README | LICENSE

commit e22f196d71f9e28095bbc99c3504e8d1d4a1456c
parent 1fb16b78538b1e20733b03a9bf6ae02c2adb2cbb
Author: Christian Grothoff <christian@grothoff.org>
Date:   Wed, 18 Sep 2013 16:34:17 +0000

release lock earlier

Diffstat:
MChangeLog | 6+++++-
Msrc/microhttpd/connection.c | 20++++++++++----------
2 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog @@ -1,7 +1,11 @@ Wed Sep 18 18:29:24 CEST 2013 Signal connection termination as OK (and not as ERROR) if the stream was terminated by the callback returning - MHD_CONTENT_READER_END_OF_STREAM. -CG + MHD_CONTENT_READER_END_OF_STREAM. Also, release response + mutex before calling the termination callback, to avoid + possible deadlock if the client destroys the response in + the termination callback (due to non-recursiveness of the + lock). -CG Wed Sep 18 14:31:35 CEST 2013 Adding #define MHD_HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN. -CG diff --git a/src/microhttpd/connection.c b/src/microhttpd/connection.c @@ -317,7 +317,9 @@ connection_close_error (struct MHD_Connection *connection, * #MHD_NO). * * @param connection the connection - * @return #MHD_NO if readying the response failed + * @return #MHD_NO if readying the response failed (the + * lock on the response will have been released already + * in this case). */ static int try_ready_normal_body (struct MHD_Connection *connection) @@ -364,8 +366,10 @@ try_ready_normal_body (struct MHD_Connection *connection) { /* either error or http 1.0 transfer, close socket! */ response->total_size = connection->response_write_position; + if (NULL != response->crc) + pthread_mutex_unlock (&response->mutex); if (MHD_CONTENT_READER_END_OF_STREAM == ret) - MHD_connection_close (connection, MHD_REQUEST_TERMINATED_COMPLETD_OK); + MHD_connection_close (connection, MHD_REQUEST_TERMINATED_COMPLETED_OK); else CONNECTION_CLOSE_ERROR (connection, "Closing connection (stream error)\n"); @@ -376,6 +380,8 @@ try_ready_normal_body (struct MHD_Connection *connection) if (0 == ret) { connection->state = MHD_CONNECTION_NORMAL_BODY_UNREADY; + if (NULL != response->crc) + pthread_mutex_unlock (&response->mutex); return MHD_NO; } return MHD_YES; @@ -1978,12 +1984,8 @@ MHD_connection_handle_write (struct MHD_Connection *connection) response = connection->response; if (response->crc != NULL) pthread_mutex_lock (&response->mutex); - if (MHD_YES != try_ready_normal_body (connection)) - { - if (response->crc != NULL) - pthread_mutex_unlock (&response->mutex); - break; - } + if (MHD_YES != try_ready_normal_body (connection)) + break; ret = connection->send_cls (connection, &response->data [connection->response_write_position @@ -2351,8 +2353,6 @@ MHD_connection_handle_idle (struct MHD_Connection *connection) } if (MHD_YES == try_ready_normal_body (connection)) { - if (connection->response->crc != NULL) - pthread_mutex_unlock (&connection->response->mutex); connection->state = MHD_CONNECTION_NORMAL_BODY_READY; break; }