| 593 | } |
| 594 | |
| 595 | inline HttpTunnelConsumer * |
| 596 | HttpTunnel::get_consumer(VConnection *vc) |
| 597 | { |
| 598 | /** Rare but persistent problem in which a @c INKVConnInternal is used by a consumer, released, |
| 599 | and then re-allocated for a different consumer. This causes two consumers to have the same VC |
| 600 | pointer resulting in this method returning the wrong consumer. Note this is a not a bad use of |
| 601 | the tunnel, but an unfortunate interaction with the FIFO free lists. |
| 602 | |
| 603 | It's not correct to check for the consumer being alive - at a minimum `HTTP_TUNNEL_EVENT_DONE` |
| 604 | is dispatched against a consumer after the consumer is not alive. Instead if a non-alive |
| 605 | consumer matches it is stored as a candidate and returned if no other match is found. If a |
| 606 | live matching consumer is found, it is immediately returned. It is never valid to have the |
| 607 | same VC in more than one active consumer. This should avoid a performance impact because in |
| 608 | the usual case the consumer will be alive. |
| 609 | |
| 610 | In the case of a deliberate dispatch of an event to a dead consumer that has a duplicate vc |
| 611 | address, this will select the last consumer which will be correct as the consumers are added |
| 612 | in order therefore the latter consumer will be the most recent / appropriate target. |
| 613 | */ |
| 614 | HttpTunnelConsumer *zret = nullptr; |
| 615 | for (HttpTunnelConsumer &c : consumers) { |
| 616 | if (c.vc == vc) { |
| 617 | zret = &c; |
| 618 | if (c.alive) { // a match that's alive is always the best. |
| 619 | break; |
| 620 | } |
| 621 | } |
| 622 | } |
| 623 | return zret; |
| 624 | } |
| 625 | |
| 626 | inline HttpTunnelProducer * |
| 627 | HttpTunnel::get_producer(VIO *vio) |
no outgoing calls
no test coverage detected