@@ -61,6 +61,8 @@ ClassAllocator<Http1ClientSession, true> http1ClientSessionAllocator("http1Clien
6161
6262Http1ClientSession::Http1ClientSession () : super(), trans(this ) {}
6363
64+ //
65+ // Will only close the connection if do_io_close has been called previously (to set read_state to HCS_CLOSED
6466void
6567Http1ClientSession::destroy ()
6668{
@@ -86,12 +88,16 @@ Http1ClientSession::release_transaction()
8688 if (transact_count == released_transactions) {
8789 // Make sure we previously called release() or do_io_close() on the session
8890 ink_release_assert (read_state != HCS_INIT);
89- if (read_state == HCS_ACTIVE_READER ) {
91+ if (is_active () ) {
9092 // (in)active timeout
9193 do_io_close (HTTP_ERRNO);
94+ } else if (read_state == HCS_ACTIVE_READER) {
95+ release (&trans); // Put back to keep-alive state
9296 } else {
9397 destroy ();
9498 }
99+ } else {
100+ ink_release_assert (transact_count == released_transactions);
95101 }
96102}
97103
209215Http1ClientSession::do_io_close (int alerrno)
210216{
211217 if (read_state == HCS_CLOSED) {
218+ if (transact_count == released_transactions) {
219+ this ->destroy ();
220+ }
212221 return ; // Don't double call session close
213222 }
214223 if (read_state == HCS_ACTIVE_READER) {
@@ -257,8 +266,6 @@ Http1ClientSession::do_io_close(int alerrno)
257266 HTTP_SUM_DYN_STAT (http_transactions_per_client_con, transact_count);
258267 read_state = HCS_CLOSED;
259268
260- // Can go ahead and close the netvc now, but keeping around the session object
261- // until all the transactions are closed
262269 if (_vc) {
263270 _vc->do_io_close ();
264271 _vc = nullptr ;
@@ -347,11 +354,21 @@ Http1ClientSession::state_keep_alive(int event, void *data)
347354{
348355 // Route the event. It is either for vc or
349356 // the origin server slave vc
350- if (data && data == slave_ka_vio) {
351- return state_slave_keep_alive (event, data);
352- } else {
353- ink_assert (data && data == ka_vio);
354- ink_assert (read_state == HCS_KEEP_ALIVE);
357+ if (data) {
358+ if (data == slave_ka_vio) {
359+ return state_slave_keep_alive (event, data);
360+ } else if (data == schedule_event) {
361+ schedule_event = nullptr ;
362+ } else {
363+ ink_assert (data && data == ka_vio);
364+ ink_assert (read_state == HCS_KEEP_ALIVE);
365+ }
366+ }
367+
368+ // If we got here due to a network I/O event directly, go ahead and cancel any remaining schedule events
369+ if (schedule_event) {
370+ schedule_event->cancel ();
371+ schedule_event = nullptr ;
355372 }
356373
357374 STATE_ENTER (&Http1ClientSession::state_keep_alive, event, data);
@@ -387,8 +404,6 @@ Http1ClientSession::state_keep_alive(int event, void *data)
387404void
388405Http1ClientSession::release (ProxyTransaction *trans)
389406{
390- ink_assert (read_state == HCS_ACTIVE_READER || read_state == HCS_INIT);
391-
392407 // When release is called from start() to read the first transaction, get_sm()
393408 // will return null.
394409 HttpSM *sm = trans->get_sm ();
@@ -409,6 +424,7 @@ Http1ClientSession::release(ProxyTransaction *trans)
409424 // buffer. If there is, spin up a new state
410425 // machine to process it. Otherwise, issue an
411426 // IO to wait for new data
427+ /* Start the new transaction once we finish completely the current transaction and unroll the stack */
412428 bool more_to_read = this ->_reader ->is_read_avail_more_than (0 );
413429 if (more_to_read) {
414430 HttpSsnDebug (" [%" PRId64 " ] data already in buffer, starting new transaction" , con_id);
@@ -429,19 +445,19 @@ Http1ClientSession::release(ProxyTransaction *trans)
429445 }
430446}
431447
432- void
448+ ProxyTransaction *
433449Http1ClientSession::new_transaction ()
434450{
435451 // If the client connection terminated during API callouts we're done.
436452 if (nullptr == _vc) {
437453 this ->do_io_close (); // calls the SSN_CLOSE hooks to match the SSN_START hooks.
438- return ;
454+ return nullptr ;
439455 }
440456
441457 if (!_vc->add_to_active_queue ()) {
442458 // no room in the active queue close the connection
443459 this ->do_io_close ();
444- return ;
460+ return nullptr ;
445461 }
446462
447463 // Defensive programming, make sure nothing persists across
@@ -453,6 +469,7 @@ Http1ClientSession::new_transaction()
453469 transact_count++;
454470
455471 trans.new_transaction (read_from_early_data > 0 ? true : false );
472+ return &trans;
456473}
457474
458475bool
@@ -472,7 +489,7 @@ Http1ClientSession::attach_server_session(PoolableSession *ssession, bool transa
472489 // have it call the client session back. This IO also prevent
473490 // the server net conneciton from calling back a dead sm
474491 SET_HANDLER (&Http1ClientSession::state_keep_alive);
475- slave_ka_vio = ssession->do_io_read (this , INT64_MAX, ssession->get_reader ()->mbuf );
492+ slave_ka_vio = ssession->do_io_read (this , INT64_MAX, ssession->get_remote_reader ()->mbuf );
476493 ink_assert (slave_ka_vio != ka_vio);
477494
478495 // Transfer control of the write side as well
0 commit comments