From 9dca4a02115ee0567f8b539ea97a4f2e197b770a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joan=20Lled=C3=B3?= Date: Sun, 19 May 2019 11:08:45 +0200 Subject: [PATCH] New function tcpip_callback_wait() * Call a function inside the tcpip thread and block the calling thread until the callback finishes. Signed-off-by: Simon Goldschmidt --- src/api/tcpip.c | 48 ++++++++++++++++++++++++++++++ src/include/lwip/priv/tcpip_priv.h | 8 ++++- src/include/lwip/tcpip.h | 1 + 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/api/tcpip.c b/src/api/tcpip.c index b0382e83..fc25df9c 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -166,6 +166,11 @@ tcpip_thread_handle_msg(struct tcpip_msg *msg) msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg); sys_sem_signal(msg->msg.api_call.sem); break; + case TCPIP_MSG_CALLBACK_STATIC_WAIT: + LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK WAIT message %p\n", (void *)msg)); + msg->msg.cb_wait.function(msg->msg.cb_wait.ctx); + sys_sem_signal(msg->msg.cb_wait.sem); + break; #endif /* !LWIP_TCPIP_CORE_LOCKING */ #if !LWIP_TCPIP_CORE_LOCKING_INPUT @@ -589,6 +594,49 @@ tcpip_callbackmsg_trycallback_fromisr(struct tcpip_callback_msg *msg) return sys_mbox_trypost_fromisr(&tcpip_mbox, msg); } +/** + * Sends a message to TCPIP thread to call a function. Caller thread blocks + * until the function returns. + * It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or + * LWIP_NETCONN_SEM_PER_THREAD. + * If not, a semaphore is created and destroyed on every call which is usually + * an expensive/slow operation. + * + * @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 + */ +err_t +tcpip_callback_wait(tcpip_callback_fn function, void *ctx) +{ +#if LWIP_TCPIP_CORE_LOCKING + LOCK_TCPIP_CORE(); + function(ctx); + UNLOCK_TCPIP_CORE(); + return ERR_OK; +#else /* LWIP_TCPIP_CORE_LOCKING */ + err_t err; + sys_sem_t sem; + struct tcpip_msg msg; + + LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(tcpip_mbox)); + + err = sys_sem_new(&sem, 0); + if (err != ERR_OK) { + return err; + } + + msg.type = TCPIP_MSG_CALLBACK_STATIC_WAIT; + msg.msg.cb_wait.function = function; + msg.msg.cb_wait.ctx = ctx; + msg.msg.cb_wait.sem = &sem; + sys_mbox_post(&tcpip_mbox, &msg); + sys_arch_sem_wait(&sem, 0); + sys_sem_free(&sem); + return ERR_OK; +#endif /* LWIP_TCPIP_CORE_LOCKING */ +} + /** * @ingroup lwip_os * Initialize this module: diff --git a/src/include/lwip/priv/tcpip_priv.h b/src/include/lwip/priv/tcpip_priv.h index 74be634b..bfa88ff6 100644 --- a/src/include/lwip/priv/tcpip_priv.h +++ b/src/include/lwip/priv/tcpip_priv.h @@ -123,7 +123,8 @@ enum tcpip_msg_type { TCPIP_MSG_UNTIMEOUT, #endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ TCPIP_MSG_CALLBACK, - TCPIP_MSG_CALLBACK_STATIC + TCPIP_MSG_CALLBACK_STATIC, + TCPIP_MSG_CALLBACK_STATIC_WAIT }; struct tcpip_msg { @@ -139,6 +140,11 @@ struct tcpip_msg { struct tcpip_api_call_data *arg; sys_sem_t *sem; } api_call; + struct { + tcpip_callback_fn function; + void *ctx; + sys_sem_t *sem; + } cb_wait; #endif /* LWIP_TCPIP_CORE_LOCKING */ #if !LWIP_TCPIP_CORE_LOCKING_INPUT struct { diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index 0b8880a9..30ce4fef 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -81,6 +81,7 @@ err_t tcpip_input(struct pbuf *p, struct netif *inp); err_t tcpip_try_callback(tcpip_callback_fn function, void *ctx); err_t tcpip_callback(tcpip_callback_fn function, void *ctx); +err_t tcpip_callback_wait(tcpip_callback_fn function, void *ctx); /** @ingroup lwip_os * @deprecated use tcpip_try_callback() or tcpip_callback() instead */