@@ -537,6 +537,7 @@ struct pn_listener_t {
537537
538538
539539static pn_event_batch_t * pconnection_process (pconnection_t * pc , uint32_t events , bool timeout , bool topup );
540+ static void write_flush (pconnection_t * pc );
540541static void listener_begin_close (pn_listener_t * l );
541542static void proactor_add (pcontext_t * ctx );
542543static bool proactor_remove (pcontext_t * ctx );
@@ -800,9 +801,13 @@ static void pconnection_forced_shutdown(pconnection_t *pc) {
800801static pn_event_t * pconnection_batch_next (pn_event_batch_t * batch ) {
801802 pconnection_t * pc = batch_pconnection (batch );
802803 pn_event_t * e = pn_connection_driver_next_event (& pc -> driver );
803- if (!e && pc -> hog_count < HOG_MAX ) {
804- if (pconnection_process (pc , 0 , false, true)) {
805- e = pn_connection_driver_next_event (& pc -> driver );
804+ if (!e ) {
805+ write_flush (pc ); // May generate transport event
806+ e = pn_connection_driver_next_event (& pc -> driver );
807+ if (!e && pc -> hog_count < HOG_MAX ) {
808+ if (pconnection_process (pc , 0 , false, true)) {
809+ e = pn_connection_driver_next_event (& pc -> driver );
810+ }
806811 }
807812 }
808813 return e ;
@@ -903,6 +908,23 @@ static bool pconnection_write(pconnection_t *pc, pn_bytes_t wbuf) {
903908 return true;
904909}
905910
911+ static void write_flush (pconnection_t * pc ) {
912+ if (!pc -> write_blocked && !pconnection_wclosed (pc )) {
913+ pn_bytes_t wbuf = pn_connection_driver_write_buffer (& pc -> driver );
914+ if (wbuf .size > 0 ) {
915+ if (!pconnection_write (pc , wbuf )) {
916+ psocket_error (& pc -> psocket , errno , pc -> disconnected ? "disconnected" : "on write to" );
917+ }
918+ }
919+ else {
920+ if (pn_connection_driver_write_closed (& pc -> driver )) {
921+ shutdown (pc -> psocket .sockfd , SHUT_WR );
922+ pc -> write_blocked = true;
923+ }
924+ }
925+ }
926+ }
927+
906928static void pconnection_connected_lh (pconnection_t * pc );
907929static void pconnection_maybe_connect_lh (pconnection_t * pc );
908930
@@ -1001,7 +1023,6 @@ static pn_event_batch_t *pconnection_process(pconnection_t *pc, uint32_t events,
10011023 pc -> current_arm = 0 ;
10021024 pc -> new_events = 0 ;
10031025 }
1004- bool unarmed = (pc -> current_arm == 0 );
10051026
10061027 if (pc -> context .closing && pconnection_is_final (pc )) {
10071028 unlock (& pc -> context .mutex );
@@ -1058,36 +1079,17 @@ static pn_event_batch_t *pconnection_process(pconnection_t *pc, uint32_t events,
10581079 tick_required = false;
10591080 }
10601081
1061- while (!pc -> write_blocked && !pconnection_wclosed (pc )) {
1062- pn_bytes_t wbuf = pn_connection_driver_write_buffer (& pc -> driver );
1063- if (wbuf .size > 0 ) {
1064- if (!pconnection_write (pc , wbuf )) {
1065- psocket_error (& pc -> psocket , errno , pc -> disconnected ? "disconnected" : "on write to" );
1066- }
1067- }
1068- else {
1069- if (pn_connection_driver_write_closed (& pc -> driver )) {
1070- shutdown (pc -> psocket .sockfd , SHUT_WR );
1071- pc -> write_blocked = true;
1072- }
1073- else
1074- break ; /* nothing to write until next read/wake/timeout */
1075- }
1076- }
1077-
10781082 if (topup ) {
10791083 // If there was anything new to topup, we have it by now.
1080- if (unarmed && pconnection_rearm_check (pc ))
1081- pconnection_rearm (pc );
10821084 return NULL ; // caller already owns the batch
10831085 }
10841086
10851087 if (pconnection_has_event (pc )) {
1086- if (unarmed && pconnection_rearm_check (pc ))
1087- pconnection_rearm (pc );
10881088 return & pc -> batch ;
10891089 }
10901090
1091+ write_flush (pc );
1092+
10911093 lock (& pc -> context .mutex );
10921094 if (pc -> context .closing && pconnection_is_final (pc )) {
10931095 unlock (& pc -> context .mutex );
@@ -1608,6 +1610,7 @@ pn_proactor_t *pn_proactor() {
16081610
16091611void pn_proactor_free (pn_proactor_t * p ) {
16101612 // No competing threads, not even a pending timer
1613+ p -> shutting_down = true;
16111614 close (p -> epollfd );
16121615 p -> epollfd = -1 ;
16131616 close (p -> eventfd );
0 commit comments