1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
Not upstream yet
--- a/src/api/tcpip.c
+++ b/src/api/tcpip.c
@@ -166,6 +166,11 @@
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
@@ -590,6 +595,49 @@
}
/**
+ * 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:
* - initialize all sub modules
--- a/src/include/lwip/priv/tcpip_priv.h
+++ b/src/include/lwip/priv/tcpip_priv.h
@@ -123,7 +123,8 @@
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_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 {
--- a/src/include/lwip/tcpip.h
+++ b/src/include/lwip/tcpip.h
@@ -81,6 +81,7 @@
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
*/
|