mirror of
https://git.savannah.nongnu.org/git/lwip.git
synced 2026-08-09 17:13:49 +08:00
task #10139 (Prefer statically allocated memory): converted mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; converted sys_mbox_new/sys_sem_new to take pointers and return err_t; task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use binary semaphores instead of mutexes - as before)
This commit is contained in:
@@ -77,11 +77,11 @@ netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_cal
|
||||
msg.msg.conn = conn;
|
||||
if (TCPIP_APIMSG(&msg) != ERR_OK) {
|
||||
LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL);
|
||||
LWIP_ASSERT("conn has no op_completed", conn->op_completed != SYS_SEM_NULL);
|
||||
LWIP_ASSERT("conn has no recvmbox", conn->recvmbox != SYS_MBOX_NULL);
|
||||
LWIP_ASSERT("conn->acceptmbox shouldn't exist", conn->acceptmbox == SYS_MBOX_NULL);
|
||||
sys_sem_free(conn->op_completed);
|
||||
sys_mbox_free(conn->recvmbox);
|
||||
LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed));
|
||||
LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox));
|
||||
LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox));
|
||||
sys_sem_free(&conn->op_completed);
|
||||
sys_mbox_free(&conn->recvmbox);
|
||||
memp_free(MEMP_NETCONN, conn);
|
||||
return NULL;
|
||||
}
|
||||
@@ -277,7 +277,7 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||
LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;);
|
||||
*new_conn = NULL;
|
||||
LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_accept: invalid acceptmbox", (conn->acceptmbox != SYS_MBOX_NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_accept: invalid acceptmbox", sys_mbox_valid(&conn->acceptmbox), return ERR_ARG;);
|
||||
|
||||
err = conn->last_err;
|
||||
if (ERR_IS_FATAL(err)) {
|
||||
@@ -287,12 +287,12 @@ netconn_accept(struct netconn *conn, struct netconn **new_conn)
|
||||
}
|
||||
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
if (sys_arch_mbox_fetch(conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
||||
if (sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, conn->recv_timeout) == SYS_ARCH_TIMEOUT) {
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
#else
|
||||
sys_arch_mbox_fetch(conn->acceptmbox, (void **)&newconn, 0);
|
||||
sys_arch_mbox_fetch(&conn->acceptmbox, (void **)&newconn, 0);
|
||||
#endif /* LWIP_SO_RCVTIMEO*/
|
||||
/* Register event with callback */
|
||||
API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0);
|
||||
@@ -335,12 +335,14 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
||||
LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;);
|
||||
*new_buf = NULL;
|
||||
LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;);
|
||||
LWIP_ERROR("netconn_accept: invalid recvmbox", (conn->recvmbox != SYS_MBOX_NULL), return ERR_CONN;);
|
||||
LWIP_ERROR("netconn_accept: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;);
|
||||
|
||||
err = conn->last_err;
|
||||
if (ERR_IS_FATAL(err)) {
|
||||
/* don't recv on fatal errors: this might block the application task
|
||||
waiting on recvmbox forever! */
|
||||
/* @todo: this does not allow us to fetch data that has been put into recvmbox
|
||||
before the fatal error occurred - is that a problem? */
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -355,13 +357,13 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
||||
}
|
||||
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
if (sys_arch_mbox_fetch(conn->recvmbox, (void **)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
||||
if (sys_arch_mbox_fetch(&conn->recvmbox, (void **)&p, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
||||
memp_free(MEMP_NETBUF, buf);
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
#else
|
||||
sys_arch_mbox_fetch(conn->recvmbox, (void **)&p, 0);
|
||||
sys_arch_mbox_fetch(&conn->recvmbox, (void **)&p, 0);
|
||||
#endif /* LWIP_SO_RCVTIMEO*/
|
||||
|
||||
if (p != NULL) {
|
||||
@@ -406,12 +408,12 @@ netconn_recv(struct netconn *conn, struct netbuf **new_buf)
|
||||
} else {
|
||||
#if (LWIP_UDP || LWIP_RAW)
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
if (sys_arch_mbox_fetch(conn->recvmbox, (void **)&buf, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
||||
if (sys_arch_mbox_fetch(&conn->recvmbox, (void **)&buf, conn->recv_timeout)==SYS_ARCH_TIMEOUT) {
|
||||
NETCONN_SET_SAFE_ERR(conn, ERR_TIMEOUT);
|
||||
return ERR_TIMEOUT;
|
||||
}
|
||||
#else
|
||||
sys_arch_mbox_fetch(conn->recvmbox, (void **)&buf, 0);
|
||||
sys_arch_mbox_fetch(&conn->recvmbox, (void **)&buf, 0);
|
||||
#endif /* LWIP_SO_RCVTIMEO*/
|
||||
LWIP_ASSERT("buf != NULL", buf != NULL);
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
||||
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_GET(conn->recv_avail, recv_avail);
|
||||
if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL) &&
|
||||
if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox) &&
|
||||
((recv_avail + (int)(p->tot_len)) <= conn->recv_bufsize)) {
|
||||
#else /* LWIP_SO_RCVBUF */
|
||||
if ((conn != NULL) && (conn->recvmbox != SYS_MBOX_NULL)) {
|
||||
@@ -118,7 +118,7 @@ recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p,
|
||||
buf->port = pcb->protocol;
|
||||
|
||||
len = q->tot_len;
|
||||
if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
|
||||
if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
|
||||
netbuf_delete(buf);
|
||||
return 0;
|
||||
} else {
|
||||
@@ -159,7 +159,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
|
||||
#if LWIP_SO_RCVBUF
|
||||
SYS_ARCH_GET(conn->recv_avail, recv_avail);
|
||||
if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL) ||
|
||||
if ((conn == NULL) || !sys_mbox_valid(&conn->recvmbox) ||
|
||||
((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) {
|
||||
#else /* LWIP_SO_RCVBUF */
|
||||
if ((conn == NULL) || (conn->recvmbox == SYS_MBOX_NULL)) {
|
||||
@@ -189,7 +189,7 @@ recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p,
|
||||
}
|
||||
|
||||
len = p->tot_len;
|
||||
if (sys_mbox_trypost(conn->recvmbox, buf) != ERR_OK) {
|
||||
if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) {
|
||||
netbuf_delete(buf);
|
||||
return;
|
||||
} else {
|
||||
@@ -222,7 +222,7 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||
if (conn == NULL) {
|
||||
return ERR_VAL;
|
||||
}
|
||||
if (conn->recvmbox == SYS_MBOX_NULL) {
|
||||
if (!sys_mbox_valid(&conn->recvmbox)) {
|
||||
/* recvmbox already deleted */
|
||||
if (p != NULL) {
|
||||
tcp_recved(pcb, p->tot_len);
|
||||
@@ -243,7 +243,7 @@ recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
|
||||
len = 0;
|
||||
}
|
||||
|
||||
if (sys_mbox_trypost(conn->recvmbox, p) != ERR_OK) {
|
||||
if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) {
|
||||
/* don't deallocate p: it is presented to us later again from tcp_fasttmr! */
|
||||
return ERR_MEM;
|
||||
} else {
|
||||
@@ -354,14 +354,14 @@ err_tcp(void *arg, err_t err)
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
|
||||
/* pass NULL-message to recvmbox to wake up pending recv */
|
||||
if (conn->recvmbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&conn->recvmbox)) {
|
||||
/* use trypost to prevent deadlock */
|
||||
sys_mbox_trypost(conn->recvmbox, NULL);
|
||||
sys_mbox_trypost(&conn->recvmbox, NULL);
|
||||
}
|
||||
/* pass NULL-message to acceptmbox to wake up pending accept */
|
||||
if (conn->acceptmbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&conn->acceptmbox)) {
|
||||
/* use trypost to preven deadlock */
|
||||
sys_mbox_trypost(conn->acceptmbox, NULL);
|
||||
sys_mbox_trypost(&conn->acceptmbox, NULL);
|
||||
}
|
||||
|
||||
if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) ||
|
||||
@@ -377,7 +377,7 @@ err_tcp(void *arg, err_t err)
|
||||
conn->current_msg->err = err;
|
||||
conn->current_msg = NULL;
|
||||
/* wake up the waiting task */
|
||||
sys_sem_signal(conn->op_completed);
|
||||
sys_sem_signal(&conn->op_completed);
|
||||
}
|
||||
} else {
|
||||
LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL);
|
||||
@@ -422,7 +422,7 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||||
#endif /* API_MSG_DEBUG */
|
||||
conn = (struct netconn *)arg;
|
||||
|
||||
if (conn->acceptmbox == SYS_MBOX_NULL) {
|
||||
if (!sys_mbox_valid(&conn->acceptmbox)) {
|
||||
LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n"));
|
||||
return ERR_VAL;
|
||||
}
|
||||
@@ -439,13 +439,13 @@ accept_function(void *arg, struct tcp_pcb *newpcb, err_t err)
|
||||
to the application thread */
|
||||
newconn->last_err = err;
|
||||
|
||||
if (sys_mbox_trypost(conn->acceptmbox, newconn) != ERR_OK) {
|
||||
if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) {
|
||||
/* When returning != ERR_OK, the pcb is aborted in tcp_process(),
|
||||
so do nothing here! */
|
||||
newconn->pcb.tcp = NULL;
|
||||
/* no need to drain since we know the recvmbox is empty. */
|
||||
sys_mbox_free(newconn->recvmbox);
|
||||
newconn->recvmbox = SYS_MBOX_NULL;
|
||||
sys_mbox_free(&newconn->recvmbox);
|
||||
sys_mbox_set_invalid(&newconn->recvmbox);
|
||||
netconn_free(newconn);
|
||||
return ERR_MEM;
|
||||
} else {
|
||||
@@ -587,20 +587,20 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((conn->op_completed = sys_sem_new(0)) == SYS_SEM_NULL) {
|
||||
if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) {
|
||||
memp_free(MEMP_NETCONN, conn);
|
||||
return NULL;
|
||||
}
|
||||
if ((conn->recvmbox = sys_mbox_new(size)) == SYS_MBOX_NULL) {
|
||||
sys_sem_free(conn->op_completed);
|
||||
if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) {
|
||||
sys_sem_free(&conn->op_completed);
|
||||
memp_free(MEMP_NETCONN, conn);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
conn->acceptmbox = SYS_MBOX_NULL;
|
||||
sys_mbox_set_invalid(&conn->acceptmbox);
|
||||
conn->state = NETCONN_NONE;
|
||||
/* initialize socket to -1 since 0 is a valid socket */
|
||||
#if LWIP_SOCKET
|
||||
/* initialize socket to -1 since 0 is a valid socket */
|
||||
conn->socket = -1;
|
||||
#endif /* LWIP_SOCKET */
|
||||
conn->callback = callback;
|
||||
@@ -608,9 +608,6 @@ netconn_alloc(enum netconn_type t, netconn_callback callback)
|
||||
#if LWIP_TCP
|
||||
conn->current_msg = NULL;
|
||||
conn->write_offset = 0;
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
conn->write_delayed = 0;
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
#endif /* LWIP_TCP */
|
||||
#if LWIP_SO_RCVTIMEO
|
||||
conn->recv_timeout = 0;
|
||||
@@ -633,12 +630,12 @@ netconn_free(struct netconn *conn)
|
||||
{
|
||||
LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL);
|
||||
LWIP_ASSERT("recvmbox must be deallocated before calling this function",
|
||||
conn->recvmbox == SYS_MBOX_NULL);
|
||||
!sys_mbox_valid(&conn->recvmbox));
|
||||
LWIP_ASSERT("acceptmbox must be deallocated before calling this function",
|
||||
conn->acceptmbox == SYS_MBOX_NULL);
|
||||
!sys_mbox_valid(&conn->acceptmbox));
|
||||
|
||||
sys_sem_free(conn->op_completed);
|
||||
conn->op_completed = SYS_SEM_NULL;
|
||||
sys_sem_free(&conn->op_completed);
|
||||
sys_sem_set_invalid(&conn->op_completed);
|
||||
|
||||
memp_free(MEMP_NETCONN, conn);
|
||||
}
|
||||
@@ -656,13 +653,12 @@ netconn_drain(struct netconn *conn)
|
||||
{
|
||||
void *mem;
|
||||
struct pbuf *p;
|
||||
sys_mbox_t mbox;
|
||||
|
||||
/* This runs in tcpip_thread, so we don't need to lock against rx packets */
|
||||
|
||||
/* Delete and drain the recvmbox. */
|
||||
mbox = conn->recvmbox;
|
||||
conn->recvmbox = SYS_MBOX_NULL;
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
while (sys_mbox_tryfetch(mbox, &mem) != SYS_MBOX_EMPTY) {
|
||||
if (sys_mbox_valid(&conn->recvmbox)) {
|
||||
while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) {
|
||||
if (conn->type == NETCONN_TCP) {
|
||||
if(mem != NULL) {
|
||||
p = (struct pbuf*)mem;
|
||||
@@ -676,14 +672,13 @@ netconn_drain(struct netconn *conn)
|
||||
netbuf_delete((struct netbuf *)mem);
|
||||
}
|
||||
}
|
||||
sys_mbox_free(mbox);
|
||||
sys_mbox_free(&conn->recvmbox);
|
||||
sys_mbox_set_invalid(&conn->recvmbox);
|
||||
}
|
||||
|
||||
/* Delete and drain the acceptmbox. */
|
||||
mbox = conn->acceptmbox;
|
||||
conn->acceptmbox = SYS_MBOX_NULL;
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
while (sys_mbox_tryfetch(mbox, &mem) != SYS_MBOX_EMPTY) {
|
||||
if (sys_mbox_valid(&conn->acceptmbox)) {
|
||||
while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) {
|
||||
/* Only tcp pcbs have an acceptmbox, so no need to check conn->type */
|
||||
/* pcb might be set to NULL already by err_tcp() */
|
||||
if (conn->pcb.tcp != NULL) {
|
||||
@@ -691,7 +686,8 @@ netconn_drain(struct netconn *conn)
|
||||
}
|
||||
netconn_delete((struct netconn *)mem);
|
||||
}
|
||||
sys_mbox_free(mbox);
|
||||
sys_mbox_free(&conn->acceptmbox);
|
||||
sys_mbox_set_invalid(&conn->acceptmbox);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -741,7 +737,7 @@ do_close_internal(struct netconn *conn)
|
||||
API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0);
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
/* wake up the application task */
|
||||
sys_sem_signal(conn->op_completed);
|
||||
sys_sem_signal(&conn->op_completed);
|
||||
} else {
|
||||
/* Closing failed, restore some of the callbacks */
|
||||
/* Closing of listen pcb will never fail! */
|
||||
@@ -811,8 +807,8 @@ do_delconn(struct api_msg_msg *msg)
|
||||
API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0);
|
||||
API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
}
|
||||
if (msg->conn->op_completed != SYS_SEM_NULL) {
|
||||
sys_sem_signal(msg->conn->op_completed);
|
||||
if (sys_sem_valid(&msg->conn->op_completed)) {
|
||||
sys_sem_signal(&msg->conn->op_completed);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -901,7 +897,7 @@ do_connected(void *arg, struct tcp_pcb *pcb, err_t err)
|
||||
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
|
||||
|
||||
if (was_blocking) {
|
||||
sys_sem_signal(conn->op_completed);
|
||||
sys_sem_signal(&conn->op_completed);
|
||||
}
|
||||
return ERR_OK;
|
||||
}
|
||||
@@ -962,7 +958,7 @@ do_connect(struct api_msg_msg *msg)
|
||||
break;
|
||||
}
|
||||
}
|
||||
sys_sem_signal(msg->conn->op_completed);
|
||||
sys_sem_signal(&msg->conn->op_completed);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1014,16 +1010,14 @@ do_listen(struct api_msg_msg *msg)
|
||||
msg->err = ERR_MEM;
|
||||
} else {
|
||||
/* delete the recvmbox and allocate the acceptmbox */
|
||||
if (msg->conn->recvmbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&msg->conn->recvmbox)) {
|
||||
/** @todo: should we drain the recvmbox here? */
|
||||
sys_mbox_free(msg->conn->recvmbox);
|
||||
msg->conn->recvmbox = SYS_MBOX_NULL;
|
||||
sys_mbox_free(&msg->conn->recvmbox);
|
||||
sys_mbox_set_invalid(&msg->conn->recvmbox);
|
||||
}
|
||||
msg->err = ERR_OK;
|
||||
if (msg->conn->acceptmbox == SYS_MBOX_NULL) {
|
||||
if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) {
|
||||
msg->err = ERR_MEM;
|
||||
}
|
||||
if (!sys_mbox_valid(&msg->conn->acceptmbox)) {
|
||||
msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE);
|
||||
}
|
||||
if (msg->err == ERR_OK) {
|
||||
msg->conn->state = NETCONN_LISTEN;
|
||||
@@ -1150,7 +1144,7 @@ do_writemore(struct netconn *conn)
|
||||
if (diff > 0xffffUL) { /* max_u16_t */
|
||||
len = 0xffff;
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
conn->write_delayed = 1;
|
||||
conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
|
||||
#endif
|
||||
} else {
|
||||
len = (u16_t)diff;
|
||||
@@ -1160,7 +1154,7 @@ do_writemore(struct netconn *conn)
|
||||
/* don't try to write more than sendbuf */
|
||||
len = available;
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
conn->write_delayed = 1;
|
||||
conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1193,7 +1187,7 @@ do_writemore(struct netconn *conn)
|
||||
tcp_output(conn->pcb.tcp);
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
conn->write_delayed = 1;
|
||||
conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
|
||||
#endif
|
||||
} else {
|
||||
/* On errors != ERR_MEM, we don't try writing any more but return
|
||||
@@ -1208,10 +1202,10 @@ do_writemore(struct netconn *conn)
|
||||
conn->current_msg = NULL;
|
||||
conn->state = NETCONN_NONE;
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
if (conn->write_delayed != 0)
|
||||
if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0)
|
||||
#endif
|
||||
{
|
||||
sys_sem_signal(conn->op_completed);
|
||||
sys_sem_signal(&conn->op_completed);
|
||||
}
|
||||
}
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
@@ -1247,11 +1241,11 @@ do_write(struct api_msg_msg *msg)
|
||||
msg->conn->current_msg = msg;
|
||||
msg->conn->write_offset = 0;
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
msg->conn->write_delayed = 0;
|
||||
msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
|
||||
if (do_writemore(msg->conn) != ERR_OK) {
|
||||
LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
|
||||
UNLOCK_TCPIP_CORE();
|
||||
sys_arch_sem_wait(msg->conn->op_completed, 0);
|
||||
sys_arch_sem_wait(&msg->conn->op_completed, 0);
|
||||
LOCK_TCPIP_CORE();
|
||||
LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE);
|
||||
}
|
||||
@@ -1355,7 +1349,7 @@ do_close(struct api_msg_msg *msg)
|
||||
{
|
||||
msg->err = ERR_VAL;
|
||||
}
|
||||
sys_sem_signal(msg->conn->op_completed);
|
||||
sys_sem_signal(&msg->conn->op_completed);
|
||||
}
|
||||
|
||||
#if LWIP_IGMP
|
||||
|
||||
@@ -118,7 +118,7 @@ static struct lwip_socket sockets[NUM_SOCKETS];
|
||||
static struct lwip_select_cb *select_cb_list;
|
||||
|
||||
/** Semaphore protecting select_cb_list */
|
||||
static sys_sem_t selectsem;
|
||||
static sys_mutex_t select_lock;
|
||||
|
||||
/** Table to quickly map an lwIP error (err_t) to a socket error
|
||||
* by using -err as an index */
|
||||
@@ -172,7 +172,9 @@ static void lwip_setsockopt_internal(void *arg);
|
||||
void
|
||||
lwip_socket_init(void)
|
||||
{
|
||||
selectsem = sys_sem_new(1);
|
||||
if(sys_mutex_new(&select_lock) != ERR_OK) {
|
||||
LWIP_ASSERT("failed to create select_lock", 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -944,6 +946,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
u32_t msectimeout;
|
||||
struct lwip_select_cb select_cb;
|
||||
struct lwip_select_cb *p_selcb;
|
||||
err_t err;
|
||||
|
||||
LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%ld tvusec=%ld)\n",
|
||||
maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset,
|
||||
@@ -957,7 +960,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
select_cb.sem_signalled = 0;
|
||||
|
||||
/* Protect ourselves searching through the list */
|
||||
sys_sem_wait(selectsem);
|
||||
sys_mutex_lock(&select_lock);
|
||||
|
||||
if (readset)
|
||||
lreadset = *readset;
|
||||
@@ -979,7 +982,7 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
/* If we don't have any current events, then suspend if we are supposed to */
|
||||
if (!nready) {
|
||||
if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
|
||||
sys_sem_signal(selectsem);
|
||||
sys_mutex_unlock(&select_lock);
|
||||
if (readset)
|
||||
FD_ZERO(readset);
|
||||
if (writeset)
|
||||
@@ -998,14 +1001,20 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
* list is only valid while we are in this function, so it's ok
|
||||
* to use local variables */
|
||||
|
||||
select_cb.sem = sys_sem_new(0);
|
||||
err = sys_sem_new(&select_cb.sem, 0);
|
||||
if (err != ERR_OK) {
|
||||
/* failed to create semaphore */
|
||||
sys_mutex_unlock(&select_lock);
|
||||
set_errno(ENOMEM);
|
||||
return -1;
|
||||
}
|
||||
/* Note that we are still protected */
|
||||
/* Put this select_cb on top of list */
|
||||
select_cb.next = select_cb_list;
|
||||
select_cb_list = &select_cb;
|
||||
|
||||
/* Now we can safely unprotect */
|
||||
sys_sem_signal(selectsem);
|
||||
sys_mutex_unlock(&select_lock);
|
||||
|
||||
/* Now just wait to be woken */
|
||||
if (timeout == 0)
|
||||
@@ -1017,23 +1026,24 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
msectimeout = 1;
|
||||
}
|
||||
|
||||
waitres = sys_arch_sem_wait(select_cb.sem, msectimeout);
|
||||
waitres = sys_arch_sem_wait(&select_cb.sem, msectimeout);
|
||||
|
||||
/* Take us off the list */
|
||||
sys_sem_wait(selectsem);
|
||||
if (select_cb_list == &select_cb)
|
||||
sys_mutex_lock(&select_lock);
|
||||
if (select_cb_list == &select_cb) {
|
||||
select_cb_list = select_cb.next;
|
||||
else
|
||||
} else {
|
||||
for (p_selcb = select_cb_list; p_selcb; p_selcb = p_selcb->next) {
|
||||
if (p_selcb->next == &select_cb) {
|
||||
p_selcb->next = select_cb.next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sys_sem_signal(selectsem);
|
||||
sys_mutex_unlock(&select_lock);
|
||||
|
||||
sys_sem_free(select_cb.sem);
|
||||
sys_sem_free(&select_cb.sem);
|
||||
if (waitres == SYS_ARCH_TIMEOUT) {
|
||||
/* Timeout */
|
||||
if (readset)
|
||||
@@ -1064,8 +1074,9 @@ lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset,
|
||||
|
||||
/* See what's set */
|
||||
nready = lwip_selscan(maxfdp1, &lreadset, &lwriteset, &lexceptset);
|
||||
} else
|
||||
sys_sem_signal(selectsem);
|
||||
} else {
|
||||
sys_mutex_unlock(&select_lock);
|
||||
}
|
||||
|
||||
if (readset)
|
||||
*readset = lreadset;
|
||||
@@ -1123,7 +1134,7 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
return;
|
||||
}
|
||||
|
||||
sys_sem_wait(selectsem);
|
||||
sys_mutex_lock(&select_lock);
|
||||
/* Set event as required */
|
||||
switch (evt) {
|
||||
case NETCONN_EVT_RCVPLUS:
|
||||
@@ -1145,17 +1156,17 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
LWIP_ASSERT("unknown event", 0);
|
||||
break;
|
||||
}
|
||||
sys_sem_signal(selectsem);
|
||||
sys_mutex_unlock(&select_lock);
|
||||
|
||||
/* Now decide if anyone is waiting for this socket */
|
||||
/* NOTE: This code is written this way to protect the select link list
|
||||
but to avoid a deadlock situation by releasing selectsem before
|
||||
but to avoid a deadlock situation by releasing select_lock before
|
||||
signalling for the select. This means we need to go through the list
|
||||
multiple times ONLY IF a select was actually waiting. We go through
|
||||
the list the number of waiting select calls + 1. This list is
|
||||
expected to be small. */
|
||||
while (1) {
|
||||
sys_sem_wait(selectsem);
|
||||
sys_mutex_lock(&select_lock);
|
||||
for (scb = select_cb_list; scb; scb = scb->next) {
|
||||
if (scb->sem_signalled == 0) {
|
||||
/* Test this select call for our socket */
|
||||
@@ -1172,10 +1183,10 @@ event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len)
|
||||
}
|
||||
if (scb) {
|
||||
scb->sem_signalled = 1;
|
||||
sys_sem_signal(scb->sem);
|
||||
sys_sem_signal(selectsem);
|
||||
sys_sem_signal(&scb->sem);
|
||||
sys_mutex_unlock(&select_lock);
|
||||
} else {
|
||||
sys_sem_signal(selectsem);
|
||||
sys_mutex_unlock(&select_lock);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1415,7 +1426,7 @@ lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen)
|
||||
data.optlen = optlen;
|
||||
data.err = err;
|
||||
tcpip_callback(lwip_getsockopt_internal, &data);
|
||||
sys_arch_sem_wait(sock->conn->op_completed, 0);
|
||||
sys_arch_sem_wait(&sock->conn->op_completed, 0);
|
||||
/* maybe lwip_getsockopt_internal has changed err */
|
||||
err = data.err;
|
||||
|
||||
@@ -1600,7 +1611,7 @@ lwip_getsockopt_internal(void *arg)
|
||||
break;
|
||||
#endif /* LWIP_UDP */
|
||||
} /* switch (level) */
|
||||
sys_sem_signal(sock->conn->op_completed);
|
||||
sys_sem_signal(&sock->conn->op_completed);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -1790,7 +1801,7 @@ lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t opt
|
||||
data.optlen = &optlen;
|
||||
data.err = err;
|
||||
tcpip_callback(lwip_setsockopt_internal, &data);
|
||||
sys_arch_sem_wait(sock->conn->op_completed, 0);
|
||||
sys_arch_sem_wait(&sock->conn->op_completed, 0);
|
||||
/* maybe lwip_setsockopt_internal has changed err */
|
||||
err = data.err;
|
||||
|
||||
@@ -1978,7 +1989,7 @@ lwip_setsockopt_internal(void *arg)
|
||||
break;
|
||||
#endif /* LWIP_UDP */
|
||||
} /* switch (level) */
|
||||
sys_sem_signal(sock->conn->op_completed);
|
||||
sys_sem_signal(&sock->conn->op_completed);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -2000,8 +2011,9 @@ lwip_ioctl(int s, long cmd, void *argp)
|
||||
}
|
||||
|
||||
SYS_ARCH_GET(sock->conn->recv_avail, recv_avail);
|
||||
if (recv_avail < 0)
|
||||
if (recv_avail < 0) {
|
||||
recv_avail = 0;
|
||||
}
|
||||
*((u16_t*)argp) = (u16_t)recv_avail;
|
||||
|
||||
/* Check if there is data left from the last recv operation. /maq 041215 */
|
||||
|
||||
@@ -52,11 +52,11 @@
|
||||
/* global variables */
|
||||
static tcpip_init_done_fn tcpip_init_done;
|
||||
static void *tcpip_init_done_arg;
|
||||
static sys_mbox_t mbox = SYS_MBOX_NULL;
|
||||
static sys_mbox_t mbox;
|
||||
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
/** The global semaphore to lock the stack. */
|
||||
sys_sem_t lock_tcpip_core;
|
||||
sys_mutex_t lock_tcpip_core;
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@ tcpip_thread(void *arg)
|
||||
while (1) { /* MAIN Loop */
|
||||
UNLOCK_TCPIP_CORE();
|
||||
/* wait for a message, timeouts are processed while waiting */
|
||||
sys_timeouts_mbox_fetch(mbox, (void **)&msg);
|
||||
sys_timeouts_mbox_fetch(&mbox, (void **)&msg);
|
||||
LOCK_TCPIP_CORE();
|
||||
switch (msg->type) {
|
||||
#if LWIP_NETCONN
|
||||
@@ -148,7 +148,7 @@ tcpip_input(struct pbuf *p, struct netif *inp)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&mbox)) {
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
@@ -157,7 +157,7 @@ tcpip_input(struct pbuf *p, struct netif *inp)
|
||||
msg->type = TCPIP_MSG_INPKT;
|
||||
msg->msg.inp.p = p;
|
||||
msg->msg.inp.netif = inp;
|
||||
if (sys_mbox_trypost(mbox, msg) != ERR_OK) {
|
||||
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
|
||||
memp_free(MEMP_TCPIP_MSG_INPKT, msg);
|
||||
return ERR_MEM;
|
||||
}
|
||||
@@ -182,7 +182,7 @@ tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&mbox)) {
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
@@ -192,9 +192,9 @@ tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block)
|
||||
msg->msg.cb.function = function;
|
||||
msg->msg.cb.ctx = ctx;
|
||||
if (block) {
|
||||
sys_mbox_post(mbox, msg);
|
||||
sys_mbox_post(&mbox, msg);
|
||||
} else {
|
||||
if (sys_mbox_trypost(mbox, msg) != ERR_OK) {
|
||||
if (sys_mbox_trypost(&mbox, msg) != ERR_OK) {
|
||||
memp_free(MEMP_TCPIP_MSG_API, msg);
|
||||
return ERR_MEM;
|
||||
}
|
||||
@@ -217,7 +217,7 @@ tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&mbox)) {
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
@@ -227,7 +227,7 @@ tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg)
|
||||
msg->msg.tmo.msecs = msecs;
|
||||
msg->msg.tmo.h = h;
|
||||
msg->msg.tmo.arg = arg;
|
||||
sys_mbox_post(mbox, msg);
|
||||
sys_mbox_post(&mbox, msg);
|
||||
return ERR_OK;
|
||||
}
|
||||
return ERR_VAL;
|
||||
@@ -246,7 +246,7 @@ tcpip_untimeout(sys_timeout_handler h, void *arg)
|
||||
{
|
||||
struct tcpip_msg *msg;
|
||||
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&mbox)) {
|
||||
msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API);
|
||||
if (msg == NULL) {
|
||||
return ERR_MEM;
|
||||
@@ -255,7 +255,7 @@ tcpip_untimeout(sys_timeout_handler h, void *arg)
|
||||
msg->type = TCPIP_MSG_UNTIMEOUT;
|
||||
msg->msg.tmo.h = h;
|
||||
msg->msg.tmo.arg = arg;
|
||||
sys_mbox_post(mbox, msg);
|
||||
sys_mbox_post(&mbox, msg);
|
||||
return ERR_OK;
|
||||
}
|
||||
return ERR_VAL;
|
||||
@@ -279,11 +279,11 @@ tcpip_apimsg(struct api_msg *apimsg)
|
||||
apimsg->msg.err = ERR_VAL;
|
||||
#endif
|
||||
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
if (sys_mbox_valid(&mbox)) {
|
||||
msg.type = TCPIP_MSG_API;
|
||||
msg.msg.apimsg = apimsg;
|
||||
sys_mbox_post(mbox, &msg);
|
||||
sys_arch_sem_wait(apimsg->msg.conn->op_completed, 0);
|
||||
sys_mbox_post(&mbox, &msg);
|
||||
sys_arch_sem_wait(&apimsg->msg.conn->op_completed, 0);
|
||||
return apimsg->msg.err;
|
||||
}
|
||||
return ERR_VAL;
|
||||
@@ -329,18 +329,18 @@ tcpip_netifapi(struct netifapi_msg* netifapimsg)
|
||||
{
|
||||
struct tcpip_msg msg;
|
||||
|
||||
if (mbox != SYS_MBOX_NULL) {
|
||||
netifapimsg->msg.sem = sys_sem_new(0);
|
||||
if (netifapimsg->msg.sem == SYS_SEM_NULL) {
|
||||
netifapimsg->msg.err = ERR_MEM;
|
||||
return netifapimsg->msg.err;
|
||||
if (sys_mbox_valid(&mbox)) {
|
||||
err_t err = sys_sem_new(&netifapimsg->msg.sem, 0);
|
||||
if (err != ERR_OK) {
|
||||
netifapimsg->msg.err = err;
|
||||
return err;
|
||||
}
|
||||
|
||||
msg.type = TCPIP_MSG_NETIFAPI;
|
||||
msg.msg.netifapimsg = netifapimsg;
|
||||
sys_mbox_post(mbox, &msg);
|
||||
sys_sem_wait(netifapimsg->msg.sem);
|
||||
sys_sem_free(netifapimsg->msg.sem);
|
||||
sys_mbox_post(&mbox, &msg);
|
||||
sys_sem_wait(&netifapimsg->msg.sem);
|
||||
sys_sem_free(&netifapimsg->msg.sem);
|
||||
return netifapimsg->msg.err;
|
||||
}
|
||||
return ERR_VAL;
|
||||
@@ -380,9 +380,13 @@ tcpip_init(tcpip_init_done_fn initfunc, void *arg)
|
||||
|
||||
tcpip_init_done = initfunc;
|
||||
tcpip_init_done_arg = arg;
|
||||
mbox = sys_mbox_new(TCPIP_MBOX_SIZE);
|
||||
if(sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
|
||||
LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
|
||||
}
|
||||
#if LWIP_TCPIP_CORE_LOCKING
|
||||
lock_tcpip_core = sys_sem_new(1);
|
||||
if(sys_mutex_new(&lock_tcpip_core) != ERR_OK) {
|
||||
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
|
||||
}
|
||||
#endif /* LWIP_TCPIP_CORE_LOCKING */
|
||||
|
||||
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
|
||||
|
||||
Reference in New Issue
Block a user