Fixed bug #44297 (CORE_LOCKING was broken some days ago); fixed that netconn_connect still used message passing for LWIP_TCPIP_CORE_LOCKING==1

This commit is contained in:
sg 2015-02-25 20:34:18 +01:00
parent 4bcddd72e6
commit 3e8ac30940
3 changed files with 39 additions and 60 deletions

View File

@ -244,26 +244,7 @@ netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port)
API_MSG_VAR_REF(msg).msg.conn = conn; API_MSG_VAR_REF(msg).msg.conn = conn;
API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr); API_MSG_VAR_REF(msg).msg.msg.bc.ipaddr = API_MSG_VAR_REF(addr);
API_MSG_VAR_REF(msg).msg.msg.bc.port = port; API_MSG_VAR_REF(msg).msg.msg.bc.port = port;
#if LWIP_TCP
#if (LWIP_UDP || LWIP_RAW)
if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)
#endif /* (LWIP_UDP || LWIP_RAW) */
{
/* The TCP version waits for the connect to succeed,
so always needs to use message passing. */
API_MSG_VAR_REF(msg).function = lwip_netconn_do_connect;
err = tcpip_apimsg(&API_MSG_VAR_REF(msg));
}
#endif /* LWIP_TCP */
#if (LWIP_UDP || LWIP_RAW) && LWIP_TCP
else
#endif /* (LWIP_UDP || LWIP_RAW) && LWIP_TCP */
#if (LWIP_UDP || LWIP_RAW)
{
/* UDP and RAW only set flags, so we can use core-locking. */
TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_connect, err); TCPIP_APIMSG(&API_MSG_VAR_REF(msg), lwip_netconn_do_connect, err);
}
#endif /* (LWIP_UDP || LWIP_RAW) */
API_MSG_VAR_FREE(msg); API_MSG_VAR_FREE(msg);
NETCONN_SET_SAFE_ERR(conn, err); NETCONN_SET_SAFE_ERR(conn, err);

View File

