diff --git a/CHANGELOG b/CHANGELOG index 8e6da0f3..097d85c2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,19 @@ HISTORY ++ New features: + 2008-01-05 Frédéric Bernon + * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: + Introduce changes for task #7490 "Add return value to sys_mbox_post" with some + modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which + indicate the number of pointers query by the mailbox. There is three defines + in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the + netconn::acceptmbox. Port maintainers, you can decide to just add this new + parameter in your implementation, but to ignore it to keep the previous behavior. + The new sys_mbox_trypost function return a value to know if the mailbox is + full or if the message is posted. Take a look to sys_arch.txt for more details. + This new function is used in tcpip_input (so, can be called in an interrupt + context since the function is not blocking), and in recv_udp and recv_raw. + 2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the diff --git a/doc/sys_arch.txt b/doc/sys_arch.txt index 77a52424..970f19f6 100644 --- a/doc/sys_arch.txt +++ b/doc/sys_arch.txt @@ -69,9 +69,12 @@ The following functions must be implemented by the sys_arch: Notice that lwIP implements a function with a similar name, sys_sem_wait(), that uses the sys_arch_sem_wait() function. -- sys_mbox_t sys_mbox_new(void) +- sys_mbox_t sys_mbox_new(int size) - Creates an empty mailbox. + Creates an empty mailbox for maximum "size" elements. Elements stored + in mailboxes are pointers. You have to define macros "_MBOX_SIZE" + in your lwipopts.h, or ignore this parameter in your implementation + and use a default size. - void sys_mbox_free(sys_mbox_t mbox) @@ -81,7 +84,13 @@ The following functions must be implemented by the sys_arch: - void sys_mbox_post(sys_mbox_t mbox, void *msg) - Posts the "msg" to the mailbox. + Posts the "msg" to the mailbox. This function have to block until + the "msg" is really posted. + +- err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg) + + Try to post the "msg" to the mailbox. Returns ERR_MEM if this one + is full, else, ERR_OK if the "msg" is posted. - u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout) diff --git a/src/api/api_lib.c b/src/api/api_lib.c index f5a16e8f..77f715b1 100644 --- a/src/api/api_lib.c +++ b/src/api/api_lib.c @@ -65,8 +65,7 @@ * NULL on memory error */ struct netconn* -netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, - void (*callback)(struct netconn *, enum netconn_evt, u16_t len)) +netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) { struct netconn *conn; struct api_msg msg; diff --git a/src/api/api_msg.c b/src/api/api_msg.c index 4add74b9..fa762fdc 100644 --- a/src/api/api_msg.c +++ b/src/api/api_msg.c @@ -98,7 +98,9 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, SYS_ARCH_INC(conn->recv_avail, p->tot_len); /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len); - sys_mbox_post(conn->recvmbox, buf); + if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + } } return 0; /* do not eat the packet */ @@ -153,7 +155,10 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, SYS_ARCH_INC(conn->recv_avail, p->tot_len); /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, p->tot_len); - sys_mbox_post(conn->recvmbox, buf); + if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) { + netbuf_delete(buf); + return; + } } #endif /* LWIP_UDP */ @@ -348,7 +353,11 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) /* Register event with callback */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - sys_mbox_post(conn->acceptmbox, newconn); + if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) { + /** @todo call here a "netconn_free" */ + LWIP_ASSERT("accept_function: not yet implemented!", 0); + return ERR_MEM; + } return ERR_OK; } #endif /* LWIP_TCP */ @@ -446,8 +455,7 @@ do_newconn(struct api_msg_msg *msg) * NULL on memory error */ struct netconn* -netconn_alloc(enum netconn_type t, - void (*callback)(struct netconn *, enum netconn_evt, u16_t len)) +netconn_alloc(enum netconn_type t, netconn_callback callback) { struct netconn *conn; @@ -460,11 +468,11 @@ netconn_alloc(enum netconn_type t, conn->type = t; conn->pcb.tcp = NULL; - if ((conn->mbox = sys_mbox_new()) == SYS_MBOX_NULL) { + if ((conn->mbox = sys_mbox_new(1)) == SYS_MBOX_NULL) { memp_free(MEMP_NETCONN, conn); return NULL; } - if ((conn->recvmbox = sys_mbox_new()) == SYS_MBOX_NULL) { + if ((conn->recvmbox = sys_mbox_new(DEFAULT_RECVMBOX_SIZE)) == SYS_MBOX_NULL) { sys_mbox_free(conn->mbox); memp_free(MEMP_NETCONN, conn); return NULL; @@ -732,7 +740,7 @@ do_listen(struct api_msg_msg *msg) msg->conn->recvmbox = NULL; } if (msg->conn->acceptmbox == SYS_MBOX_NULL) { - if ((msg->conn->acceptmbox = sys_mbox_new()) == SYS_MBOX_NULL) { + if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) { msg->conn->err = ERR_MEM; } } diff --git a/src/api/tcpip.c b/src/api/tcpip.c index 65faaa88..e68c805f 100644 --- a/src/api/tcpip.c +++ b/src/api/tcpip.c @@ -332,7 +332,10 @@ tcpip_input(struct pbuf *p, struct netif *inp) msg->type = TCPIP_MSG_INPKT; msg->msg.inp.p = p; msg->msg.inp.netif = inp; - sys_mbox_post(mbox, msg); + if (sys_mbox_trypost(mbox, msg) != ERR_OK) { + memp_free(MEMP_TCPIP_MSG_INPKT, msg); + return ERR_MEM; + } return ERR_OK; } return ERR_VAL; @@ -499,7 +502,7 @@ tcpip_init(void (* initfunc)(void *), void *arg) tcpip_init_done = initfunc; tcpip_init_done_arg = arg; - mbox = sys_mbox_new(); + mbox = sys_mbox_new(TCPIP_MBOX_SIZE); #if LWIP_TCPIP_CORE_LOCKING lock_tcpip_core = sys_sem_new(1); #endif /* LWIP_TCPIP_CORE_LOCKING */ diff --git a/src/include/lwip/api.h b/src/include/lwip/api.h index 0195df88..4e8a1b4b 100644 --- a/src/include/lwip/api.h +++ b/src/include/lwip/api.h @@ -98,6 +98,10 @@ struct ip_pcb; struct tcp_pcb; struct udp_pcb; struct raw_pcb; +struct netconn; + +/** A callback prototype to inform about events for a netconn */ +typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); /** A netconn descriptor */ struct netconn { @@ -148,7 +152,7 @@ struct netconn { u8_t write_delayed; #endif /* LWIP_TCPIP_CORE_LOCKING */ /** A callback function that is informed about events for this netconn */ - void (* callback)(struct netconn *, enum netconn_evt, u16_t len); + netconn_callback callback; }; /* Register an Network connection event */ @@ -161,7 +165,7 @@ struct netconn { #define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, - void (*callback)(struct netconn *, enum netconn_evt, u16_t len)); + netconn_callback callback); err_t netconn_delete (struct netconn *conn); enum netconn_type netconn_type (struct netconn *conn); diff --git a/src/include/lwip/api_msg.h b/src/include/lwip/api_msg.h index 1691a889..e6cd1590 100644 --- a/src/include/lwip/api_msg.h +++ b/src/include/lwip/api_msg.h @@ -148,9 +148,7 @@ void do_join_leave_group( struct api_msg_msg *msg); void do_gethostbyname(void *arg); #endif /* LWIP_DNS */ -struct netconn* netconn_alloc( - enum netconn_type t, - void (*callback)(struct netconn *, enum netconn_evt, u16_t len)); +struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); #ifdef __cplusplus } diff --git a/src/include/lwip/opt.h b/src/include/lwip/opt.h index 9ec3a426..461e6f35 100644 --- a/src/include/lwip/opt.h +++ b/src/include/lwip/opt.h @@ -874,6 +874,15 @@ #define TCPIP_THREAD_PRIO 1 #endif +/** + * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when tcpip_init is called. + */ +#ifndef TCPIP_MBOX_SIZE +#define TCPIP_MBOX_SIZE 0 +#endif + /** * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. */ @@ -949,6 +958,24 @@ #define DEFAULT_THREAD_PRIO 1 #endif +/** + * DEFAULT_RECVMBOX_SIZE: The mailbox size for the incoming packets. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the recvmbox is created. + */ +#ifndef DEFAULT_RECVMBOX_SIZE +#define DEFAULT_RECVMBOX_SIZE 0 +#endif + +/** + * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. + * The queue size value itself is platform-dependent, but is passed to + * sys_mbox_new() when the acceptmbox is created. + */ +#ifndef DEFAULT_ACCEPTMBOX_SIZE +#define DEFAULT_ACCEPTMBOX_SIZE 0 +#endif + /* ---------------------------------------------- ---------- Sequential layer options ---------- diff --git a/src/include/lwip/sys.h b/src/include/lwip/sys.h index 6927886e..ce73beac 100644 --- a/src/include/lwip/sys.h +++ b/src/include/lwip/sys.h @@ -56,9 +56,11 @@ struct sys_timeo {u8_t dummy;}; #define sys_sem_wait_timeout(s,t) #define sys_arch_sem_wait(s,t) #define sys_sem_free(s) -#define sys_mbox_new() 0 +#define sys_mbox_new(s) 0 #define sys_mbox_fetch(m,d) +#define sys_mbox_tryfetch(m,d) #define sys_mbox_post(m,d) +#define sys_mbox_trypost(m,d) #define sys_mbox_free(m) #define sys_thread_new(n,t,a,s,p) @@ -73,6 +75,7 @@ struct sys_timeo {u8_t dummy;}; */ #define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT +#include "lwip/err.h" #include "arch/sys_arch.h" typedef void (* sys_timeout_handler)(void *arg); @@ -121,8 +124,9 @@ u32_t sys_jiffies(void); /* since power up. */ #endif /* Mailbox functions. */ -sys_mbox_t sys_mbox_new(void); +sys_mbox_t sys_mbox_new(int size); void sys_mbox_post(sys_mbox_t mbox, void *msg); +err_t sys_mbox_trypost(sys_mbox_t mbox, void *msg); u32_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout); #ifndef sys_arch_mbox_tryfetch /* Allow port to override with a macro */ u32_t sys_arch_mbox_tryfetch(sys_mbox_t mbox, void **msg);