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:
goldsimon
2010-02-12 13:49:21 +00:00
parent 2d1631792a
commit 0030d1ade5
11 changed files with 232 additions and 151 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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 */

View File

@@ -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);