| 1328 | } |
| 1329 | |
| 1330 | static void ev_no_io(h2_proxy_session *session, int arg, const char *msg) |
| 1331 | { |
| 1332 | switch (session->state) { |
| 1333 | case H2_PROXYS_ST_BUSY: |
| 1334 | case H2_PROXYS_ST_LOCAL_SHUTDOWN: |
| 1335 | case H2_PROXYS_ST_REMOTE_SHUTDOWN: |
| 1336 | /* nothing for input and output to do. If we remain |
| 1337 | * in this state, we go into a tight loop and suck up |
| 1338 | * CPU cycles. Ideally, we'd like to do a blocking read, but that |
| 1339 | * is not possible if we have scheduled tasks and wait |
| 1340 | * for them to produce something. */ |
| 1341 | if (h2_proxy_ihash_empty(session->streams)) { |
| 1342 | if (!is_accepting_streams(session)) { |
| 1343 | /* We are no longer accepting new streams and have |
| 1344 | * finished processing existing ones. Time to leave. */ |
| 1345 | session_shutdown(session, arg, msg); |
| 1346 | transit(session, "no io", H2_PROXYS_ST_DONE); |
| 1347 | } |
| 1348 | else { |
| 1349 | /* When we have no streams, no task events are possible, |
| 1350 | * switch to blocking reads */ |
| 1351 | transit(session, "no io", H2_PROXYS_ST_IDLE); |
| 1352 | } |
| 1353 | } |
| 1354 | else { |
| 1355 | /* Unable to do blocking reads, as we wait on events from |
| 1356 | * task processing in other threads. Do a busy wait with |
| 1357 | * backoff timer. */ |
| 1358 | transit(session, "no io", H2_PROXYS_ST_WAIT); |
| 1359 | } |
| 1360 | break; |
| 1361 | default: |
| 1362 | /* nop */ |
| 1363 | break; |
| 1364 | } |
| 1365 | } |
| 1366 | |
| 1367 | static void ev_stream_submitted(h2_proxy_session *session, int stream_id, |
| 1368 | const char *msg) |
no test coverage detected