diff --git a/src/api/api_lib.c b/src/api/api_lib.c index 5b802744..b4244a43 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -220,7 +220,7 @@ netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, msg.function = do_newconn; msg.msg.msg.n.proto = proto; msg.msg.conn = conn; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); if ( conn->err != ERR_OK ) { sys_sem_free(conn->sem); @@ -258,7 +258,7 @@ netconn_delete(struct netconn *conn) msg.function = do_delconn; msg.msg.conn = conn; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); /* Drain the recvmbox. */ if (conn->recvmbox != SYS_MBOX_NULL) { @@ -362,7 +362,7 @@ netconn_bind(struct netconn *conn, struct ip_addr *addr, u16_t port) msg.msg.conn = conn; msg.msg.msg.bc.ipaddr = addr; msg.msg.msg.bc.port = port; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return conn->err; } @@ -384,6 +384,7 @@ netconn_connect(struct netconn *conn, struct ip_addr *addr, u16_t port) msg.msg.conn = conn; msg.msg.msg.bc.ipaddr = addr; msg.msg.msg.bc.port = port; + /* This is the only function which need to not block tcpip_thread */ tcpip_apimsg(&msg); return conn->err; } @@ -397,7 +398,7 @@ netconn_disconnect(struct netconn *conn) msg.function = do_disconnect; msg.msg.conn = conn; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return conn->err; } @@ -411,7 +412,7 @@ netconn_listen(struct netconn *conn) msg.function = do_listen; msg.msg.conn = conn; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return conn->err; } @@ -512,7 +513,7 @@ netconn_recv(struct netconn *conn) } else { msg.msg.msg.r.len = 1; } - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); #endif /* LWIP_TCP */ } else { #if (LWIP_UDP || LWIP_RAW) @@ -562,7 +563,7 @@ netconn_send(struct netconn *conn, struct netbuf *buf) msg.function = do_send; msg.msg.conn = conn; msg.msg.msg.b = buf; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return conn->err; } @@ -605,7 +606,7 @@ netconn_write(struct netconn *conn, const void *dataptr, u16_t size, u8_t copy) LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_write: writing %d bytes (%d)\n", len, copy)); msg.msg.msg.w.len = len; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); if (conn->err == ERR_OK) { dataptr = (void *)((u8_t *)dataptr + len); size -= len; @@ -633,7 +634,7 @@ netconn_close(struct netconn *conn) again: msg.function = do_close; msg.msg.conn = conn; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); if (conn->err == ERR_MEM && conn->sem != SYS_SEM_NULL) { sys_sem_wait(conn->sem); goto again; @@ -662,7 +663,7 @@ netconn_join_leave_group (struct netconn *conn, msg.msg.msg.jl.multiaddr = multiaddr; msg.msg.msg.jl.interface = interface; msg.msg.msg.jl.join_or_leave = join_or_leave; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return conn->err; } #endif /* LWIP_IGMP */ diff --git a/src/api/api_msg.c b/src/api/api_msg.c index bc8c101a..c4b81fa0 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -340,7 +340,7 @@ do_newconn(struct api_msg_msg *msg) /* Is this an error condition? Should it be deleted? */ /* We currently just are happy and return. */ - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } void @@ -388,7 +388,7 @@ do_delconn(struct api_msg_msg *msg) } if (msg->conn->mbox != SYS_MBOX_NULL) { - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } } @@ -422,7 +422,7 @@ do_bind(struct api_msg_msg *msg) } } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } #if LWIP_TCP @@ -493,7 +493,7 @@ do_disconnect(struct api_msg_msg *msg) udp_disconnect(msg->conn->pcb.udp); } #endif /* LWIP_UDP */ - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } void @@ -521,7 +521,7 @@ do_listen(struct api_msg_msg *msg) } } #endif /* LWIP_TCP */ - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } void @@ -553,7 +553,7 @@ do_send(struct api_msg_msg *msg) } } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } void @@ -568,7 +568,7 @@ do_recv(struct api_msg_msg *msg) } } #endif /* LWIP_TCP */ - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } void @@ -606,7 +606,7 @@ do_write(struct api_msg_msg *msg) } } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } void @@ -623,7 +623,7 @@ do_close(struct api_msg_msg *msg) } } #endif /* LWIP_TCP */ - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } #if LWIP_IGMP @@ -647,7 +647,7 @@ do_join_leave_group(struct api_msg_msg *msg) } } } - sys_mbox_post(msg->conn->mbox, NULL); + TCPIP_APIMSG_ACK(msg); } #endif /* LWIP_IGMP */ diff --git a/src/api/netifapi.c b/src/api/netifapi.c index 67b6bb33..e7e205a9 100644 --- a/src/api/netifapi.c +++ b/src/api/netifapi.c @@ -56,7 +56,7 @@ netifapi_netif_add(struct netif *netif, msg.msg.add.state = state; msg.msg.add.init = init; msg.msg.add.input = input; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return msg.err; } @@ -72,7 +72,7 @@ netifapi_netif_remove(struct netif *netif) struct netifapi_msg msg; msg.type = NETIFAPI_MSG_NETIF_REMOVE; msg.netif = netif; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return msg.err; } @@ -88,7 +88,7 @@ netifapi_dhcp_start(struct netif *netif) struct netifapi_msg msg; msg.type = NETIFAPI_MSG_DHCP_START; msg.netif = netif; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return msg.err; } @@ -104,7 +104,7 @@ netifapi_dhcp_stop(struct netif *netif) struct netifapi_msg msg; msg.type = NETIFAPI_MSG_DHCP_STOP; msg.netif = netif; - tcpip_apimsg(&msg); + TCPIP_APIMSG(&msg); return msg.err; } diff --git a/src/api/sockets.c b/src/api/sockets.c index 2d8fe802..39909d0d 100644 --- a/src/api/sockets.c +++ b/src/api/sockets.c @@ -539,6 +539,26 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags, ((tolen == sizeof(struct sockaddr_in)) && ((((struct sockaddr_in *)to)->sin_family) == AF_INET)))); +#if LWIP_TCPIP_CORE_LOCKING + { struct pbuf* p; + + p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (p == NULL) { + err = ERR_MEM; + } else { + p->payload = (void*)data; + p->len = p->tot_len = size; + + remote_addr.addr = ((struct sockaddr_in *)to)->sin_addr.s_addr; + + LOCK_TCPIP_CORE(); + err = sock->conn->err = udp_sendto(sock->conn->pcb.udp, p, &remote_addr, ntohs(((struct sockaddr_in *)to)->sin_port)); + UNLOCK_TCPIP_CORE(); + + pbuf_free(p); + } + } +#else /* initialize a buffer */ buf.p = buf.ptr = NULL; if (to) { @@ -568,7 +588,7 @@ lwip_sendto(int s, const void *data, int size, unsigned int flags, if (buf.p != NULL) { pbuf_free(buf.p); } - +#endif /* LWIP_TCPIP_CORE_LOCKING */ sock_set_errno(sock, err_to_errno(err)); return (err==ERR_OK?size:-1); } diff --git a/src/api/tcpip.c b/src/api/tcpip.c index fd107a36..71665ee0 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -53,6 +53,11 @@ static void (* tcpip_init_done)(void *arg) = NULL; static void *tcpip_init_done_arg = NULL; static sys_mbox_t mbox = SYS_MBOX_NULL; +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +sys_sem_t lock_tcpip_core = 0; +#endif /* LWIP_TCPIP_CORE_LOCKING */ + #if LWIP_TCP static int tcpip_tcp_timer_active = 0; @@ -206,6 +211,7 @@ tcpip_thread(void *arg) sys_timeout( IGMP_TMR_INTERVAL, igmp_timer, NULL); #endif /* LWIP_IGMP */ + LOCK_TCPIP_CORE(); while (1) { /* MAIN Loop */ sys_mbox_fetch(mbox, (void *)&msg); switch (msg->type) { @@ -327,6 +333,18 @@ tcpip_apimsg(struct api_msg *apimsg) return ERR_VAL; } +#if LWIP_TCPIP_CORE_LOCKING +err_t +tcpip_apimsg_lock(struct api_msg *apimsg) +{ + LOCK_TCPIP_CORE(); + apimsg->function(&(apimsg->msg)); + UNLOCK_TCPIP_CORE(); + return ERR_OK; + +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ + #if LWIP_NETIF_API err_t tcpip_netifapi(struct netifapi_msg* netifapimsg) { @@ -367,6 +385,10 @@ tcpip_init(void (* initfunc)(void *), void *arg) tcpip_init_done = initfunc; tcpip_init_done_arg = arg; mbox = sys_mbox_new(); +#if LWIP_TCPIP_CORE_LOCKING + lock_tcpip_core = sys_sem_new(1); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + sys_thread_new(tcpip_thread, NULL, TCPIP_THREAD_PRIO); } diff --git a/src/core/sys.c b/src/core/sys.c index 71bb1c90..a12c8d3b 100644 --- a/src/core/sys.c +++ b/src/core/sys.c @@ -34,6 +34,7 @@ #include "lwip/opt.h" #include "lwip/def.h" #include "lwip/memp.h" +#include "lwip/tcpip.h" #if (NO_SYS == 0) @@ -67,10 +68,14 @@ sys_mbox_fetch(sys_mbox_t mbox, void **msg) timeouts = sys_arch_timeouts(); if (!timeouts || !timeouts->next) { + UNLOCK_TCPIP_CORE(); time = sys_arch_mbox_fetch(mbox, msg, 0); + LOCK_TCPIP_CORE(); } else { if (timeouts->next->time > 0) { + UNLOCK_TCPIP_CORE(); time = sys_arch_mbox_fetch(mbox, msg, timeouts->next->time); + LOCK_TCPIP_CORE(); } else { time = SYS_ARCH_TIMEOUT; } diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 4b91c86c..bc5f0fed 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -474,6 +474,11 @@ a lot of data that needs to be copied, this should be set high. */ #define DEFAULT_THREAD_PRIO 1 #endif +/* ---------- Sequential layer options */ +/* EXPERIMENTAL, Don't use it if you're not an active lwIP project member */ +#ifndef LWIP_TCPIP_CORE_LOCKING +#define LWIP_TCPIP_CORE_LOCKING 0 +#endif /* ---------- Socket options ---------- */ /* Enable BSD-style sockets functions names */ diff --git a/src/include/lwip/tcpip.h b/src/include/lwip/tcpip.h index 5f8e9d56..977c6f18 100644 --- a/src/include/lwip/tcpip.h +++ b/src/include/lwip/tcpip.h @@ -40,8 +40,25 @@ extern "C" { #endif +#if LWIP_TCPIP_CORE_LOCKING +/** The global semaphore to lock the stack. */ +extern sys_sem_t lock_tcpip_core; +#define LOCK_TCPIP_CORE() sys_sem_wait(lock_tcpip_core) +#define UNLOCK_TCPIP_CORE() sys_sem_signal(lock_tcpip_core) +#define TCPIP_APIMSG(m) tcpip_apimsg_lock(m) +#define TCPIP_APIMSG_ACK(m) +#else +#define LOCK_TCPIP_CORE() +#define UNLOCK_TCPIP_CORE() +#define TCPIP_APIMSG(m) tcpip_apimsg(m) +#define TCPIP_APIMSG_ACK(m) sys_mbox_post(m->conn->mbox, NULL) +#endif /* LWIP_TCPIP_CORE_LOCKING */ + void tcpip_init(void (* tcpip_init_done)(void *), void *arg); err_t tcpip_apimsg(struct api_msg *apimsg); +#if LWIP_TCPIP_CORE_LOCKING +err_t tcpip_apimsg_lock(struct api_msg *apimsg); +#endif /* LWIP_TCPIP_CORE_LOCKING */ #if ETHARP_TCPIP_INPUT err_t tcpip_input(struct pbuf *p, struct netif *inp); #endif /* ETHARP_TCPIP_INPUT */