diff --git a/examples/sock/hello_world/hello_sock.c b/examples/sock/hello_world/hello_sock.c index a3a5d5531..412c68b4c 100644 --- a/examples/sock/hello_world/hello_sock.c +++ b/examples/sock/hello_world/hello_sock.c @@ -72,6 +72,8 @@ struct hello_context_t { struct spdk_poller *poller_in; struct spdk_poller *poller_out; struct spdk_poller *time_out; + + int rc; }; /* @@ -106,6 +108,13 @@ static void hello_sock_parse_arg(int ch, char *arg) } } +static void +hello_sock_net_fini_cb(void *cb_arg) +{ + struct hello_context_t *ctx = cb_arg; + spdk_app_stop(ctx->rc); +} + static int hello_sock_close_timeout_poll(void *arg) { @@ -115,8 +124,19 @@ hello_sock_close_timeout_poll(void *arg) spdk_poller_unregister(&ctx->time_out); spdk_poller_unregister(&ctx->poller_in); spdk_sock_close(&ctx->sock); + spdk_sock_group_close(&ctx->group); - spdk_app_stop(0); + spdk_net_framework_fini(hello_sock_net_fini_cb, arg); + return 0; +} + +static int +hello_sock_quit(struct hello_context_t *ctx, int rc) +{ + ctx->rc = rc; + spdk_poller_unregister(&ctx->poller_out); + ctx->time_out = spdk_poller_register(hello_sock_close_timeout_poll, ctx, + CLOSE_TIMEOUT_US); return 0; } @@ -164,11 +184,7 @@ hello_sock_writev_poll(void *arg) if (n == 0 || !g_is_running) { /* EOF */ SPDK_NOTICELOG("Closing connection...\n"); - - ctx->time_out = spdk_poller_register(hello_sock_close_timeout_poll, ctx, - CLOSE_TIMEOUT_US); - - spdk_poller_unregister(&ctx->poller_out); + hello_sock_quit(ctx, 0); return 0; } if (n > 0) { @@ -266,18 +282,19 @@ hello_sock_accept_poll(void *arg) uint16_t cport, sport; if (!g_is_running) { - spdk_poller_unregister(&ctx->poller_in); - spdk_poller_unregister(&ctx->poller_out); - spdk_sock_close(&ctx->sock); - spdk_sock_group_close(&ctx->group); - spdk_app_stop(0); + hello_sock_quit(ctx, 0); return 0; } while (1) { sock = spdk_sock_accept(ctx->sock); if (sock != NULL) { - spdk_sock_getaddr(sock, saddr, sizeof(saddr), &sport, caddr, sizeof(caddr), &cport); + rc = spdk_sock_getaddr(sock, saddr, sizeof(saddr), &sport, caddr, sizeof(caddr), &cport); + if (rc < 0) { + SPDK_ERRLOG("Cannot get connection addresses\n"); + spdk_sock_close(&ctx->sock); + return -1; + } SPDK_NOTICELOG("Accepting a new connection from (%s, %hu) to (%s, %hu)\n", caddr, cport, saddr, sport); @@ -350,14 +367,20 @@ hello_sock_shutdown_cb(void) { g_is_running = false; } + /* * Our initial event that kicks off everything from main(). */ static void -hello_start(void *arg1, void *arg2) +hello_start(void *arg1, int rc) { struct hello_context_t *ctx = arg1; - int rc = 0; + + if (rc) { + SPDK_ERRLOG("ERROR starting application\n"); + spdk_app_stop(-1); + return; + } SPDK_NOTICELOG("Successfully started the application\n"); @@ -373,6 +396,12 @@ hello_start(void *arg1, void *arg2) } } +static void +start_net_framework(void *arg1, void *arg2) +{ + spdk_net_framework_start(hello_start, arg1); +} + int main(int argc, char **argv) { @@ -395,18 +424,11 @@ main(int argc, char **argv) hello_context.port = g_port; hello_context.verbose = g_verbose; - rc = spdk_net_framework_start(); - if (rc) { - SPDK_ERRLOG("ERROR starting application\n"); - goto end; - } - - rc = spdk_app_start(&opts, hello_start, &hello_context, NULL); + rc = spdk_app_start(&opts, start_net_framework, &hello_context, NULL); if (rc) { SPDK_ERRLOG("ERROR starting application\n"); } -end: SPDK_NOTICELOG("Exiting from application\n"); if (hello_context.verbose) { @@ -414,8 +436,6 @@ end: hello_context.bytes_in, hello_context.bytes_out); } - spdk_net_framework_fini(); - /* Gracefully close out all of the SPDK subsystems. */ spdk_app_fini(); return rc; diff --git a/include/spdk/net.h b/include/spdk/net.h index ef58dd6d5..7326d51ba 100644 --- a/include/spdk/net.h +++ b/include/spdk/net.h @@ -82,17 +82,36 @@ int spdk_interface_init(void); */ void spdk_interface_destroy(void); +/** + * Net framework initialization callback. + * + * \param cb_arg Callback argument. + * \param rc 0 if net framework initialized successfully or negative errno if it failed. + */ +typedef void (*spdk_net_init_cb)(void *cb_arg, int rc); + +/** + * Net framework finish callback. + * + * \param cb_arg Callback argument. + */ +typedef void (*spdk_net_fini_cb)(void *cb_arg); + +void spdk_net_framework_init_next(int rc); + /** * Start all registered frameworks. * * \return 0 on success. */ -int spdk_net_framework_start(void); +void spdk_net_framework_start(spdk_net_init_cb cb_fn, void *cb_arg); + +void spdk_net_framework_fini_next(void); /** * Stop all registered frameworks. */ -void spdk_net_framework_fini(void); +void spdk_net_framework_fini(spdk_net_fini_cb cb_fn, void *cb_arg); #ifdef __cplusplus } diff --git a/lib/event/subsystems/net/net.c b/lib/event/subsystems/net/net.c index 9355514f2..62d65dbdb 100644 --- a/lib/event/subsystems/net/net.c +++ b/lib/event/subsystems/net/net.c @@ -63,21 +63,28 @@ static struct spdk_subsystem g_spdk_subsystem_interface = { SPDK_SUBSYSTEM_REGISTER(g_spdk_subsystem_interface); +static void +spdk_net_start_complete(void *cb_arg, int rc) +{ + spdk_subsystem_init_next(rc); +} + static void spdk_net_subsystem_start(void) { - int rc; + spdk_net_framework_start(spdk_net_start_complete, NULL); +} - rc = spdk_net_framework_start(); - - spdk_subsystem_init_next(rc); +static void +spdk_net_fini_done(void *cb_arg) +{ + spdk_subsystem_fini_next(); } static void spdk_net_subsystem_fini(void) { - spdk_net_framework_fini(); - spdk_subsystem_fini_next(); + spdk_net_framework_fini(spdk_net_fini_done, NULL); } static struct spdk_subsystem g_spdk_subsystem_net_framework = { diff --git a/lib/sock/net_framework.c b/lib/sock/net_framework.c index 5d5a568fb..0a205c511 100644 --- a/lib/sock/net_framework.c +++ b/lib/sock/net_framework.c @@ -38,29 +38,70 @@ static STAILQ_HEAD(, spdk_net_framework) g_net_frameworks = STAILQ_HEAD_INITIALIZER(g_net_frameworks); -int spdk_net_framework_start(void) -{ - struct spdk_net_framework *net_framework = NULL; - int rc; +static spdk_net_init_cb g_init_cb_fn = NULL; +static void *g_init_cb_arg = NULL; - STAILQ_FOREACH_FROM(net_framework, &g_net_frameworks, link) { - rc = net_framework->init(); - if (rc != 0) { - SPDK_ERRLOG("Net framework %s failed to initalize\n", net_framework->name); - return rc; - } +static spdk_net_fini_cb g_fini_cb_fn = NULL; +static void *g_fini_cb_arg = NULL; + +struct spdk_net_framework *g_next_net_framework = NULL; + +void +spdk_net_framework_init_next(int rc) +{ + if (rc) { + SPDK_ERRLOG("Net framework %s failed to initalize with error %d\n", g_next_net_framework->name, rc); + g_init_cb_fn(g_init_cb_arg, rc); + return; } - return 0; + if (g_next_net_framework == NULL) { + g_next_net_framework = STAILQ_FIRST(&g_net_frameworks); + } else { + g_next_net_framework = STAILQ_NEXT(g_next_net_framework, link); + } + + if (g_next_net_framework == NULL) { + g_init_cb_fn(g_init_cb_arg, 0); + return; + } + + g_next_net_framework->init(); } -void spdk_net_framework_fini(void) +void +spdk_net_framework_start(spdk_net_init_cb cb_fn, void *cb_arg) { - struct spdk_net_framework *net_framework = NULL; + g_init_cb_fn = cb_fn; + g_init_cb_arg = cb_arg; - STAILQ_FOREACH_FROM(net_framework, &g_net_frameworks, link) { - net_framework->fini(); + spdk_net_framework_init_next(0); +} + +void +spdk_net_framework_fini_next(void) +{ + if (g_next_net_framework == NULL) { + g_next_net_framework = STAILQ_FIRST(&g_net_frameworks); + } else { + g_next_net_framework = STAILQ_NEXT(g_next_net_framework, link); } + + if (g_next_net_framework == NULL) { + g_fini_cb_fn(g_fini_cb_arg); + return; + } + + g_next_net_framework->fini(); +} + +void +spdk_net_framework_fini(spdk_net_fini_cb cb_fn, void *cb_arg) +{ + g_fini_cb_fn = cb_fn; + g_fini_cb_arg = cb_arg; + + spdk_net_framework_fini_next(); } void