@ -66,8 +66,15 @@
/* forward declarations */ /* forward declarations */
#if LWIP_TCP #if LWIP_TCP
static err_t lwip_netconn_do_writemore(struct netconn *conn); #if LWIP_TCPIP_CORE_LOCKING
static err_t lwip_netconn_do_close_internal(struct netconn *conn); #define WRITE_DELAYED , 1
#define WRITE_DELAYED_PARAM , u8_t delayed
#else /* LWIP_TCPIP_CORE_LOCKING */
#define WRITE_DELAYED
#define WRITE_DELAYED_PARAM
#endif /* LWIP_TCPIP_CORE_LOCKING */
static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM);
static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM);
#endif #endif
#if LWIP_RAW #if LWIP_RAW
@ -286,14 +293,14 @@ poll_tcp(void *arg, struct tcp_pcb *pcb)
LWIP_ASSERT("conn != NULL", (conn != NULL)); LWIP_ASSERT("conn != NULL", (conn != NULL));
if (conn->state == NETCONN_WRITE) { if (conn->state == NETCONN_WRITE) {
lwip_netconn_do_writemore(conn); lwip_netconn_do_writemore(conn WRITE_DELAYED);
} else if (conn->state == NETCONN_CLOSE) { } else if (conn->state == NETCONN_CLOSE) {
#if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER #if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER
if (conn->current_msg && conn->current_msg->msg.sd.polls_left) { if (conn->current_msg && conn->current_msg->msg.sd.polls_left) {
conn->current_msg->msg.sd.polls_left--; conn->current_msg->msg.sd.polls_left--;
} }
#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */ #endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */
lwip_netconn_do_close_internal(conn); lwip_netconn_do_close_internal(conn WRITE_DELAYED);
} }
/* @todo: implement connect timeout here? */ /* @todo: implement connect timeout here? */
@ -327,9 +334,9 @@ sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len)
LWIP_ASSERT("conn != NULL", (conn != NULL)); LWIP_ASSERT("conn != NULL", (conn != NULL));
if (conn->state == NETCONN_WRITE) { if (conn->state == NETCONN_WRITE) {
lwip_netconn_do_writemore(conn); lwip_netconn_do_writemore(conn WRITE_DELAYED);
} else if (conn->state == NETCONN_CLOSE) { } else if (conn->state == NETCONN_CLOSE) {
lwip_netconn_do_close_internal(conn); lwip_netconn_do_close_internal(conn WRITE_DELAYED);
} }
if (conn) { if (conn) {
@ -762,9 +769,10 @@ netconn_drain(struct netconn *conn)
* places. * places.
* *
* @param conn the TCP netconn to close * @param conn the TCP netconn to close
* [@param delay 1 if called from sent/poll (wake up calling thread on end)]
*/ */
static err_t static err_t
lwip_netconn_do_close_internal(struct netconn *conn) lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM)
{ {
err_t err; err_t err;
u8_t shut, shut_rx, shut_tx, close; u8_t shut, shut_rx, shut_tx, close;
@ -926,8 +934,13 @@ lwip_netconn_do_close_internal(struct netconn *conn)
API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0);
} }
} }
#if LWIP_TCPIP_CORE_LOCKING
if (delayed)
#endif
{
/* wake up the application task */ /* wake up the application task */
sys_sem_signal(op_completed_sem); sys_sem_signal(op_completed_sem);
}
return ERR_OK; return ERR_OK;
} }
if (!close_finished) { if (!close_finished) {
@ -975,7 +988,6 @@ lwip_netconn_do_delconn(struct api_msg_msg *msg)
msg->conn->current_msg = NULL; msg->conn->current_msg = NULL;
msg->conn->write_offset = 0; msg->conn->write_offset = 0;
msg->conn->state = NETCONN_NONE; msg->conn->state = NETCONN_NONE;
msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
sys_sem_signal(op_completed_sem); sys_sem_signal(op_completed_sem);
} }
} }
@ -1018,7 +1030,7 @@ lwip_netconn_do_delconn(struct api_msg_msg *msg)
msg->msg.sd.shut = NETCONN_SHUT_RDWR; msg->msg.sd.shut = NETCONN_SHUT_RDWR;
msg->conn->current_msg = msg; msg->conn->current_msg = msg;
#if LWIP_TCPIP_CORE_LOCKING #if LWIP_TCPIP_CORE_LOCKING
if (lwip_netconn_do_close_internal(msg->conn) != ERR_OK) { if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) {
LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE);
UNLOCK_TCPIP_CORE(); UNLOCK_TCPIP_CORE();
sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
@ -1045,7 +1057,7 @@ lwip_netconn_do_delconn(struct api_msg_msg *msg)
API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0);
} }
if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) { if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) {
sys_sem_signal(LWIP_API_MSG_SEM(msg)); TCPIP_APIMSG_ACK(msg);
} }
} }
@ -1153,11 +1165,6 @@ lwip_netconn_do_connect(struct api_msg_msg *msg)
if (msg->conn->pcb.tcp == NULL) { if (msg->conn->pcb.tcp == NULL) {
/* This may happen when calling netconn_connect() a second time */ /* This may happen when calling netconn_connect() a second time */
msg->err = ERR_CLSD; msg->err = ERR_CLSD;
if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) {
/* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */
sys_sem_signal(LWIP_API_MSG_SEM(msg));
return;
}
} else { } else {
switch (NETCONNTYPE_GROUP(msg->conn->type)) { switch (NETCONNTYPE_GROUP(msg->conn->type)) {
#if LWIP_RAW #if LWIP_RAW
@ -1190,14 +1197,19 @@ lwip_netconn_do_connect(struct api_msg_msg *msg)
} else { } else {
msg->conn->current_msg = msg; msg->conn->current_msg = msg;
/* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()),
* when the connection is established! */ when the connection is established! */
#if LWIP_TCPIP_CORE_LOCKING
LWIP_ASSERT("state!", msg->conn->state == NETCONN_CONNECT);
UNLOCK_TCPIP_CORE();
sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
LOCK_TCPIP_CORE();
LWIP_ASSERT("state!", msg->conn->state != NETCONN_CONNECT);
#endif /* LWIP_TCPIP_CORE_LOCKING */
return; return;
} }
} }
} }
/* For TCP, netconn_connect() calls tcpip_apimsg(), so signal op_completed here. */ break;
sys_sem_signal(LWIP_API_MSG_SEM(msg));
return;
#endif /* LWIP_TCP */ #endif /* LWIP_TCP */
default: default:
LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0));
@ -1396,11 +1408,12 @@ lwip_netconn_do_recv(struct api_msg_msg *msg)
* blocking application thread (waiting in netconn_write) is released. * blocking application thread (waiting in netconn_write) is released.
* *
* @param conn netconn (that is currently in state NETCONN_WRITE) to process * @param conn netconn (that is currently in state NETCONN_WRITE) to process
* [@param delay 1 if called from sent/poll (wake up calling thread on end)]
* @return ERR_OK * @return ERR_OK
* ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished
*/ */
static err_t static err_t
lwip_netconn_do_writemore(struct netconn *conn) lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM)
{ {
err_t err; err_t err;
void *dataptr; void *dataptr;
@ -1442,9 +1455,6 @@ lwip_netconn_do_writemore(struct netconn *conn)
diff = conn->current_msg->msg.w.len - conn->write_offset; diff = conn->current_msg->msg.w.len - conn->write_offset;
if (diff > 0xffffUL) { /* max_u16_t */ if (diff > 0xffffUL) { /* max_u16_t */
len = 0xffff; len = 0xffff;
#if LWIP_TCPIP_CORE_LOCKING
conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
#endif
apiflags |= TCP_WRITE_FLAG_MORE; apiflags |= TCP_WRITE_FLAG_MORE;
} else { } else {
len = (u16_t)diff; len = (u16_t)diff;
@ -1459,9 +1469,6 @@ lwip_netconn_do_writemore(struct netconn *conn)
goto err_mem; goto err_mem;
} }
} else { } else {
#if LWIP_TCPIP_CORE_LOCKING
conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
#endif
apiflags |= TCP_WRITE_FLAG_MORE; apiflags |= TCP_WRITE_FLAG_MORE;
} }
} }
@ -1517,9 +1524,6 @@ err_mem:
write_finished = 1; write_finished = 1;
conn->current_msg->msg.w.len = 0; conn->current_msg->msg.w.len = 0;
} else { } else {
#if LWIP_TCPIP_CORE_LOCKING
conn->flags |= NETCONN_FLAG_WRITE_DELAYED;
#endif
} }
} else { } else {
/* On errors != ERR_MEM, we don't try writing any more but return /* On errors != ERR_MEM, we don't try writing any more but return
@ -1536,7 +1540,7 @@ err_mem:
conn->current_msg = NULL; conn->current_msg = NULL;
conn->state = NETCONN_NONE; conn->state = NETCONN_NONE;
#if LWIP_TCPIP_CORE_LOCKING #if LWIP_TCPIP_CORE_LOCKING
if ((conn->flags & NETCONN_FLAG_WRITE_DELAYED) != 0) if (delayed)
#endif #endif
{ {
sys_sem_signal(op_completed_sem); sys_sem_signal(op_completed_sem);
@ -1577,8 +1581,7 @@ lwip_netconn_do_write(struct api_msg_msg *msg)
msg->conn->current_msg = msg; msg->conn->current_msg = msg;
msg->conn->write_offset = 0; msg->conn->write_offset = 0;
#if LWIP_TCPIP_CORE_LOCKING #if LWIP_TCPIP_CORE_LOCKING
msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED; if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) {
if (lwip_netconn_do_writemore(msg->conn) != ERR_OK) {
LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE);
UNLOCK_TCPIP_CORE(); UNLOCK_TCPIP_CORE();
sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);
@ -1701,7 +1704,6 @@ lwip_netconn_do_close(struct api_msg_msg *msg)
msg->conn->current_msg = NULL; msg->conn->current_msg = NULL;
msg->conn->write_offset = 0; msg->conn->write_offset = 0;
msg->conn->state = NETCONN_NONE; msg->conn->state = NETCONN_NONE;
msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
sys_sem_signal(op_completed_sem); sys_sem_signal(op_completed_sem);
} else { } else {
LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD); LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD);
@ -1722,7 +1724,7 @@ lwip_netconn_do_close(struct api_msg_msg *msg)
msg->conn->state = NETCONN_CLOSE; msg->conn->state = NETCONN_CLOSE;
msg->conn->current_msg = msg; msg->conn->current_msg = msg;
#if LWIP_TCPIP_CORE_LOCKING #if LWIP_TCPIP_CORE_LOCKING
if (lwip_netconn_do_close_internal(msg->conn) != ERR_OK) { if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) {
LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE);
UNLOCK_TCPIP_CORE(); UNLOCK_TCPIP_CORE();
sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0);

View File

@ -66,10 +66,6 @@ extern "C" {
#define NETCONN_DONTBLOCK 0x04 #define NETCONN_DONTBLOCK 0x04
/* Flags for struct netconn.flags (u8_t) */ /* Flags for struct netconn.flags (u8_t) */
/** TCP: when data passed to netconn_write doesn't fit into the send buffer,
this temporarily stores whether to wake up the original application task
if data couldn't be sent in the first try. */
#define NETCONN_FLAG_WRITE_DELAYED 0x01
/** Should this netconn avoid blocking? */ /** Should this netconn avoid blocking? */
#define NETCONN_FLAG_NON_BLOCKING 0x02 #define NETCONN_FLAG_NON_BLOCKING 0x02
/** Was the last connect action a non-blocking one? */ /** Was the last connect action a non-blocking one? */