mirror of
https://github.com/lwip-tcpip/lwip.git
synced 2024-11-17 17:10:03 +00:00
started to implement fullduplex sockets/netconns (note that this is highly unstable yet!)
This commit is contained in:
parent
04b4971d8c
commit
7ff9825f55
@ -6,6 +6,10 @@ HISTORY
|
||||
|
||||
++ New features:
|
||||
|
||||
2015-02-11: Simon Goldschmidt
|
||||
* api_msg.c, opt.h: started to implement fullduplex sockets/netconns
|
||||
(note that this is highly unstable yet!)
|
||||
|
||||
2015-01-02: Simon Goldschmidt
|
||||
* tcp.c: tcp_kill_prio(): prefer nearly-closed connections (waiting for the
|
||||
last ACK only) over established connections when out of tcp pcbs
|
||||
|
@ -960,11 +960,34 @@ lwip_netconn_do_delconn(struct api_msg_msg *msg)
|
||||
enum netconn_state state = msg->conn->state;
|
||||
LWIP_ASSERT("netconn state error", /* this only happens for TCP netconns */
|
||||
(state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP));
|
||||
if ((msg->conn->state != NETCONN_NONE) &&
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
/* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */
|
||||
if (state != NETCONN_NONE) {
|
||||
if ((state == NETCONN_WRITE) ||
|
||||
((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) {
|
||||
/* close requested, abort running write/connect */
|
||||
sys_sem_t* op_completed_sem;
|
||||
LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
|
||||
op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
|
||||
msg->conn->current_msg->err = ERR_CLSD;
|
||||
msg->conn->current_msg = NULL;
|
||||
msg->conn->write_offset = 0;
|
||||
msg->conn->state = NETCONN_NONE;
|
||||
msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
|
||||
sys_sem_signal(op_completed_sem);
|
||||
}
|
||||
}
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
if (((msg->conn->state != NETCONN_NONE) &&
|
||||
(msg->conn->state != NETCONN_LISTEN) &&
|
||||
(msg->conn->state != NETCONN_CONNECT)) {
|
||||
(msg->conn->state != NETCONN_CONNECT)) ||
|
||||
(msg->conn->state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn)) {
|
||||
/* This means either a blocking write or blocking connect is running
|
||||
(nonblocking write returns and sets state to NONE) */
|
||||
msg->err = ERR_INPROGRESS;
|
||||
} else {
|
||||
} else
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
{
|
||||
LWIP_ASSERT("blocking connect in progress",
|
||||
(msg->conn->state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn));
|
||||
msg->err = ERR_OK;
|
||||
@ -1642,8 +1665,32 @@ lwip_netconn_do_close(struct api_msg_msg *msg)
|
||||
if ((msg->conn->pcb.tcp != NULL) &&
|
||||
(NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) &&
|
||||
((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) {
|
||||
if ((state == NETCONN_CONNECT) || (state == NETCONN_WRITE)) {
|
||||
/* Check if we are in a connected state */
|
||||
if (state == NETCONN_CONNECT) {
|
||||
/* TCP connect in progress: cannot shutdown */
|
||||
msg->err = ERR_CONN;
|
||||
} else if (state == NETCONN_WRITE) {
|
||||
#if LWIP_NETCONN_FULLDUPLEX
|
||||
if (msg->msg.sd.shut & NETCONN_SHUT_WR) {
|
||||
/* close requested, abort running write */
|
||||
sys_sem_t* op_completed_sem;
|
||||
LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL);
|
||||
op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg);
|
||||
msg->conn->current_msg->err = ERR_CLSD;
|
||||
msg->conn->current_msg = NULL;
|
||||
msg->conn->write_offset = 0;
|
||||
msg->conn->state = NETCONN_NONE;
|
||||
msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED;
|
||||
sys_sem_signal(op_completed_sem);
|
||||
} else {
|
||||
LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD);
|
||||
/* In this case, let the write continue and do not interfere with
|
||||
conn->current_msg or conn->state! */
|
||||
msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0);
|
||||
}
|
||||
#else /* LWIP_NETCONN_FULLDUPLEX */
|
||||
msg->err = ERR_INPROGRESS;
|
||||
#endif /* LWIP_NETCONN_FULLDUPLEX */
|
||||
} else {
|
||||
if (msg->msg.sd.shut & NETCONN_SHUT_RD) {
|
||||
/* Drain and delete mboxes */
|
||||
|
@ -1497,6 +1497,18 @@
|
||||
#define LWIP_NETCONN_SEM_PER_THREAD 0
|
||||
#endif
|
||||
|
||||
/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread,
|
||||
* writing from a 2nd thread and closing from a 3rd thread at the same time.
|
||||
* ATTENTION: This is currently really alpha! Some requirements:
|
||||
* - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from
|
||||
* multiple threads at once
|
||||
* - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox
|
||||
* and prevent a task pending on this during/after deletion
|
||||
*/
|
||||
#ifndef LWIP_NETCONN_FULLDUPLEX
|
||||
#define LWIP_NETCONN_FULLDUPLEX 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
------------------------------------
|
||||
---------- Socket options ----------
|
||||
|
Loading…
Reference in New Issue
Block a user