| 1344 | } |
| 1345 | |
| 1346 | static apr_status_t h2_session_send(h2_session *session) |
| 1347 | { |
| 1348 | int ngrv, pending = 0; |
| 1349 | apr_status_t rv = APR_SUCCESS; |
| 1350 | |
| 1351 | while (nghttp2_session_want_write(session->ngh2)) { |
| 1352 | ngrv = nghttp2_session_send(session->ngh2); |
| 1353 | ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, session->c1, |
| 1354 | "nghttp2_session_send: %d", (int)ngrv); |
| 1355 | pending = 1; |
| 1356 | if (ngrv != 0 && ngrv != NGHTTP2_ERR_WOULDBLOCK) { |
| 1357 | if (nghttp2_is_fatal(ngrv)) { |
| 1358 | h2_session_dispatch_event(session, H2_SESSION_EV_PROTO_ERROR, |
| 1359 | ngrv, nghttp2_strerror(ngrv)); |
| 1360 | rv = APR_EGENERAL; |
| 1361 | goto cleanup; |
| 1362 | } |
| 1363 | } |
| 1364 | if (h2_c1_io_needs_flush(&session->io) || |
| 1365 | ngrv == NGHTTP2_ERR_WOULDBLOCK) { |
| 1366 | rv = h2_c1_io_assure_flushed(&session->io); |
| 1367 | if (rv != APR_SUCCESS) |
| 1368 | goto cleanup; |
| 1369 | pending = 0; |
| 1370 | } |
| 1371 | } |
| 1372 | if (pending) { |
| 1373 | rv = h2_c1_io_pass(&session->io); |
| 1374 | } |
| 1375 | cleanup: |
| 1376 | if (rv != APR_SUCCESS) { |
| 1377 | h2_session_dispatch_event(session, H2_SESSION_EV_CONN_ERROR, rv, NULL); |
| 1378 | } |
| 1379 | return rv; |
| 1380 | } |
| 1381 | |
| 1382 | /** |
| 1383 | * A streams input state has changed. |
no test coverage detected