event: directly add poller when adding to current core

This is required since pollers are now directly removed
(rather than scheduling an event) when the unregister call
is made on the poller's lcore.

Without this change, if a poller is registered then
immediately unregistered, the unregistration will seg
fault since the event adding the poller has not executed
yet.

Also add a test case that exhibits the sequence of events
described in this commit message.

Signed-off-by: Jim Harris <james.r.harris@intel.com>
Change-Id: I5c6ba0ee224ac1f8f3ebb8e7571714e718bd42db
This commit is contained in:
Jim Harris 2016-10-11 11:20:49 -07:00
parent 0aa2986475
commit d4d82fc3ab
2 changed files with 36 additions and 9 deletions

View File

@ -661,12 +661,9 @@ spdk_reactors_fini(void)
}
static void
_spdk_event_add_poller(spdk_event_t event)
_spdk_poller_register(struct spdk_reactor *reactor, struct spdk_poller *poller,
struct spdk_event *next)
{
struct spdk_reactor *reactor = spdk_event_get_arg1(event);
struct spdk_poller *poller = spdk_event_get_arg2(event);
struct spdk_event *next = spdk_event_get_next(event);
if (poller->period_ticks) {
spdk_poller_insert_timer(reactor, poller, spdk_get_ticks());
} else {
@ -678,13 +675,22 @@ _spdk_event_add_poller(spdk_event_t event)
}
}
static void
_spdk_event_add_poller(spdk_event_t event)
{
struct spdk_reactor *reactor = spdk_event_get_arg1(event);
struct spdk_poller *poller = spdk_event_get_arg2(event);
struct spdk_event *next = spdk_event_get_next(event);
_spdk_poller_register(reactor, poller, next);
}
void
spdk_poller_register(struct spdk_poller **ppoller, spdk_poller_fn fn, void *arg,
uint32_t lcore, struct spdk_event *complete, uint64_t period_microseconds)
{
struct spdk_poller *poller;
struct spdk_reactor *reactor;
struct spdk_event *event;
poller = calloc(1, sizeof(*poller));
if (poller == NULL) {
@ -709,10 +715,22 @@ spdk_poller_register(struct spdk_poller **ppoller, spdk_poller_fn fn, void *arg,
}
*ppoller = poller;
reactor = spdk_reactor_get(lcore);
event = spdk_event_allocate(lcore, _spdk_event_add_poller, reactor, poller, complete);
spdk_event_call(event);
if (lcore == spdk_app_get_current_core()) {
/*
* The poller is registered to run on the current core, so call the add function
* directly.
*/
_spdk_poller_register(reactor, poller, complete);
} else {
/*
* The poller is registered to run on a different core.
* Schedule an event to run on the poller's core that will add the poller.
*/
spdk_event_call(spdk_event_allocate(lcore, _spdk_event_add_poller, reactor, poller,
complete));
}
}
static void

View File

@ -44,6 +44,7 @@ static struct spdk_poller *poller_100ms;
static struct spdk_poller *poller_250ms;
static struct spdk_poller *poller_500ms;
static struct spdk_poller *poller_oneshot;
static struct spdk_poller *poller_unregister;
static void
test_end(void *arg)
@ -67,6 +68,11 @@ oneshot(void *arg)
spdk_poller_unregister(&poller_oneshot, NULL);
}
static void
nop(void *arg)
{
}
static void
test_start(spdk_event_t evt)
{
@ -79,6 +85,9 @@ test_start(spdk_event_t evt)
spdk_poller_register(&poller_250ms, tick, (void *)250, 0, NULL, 250000);
spdk_poller_register(&poller_500ms, tick, (void *)500, 0, NULL, 500000);
spdk_poller_register(&poller_oneshot, oneshot, NULL, 0, NULL, 0);
spdk_poller_register(&poller_unregister, nop, NULL, 0, NULL, 0);
spdk_poller_unregister(&poller_unregister, NULL);
}
static void