Add new error code NGHTTP2_ERR_PAUSE to send_data_callback
If application returns NGHTTP2_ERR_PAUSE from send_data_callback, it means application processed all data, but wants to make nghttp2_session_mem_send or nghttp2_session_send return immediately. This is useful if application writes to fixed sized buffers, and there is no room to write more data.
This commit is contained in:
parent
da89f9c150
commit
45d4c9dece
|
@ -1199,18 +1199,22 @@ typedef ssize_t (*nghttp2_send_callback)(nghttp2_session *session,
|
||||||
* The application has to send complete DATA frame in this callback.
|
* The application has to send complete DATA frame in this callback.
|
||||||
* If all data were written successfully, return 0.
|
* If all data were written successfully, return 0.
|
||||||
*
|
*
|
||||||
* If it cannot send it all, just return
|
* If it cannot send any data at all, just return
|
||||||
* :enum:`NGHTTP2_ERR_WOULDBLOCK`; the library will call this callback
|
* :enum:`NGHTTP2_ERR_WOULDBLOCK`; the library will call this callback
|
||||||
* with the same parameters later (It is recommended to send complete
|
* with the same parameters later (It is recommended to send complete
|
||||||
* DATA frame at once in this function to deal with error; if partial
|
* DATA frame at once in this function to deal with error; if partial
|
||||||
* frame data has already sent, it is impossible to send another data
|
* frame data has already sent, it is impossible to send another data
|
||||||
* in that state, and all we can do is tear down connection). If
|
* in that state, and all we can do is tear down connection). When
|
||||||
* application decided to reset this stream, return
|
* data is fully processed, but application wants to make
|
||||||
* :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then the library
|
* `nghttp2_session_mem_send()` or `nghttp2_session_send()` return
|
||||||
* will send RST_STREAM with INTERNAL_ERROR as error code. The
|
* immediately without processing next frames, return
|
||||||
* application can also return :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`,
|
* :enum:`NGHTTP2_ERR_PAUSE`. If application decided to reset this
|
||||||
* which will result in connection closure. Returning any other value
|
* stream, return :enum:`NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE`, then
|
||||||
* is treated as :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
|
* the library will send RST_STREAM with INTERNAL_ERROR as error code.
|
||||||
|
* The application can also return
|
||||||
|
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE`, which will result in
|
||||||
|
* connection closure. Returning any other value is treated as
|
||||||
|
* :enum:`NGHTTP2_ERR_CALLBACK_FAILURE` is returned.
|
||||||
*/
|
*/
|
||||||
typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
|
typedef int (*nghttp2_send_data_callback)(nghttp2_session *session,
|
||||||
nghttp2_frame *frame,
|
nghttp2_frame *frame,
|
||||||
|
|
|
@ -2610,12 +2610,15 @@ static int session_call_send_data(nghttp2_session *session,
|
||||||
&aux_data->data_prd.source,
|
&aux_data->data_prd.source,
|
||||||
session->user_data);
|
session->user_data);
|
||||||
|
|
||||||
if (rv == 0 || rv == NGHTTP2_ERR_WOULDBLOCK ||
|
switch (rv) {
|
||||||
rv == NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE) {
|
case 0:
|
||||||
|
case NGHTTP2_ERR_WOULDBLOCK:
|
||||||
|
case NGHTTP2_ERR_PAUSE:
|
||||||
|
case NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
default:
|
||||||
|
|
||||||
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
return NGHTTP2_ERR_CALLBACK_FAILURE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
||||||
|
@ -2790,6 +2793,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
||||||
case NGHTTP2_OB_SEND_NO_COPY: {
|
case NGHTTP2_OB_SEND_NO_COPY: {
|
||||||
nghttp2_stream *stream;
|
nghttp2_stream *stream;
|
||||||
nghttp2_frame *frame;
|
nghttp2_frame *frame;
|
||||||
|
int pause;
|
||||||
|
|
||||||
DEBUGF(fprintf(stderr, "send: no copy DATA\n"));
|
DEBUGF(fprintf(stderr, "send: no copy DATA\n"));
|
||||||
|
|
||||||
|
@ -2833,7 +2837,7 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(rv == 0);
|
pause = (rv == NGHTTP2_ERR_PAUSE);
|
||||||
|
|
||||||
rv = session_after_frame_sent1(session);
|
rv = session_after_frame_sent1(session);
|
||||||
if (rv < 0) {
|
if (rv < 0) {
|
||||||
|
@ -2848,6 +2852,10 @@ static ssize_t nghttp2_session_mem_send_internal(nghttp2_session *session,
|
||||||
|
|
||||||
/* We have already adjusted the next state */
|
/* We have already adjusted the next state */
|
||||||
|
|
||||||
|
if (pause) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case NGHTTP2_OB_SEND_CLIENT_MAGIC: {
|
case NGHTTP2_OB_SEND_CLIENT_MAGIC: {
|
||||||
|
|
Loading…
Reference in New Issue