Deliver fake events for the current dcb immediately
If a fake event is added to the current dcb, we arrange things so that it is delivered immediately when the handling of the event(s) during which the fake event was added, has been performed. Otherwise the event is delivered via the event loop.
This commit is contained in:
@ -156,6 +156,7 @@ typedef struct dcb
|
||||
GWBUF *delayq; /**< Delay Backend Write Data Queue */
|
||||
GWBUF *readq; /**< Read queue for storing incomplete reads */
|
||||
GWBUF *fakeq; /**< Fake event queue for generated events */
|
||||
uint32_t fake_event; /**< Fake event to be delivered to handler */
|
||||
|
||||
DCBSTATS stats; /**< DCB related statistics */
|
||||
struct dcb *nextpersistent; /**< Next DCB in the persistent pool for SERVER */
|
||||
|
@ -3126,11 +3126,6 @@ static uint32_t dcb_process_poll_events(DCB *dcb, uint32_t events)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dcb->n_close != 0)
|
||||
{
|
||||
dcb_final_close(dcb);
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -3138,6 +3133,25 @@ static uint32_t dcb_handler(DCB* dcb, uint32_t events)
|
||||
{
|
||||
this_thread.current_dcb = dcb;
|
||||
uint32_t rv = dcb_process_poll_events(dcb, events);
|
||||
|
||||
// When all I/O events have been handled, we will immediately
|
||||
// process an added fake event. As the handling of a fake event
|
||||
// may lead to the addition of another fake event we loop until
|
||||
// there is no fake event or the dcb has been closed.
|
||||
|
||||
while ((dcb->n_close == 0) && (dcb->fake_event != 0))
|
||||
{
|
||||
events = dcb->fake_event;
|
||||
dcb->fake_event = 0;
|
||||
|
||||
rv |= dcb_process_poll_events(dcb, events);
|
||||
}
|
||||
|
||||
if (dcb->n_close != 0)
|
||||
{
|
||||
dcb_final_close(dcb);
|
||||
}
|
||||
|
||||
this_thread.current_dcb = NULL;
|
||||
|
||||
return rv;
|
||||
@ -3177,6 +3191,26 @@ private:
|
||||
|
||||
static void poll_add_event_to_dcb(DCB* dcb, GWBUF* buf, uint32_t ev)
|
||||
{
|
||||
if (dcb == this_thread.current_dcb)
|
||||
{
|
||||
// If the fake event is added to the current DCB, we arrange for
|
||||
// it to be handled immediately in dcb_handler() when the handling
|
||||
// of the current events are done...
|
||||
|
||||
if (dcb->fake_event != 0)
|
||||
{
|
||||
MXS_WARNING("Events have already been injected to current DCB, discarding existing.");
|
||||
gwbuf_free(dcb->fakeq);
|
||||
dcb->fake_event = 0;
|
||||
}
|
||||
|
||||
dcb->fakeq = buf;
|
||||
dcb->fake_event = ev;
|
||||
}
|
||||
else
|
||||
{
|
||||
// ... otherwise we post the fake event using the messaging mechanism.
|
||||
|
||||
FakeEventTask* task = new (std::nothrow) FakeEventTask(dcb, buf, ev);
|
||||
|
||||
if (task)
|
||||
@ -3189,6 +3223,7 @@ static void poll_add_event_to_dcb(DCB* dcb, GWBUF* buf, uint32_t ev)
|
||||
MXS_OOM();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void poll_add_epollin_event_to_dcb(DCB* dcb, GWBUF* buf)
|
||||
{
|
||||
|
Reference in New Issue
Block a user