in outnet_tcptimer: pick up callbacks and clean the struct pending for

use again in tcp_free list; then perform the callbacks in a cleaner state
for reentry into the outside network code.  Delete callbacks afterwards.
This commit is contained in:
W.C.A. Wijngaards 2020-07-09 10:28:47 +02:00
parent 80f21f48c5
commit d89a45d1e1

View file

@ -1773,6 +1773,7 @@ outnet_tcptimer(void* arg)
} else {
/* it was in use */
struct pending_tcp* pend=(struct pending_tcp*)w->next_waiting;
struct pending_tcp pickup;
/* see if it needs unlink from reuse tree */
if(pend->reuse.node.key) {
reuse_tcp_remove_tree_list(outnet, &pend->reuse);
@ -1785,19 +1786,33 @@ outnet_tcptimer(void* arg)
#endif
}
comm_point_close(pend->c);
/* pickup the callback items and call them after we have
* removed the current pending. so that the callbacks
* to the state machine happen after the query has timeouted
* and been deleted and it works from that clean state,
* because it may call the outside network routines to make
* new queries. */
pickup = *pend;
/* unlink them from pend, delete from pickup calls later */
pend->query = NULL;
rbtree_init(&pend->reuse.tree_by_id, reuse_id_cmp);
pend->reuse.write_wait_first = NULL;
pend->reuse.write_wait_last = NULL;
/* pend is clear for reuse in the tcp_free list */
pend->next_free = outnet->tcp_free;
outnet->tcp_free = pend;
/* do failure callbacks for all the queries in the
* wait for write list and in the id-tree */
/* callback for 'w' arg already in list of curquery,
* readwait list, writewait list */
reuse_cb_curquery_for_failure(pend, NETEVENT_TIMEOUT);
reuse_cb_readwait_for_failure(pend, NETEVENT_TIMEOUT);
reuse_cb_writewait_for_failure(pend, NETEVENT_TIMEOUT);
waiting_tcp_delete(pend->query); /* del curquery */
reuse_del_readwait(pend);
reuse_del_writewait(pend);
pend->query = NULL;
pend->next_free = outnet->tcp_free;
outnet->tcp_free = pend;
reuse_cb_curquery_for_failure(&pickup, NETEVENT_TIMEOUT);
reuse_cb_readwait_for_failure(&pickup, NETEVENT_TIMEOUT);
reuse_cb_writewait_for_failure(&pickup, NETEVENT_TIMEOUT);
/* delete the stored callback structures */
waiting_tcp_delete(pickup.query);
reuse_del_readwait(&pickup);
reuse_del_writewait(&pickup);
}
use_free_buffer(outnet);
}