MXS-1376 Really close a DCB only at the end of event loop

When dcb_close() is called, the DCB is only marked for closing
and the actual closing takes place only after all event handlers
have been called. That way, the state of the DCB will not change
during event processing but only after.

From a handler perspective this should now be just like it was
when the zombie queue was present.

TODO: There are far too many state variables or variables akin to
      state variables - dcb_role, state, persistentstart, n_close -
      in DCB. A cleanup is warranted.
This commit is contained in:
Johan Wikman
2017-08-29 15:35:02 +03:00
parent 08ae659310
commit 2a346fd061
2 changed files with 84 additions and 66 deletions

View File

@ -180,6 +180,7 @@ typedef struct dcb
struct dcb *next; /**< Next DCB in owning thread's list */
struct dcb *tail; /**< Last DCB in owning thread's list */
} thread;
uint32_t n_close; /** How many times dcb_close has been called. */
skygw_chk_t dcb_chk_tail;
} DCB;

View File

@ -99,11 +99,11 @@ void dcb_finish()
static void dcb_initialize(DCB *dcb);
static void dcb_final_free(DCB *dcb);
static void dcb_final_close(DCB *dcb);
static void dcb_call_callback(DCB *dcb, DCB_REASON reason);
static int dcb_null_write(DCB *dcb, GWBUF *buf);
static int dcb_null_auth(DCB *dcb, SERVER *server, MXS_SESSION *session, GWBUF *buf);
static inline DCB * dcb_find_in_list(DCB *dcb);
static inline void dcb_process_victim_queue(int threadid);
static void dcb_stop_polling_and_shutdown (DCB *dcb);
static bool dcb_maybe_add_persistent(DCB *);
static inline bool dcb_write_parameter_check(DCB *dcb, GWBUF *queue);
@ -1059,9 +1059,21 @@ void dcb_close(DCB *dcb)
// TODO: persistent pool here and now, and then close it immediately.
dcb->dcb_errhandle_called = true;
}
else if (dcb->n_close == 0)
{
dcb->n_close = 1;
}
else
{
bool should_close = true;
++dcb->n_close;
// TODO: Will this happen on a regular basis?
MXS_WARNING("dcb_close(%p) called %u times.", dcb, dcb->n_close);
}
}
static void dcb_final_close(DCB* dcb)
{
ss_dassert(dcb->n_close != 0);
if (dcb->dcb_role == DCB_ROLE_BACKEND_HANDLER && // Backend DCB
dcb->state == DCB_STATE_POLLING && // Being polled
@ -1079,11 +1091,11 @@ void dcb_close(DCB *dcb)
if (dcb_maybe_add_persistent(dcb))
{
should_close = false;
dcb->n_close = 0;
}
}
if (should_close)
if (dcb->n_close != 0)
{
if (dcb->state == DCB_STATE_POLLING)
{
@ -1136,7 +1148,6 @@ void dcb_close(DCB *dcb)
dcb_final_free(dcb);
}
}
}
/**
* Add DCB to persistent pool if it qualifies, close otherwise
@ -3052,6 +3063,12 @@ static uint32_t dcb_process_poll_events(DCB *dcb, uint32_t events)
}
}
#endif
if (dcb->n_close != 0)
{
dcb_final_close(dcb);
}
return rc;
}