From 68d36f19f0365f0d58b9b12c5748aeac2700b9d1 Mon Sep 17 00:00:00 2001 From: Dirk Ziegelmeier Date: Wed, 21 Jun 2017 13:42:54 +0200 Subject: [PATCH] Implement LWIP core locking support in tcpip_callback_with_block() Created two new functions for API cleanup: tcpip_callback() that blocks until message is posted, cannot be called from IRQs. tcpip_try_callback() that does not block and just tries to post a message. Can be called from IRQs. Add compatibility #define tcpip_callback_with_block() that maps to these two functions according to "block" parameter. --- src/api/tcpip.c | 62 ++++++++++++++++++++++++++++++++++------ src/include/lwip/tcpip.h | 10 +++---- 2 files changed, 57 insertions(+), 15 deletions(-) diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 645e5ae0..f2ca0f04 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -256,14 +256,61 @@ tcpip_input(struct pbuf *p, struct netif *inp) * tcpip_thread for easy access synchronization. * A function called in that way may access lwIP core code * without fearing concurrent access. + * When LWIP_TCPIP_CORE_LOCKING is enabled, the specified + * function is called after the lwIP core lock was aquired, + * no message / mbox interaction is needed. + * Blocks until the request is posted. + * Must not be called from interrupt context! * * @param function the function to call * @param ctx parameter passed to f - * @param block 1 to block until the request is posted, 0 to non-blocking mode * @return ERR_OK if the function was called, another err_t if not + * + * @see tcpip_try_callback */ err_t -tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) +tcpip_callback(tcpip_callback_fn function, void *ctx) +{ +#if LWIP_TCPIP_CORE_LOCKING + LOCK_TCPIP_CORE(); + function(ctx); + UNLOCK_TCPIP_CORE(); +#else + struct tcpip_msg *msg; + + LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); + + msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); + if (msg == NULL) { + return ERR_MEM; + } + + msg->type = TCPIP_MSG_CALLBACK; + msg->msg.cb.function = function; + msg->msg.cb.ctx = ctx; + + sys_mbox_post(&mbox, msg); +#endif + return ERR_OK; +} + +/** + * Call a specific function in the thread context of + * tcpip_thread for easy access synchronization. + * A function called in that way may access lwIP core code + * without fearing concurrent access. + * Does NOT block when the request cannot be posted because the + * mbox is full, but returns ERR_MEM instead. + * Can be called from interrupt context. + * + * @param function the function to call + * @param ctx parameter passed to f + * @return ERR_OK if the function was called, another err_t if not + * + * @see tcpip_callback + */ +err_t +tcpip_try_callback(tcpip_callback_fn function, void *ctx) { struct tcpip_msg *msg; @@ -277,13 +324,10 @@ tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) msg->type = TCPIP_MSG_CALLBACK; msg->msg.cb.function = function; msg->msg.cb.ctx = ctx; - if (block) { - sys_mbox_post(&mbox, msg); - } else { - if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_API, msg); - return ERR_MEM; - } + + if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_API, msg); + return ERR_MEM; } return ERR_OK; } diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index a6c826ad..d640dd7a 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -77,12 +77,10 @@ void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn); err_t tcpip_input(struct pbuf *p, struct netif *inp); -err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); -/** - * @ingroup lwip_os - * @see tcpip_callback_with_block - */ -#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) +err_t tcpip_try_callback(tcpip_callback_fn function, void *ctx); +err_t tcpip_callback(tcpip_callback_fn function, void *ctx); +/* for compatibility with older lwIP versions */ +#define tcpip_callback_with_block(function, ctx, block) ((block != 0)? tcpip_callback(function, ctx) : tcpip_try_callback(function, ctx)) struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg);