diff --git a/platform/src/tcp_stream.cpp b/platform/src/tcp_stream.cpp index 4c3f52f..3e9e170 100644 --- a/platform/src/tcp_stream.cpp +++ b/platform/src/tcp_stream.cpp @@ -208,6 +208,11 @@ struct tfe_stream_write_ctx * tfe_stream_write_frag_start(const struct tfe_strea int tfe_stream_write_frag(struct tfe_stream_write_ctx * w_ctx, const unsigned char * data, size_t size) { + if(w_ctx->_stream == NULL) + { + return -EPIPE; + } + struct tfe_conn_private * this_conn = __this_conn(w_ctx->_stream, w_ctx->dir); int ret = 0; if (this_conn != NULL) @@ -224,8 +229,13 @@ int tfe_stream_write_frag(struct tfe_stream_write_ctx * w_ctx, const unsigned ch void tfe_stream_write_frag_end(struct tfe_stream_write_ctx * w_ctx) { - struct tfe_conn_private * this_conn = __this_conn(w_ctx->_stream, w_ctx->dir); - struct tfe_conn_private * peer_conn = __peer_conn(w_ctx->_stream, w_ctx->dir); + struct tfe_conn_private * this_conn; + struct tfe_conn_private * peer_conn; + + /* The connection terminated before this function call */ + if (w_ctx->_stream == NULL) goto __out; + this_conn = __this_conn(w_ctx->_stream, w_ctx->dir); + peer_conn = __peer_conn(w_ctx->_stream, w_ctx->dir); if (this_conn != NULL) { @@ -233,20 +243,18 @@ void tfe_stream_write_frag_end(struct tfe_stream_write_ctx * w_ctx) bufferevent_enable(peer_conn->bev, EV_READ); } - if (w_ctx->_stream != NULL) + if (w_ctx->dir == CONN_DIR_DOWNSTREAM) { - if (w_ctx->dir == CONN_DIR_DOWNSTREAM) - { - assert(w_ctx->_stream->w_ctx_downstream == w_ctx); - w_ctx->_stream->w_ctx_downstream = NULL; - } - else - { - assert(w_ctx->_stream->w_ctx_upstream == w_ctx); - w_ctx->_stream->w_ctx_upstream = NULL; - } + assert(w_ctx->_stream->w_ctx_downstream == w_ctx); + w_ctx->_stream->w_ctx_downstream = NULL; + } + else + { + assert(w_ctx->_stream->w_ctx_upstream == w_ctx); + w_ctx->_stream->w_ctx_upstream = NULL; } +__out: free(w_ctx); } @@ -616,6 +624,7 @@ static void __stream_bev_eventcb(struct bufferevent * bev, short events, void * struct tfe_conn_private ** ref_peer_conn{}; struct ssl_stream ** ref_this_ssl_stream{}; struct ssl_stream ** ref_peer_ssl_stream{}; + struct tfe_stream_write_ctx ** ref_this_write_ctx{}; const char * __str_dir = NULL; if (__bev_dir(_stream, bev) == CONN_DIR_UPSTREAM) @@ -624,6 +633,7 @@ static void __stream_bev_eventcb(struct bufferevent * bev, short events, void * ref_peer_conn = &_stream->conn_downstream; ref_this_ssl_stream = &_stream->ssl_upstream; ref_peer_ssl_stream = &_stream->ssl_downstream; + ref_this_write_ctx = &_stream->w_ctx_upstream; } if (__bev_dir(_stream, bev) == CONN_DIR_DOWNSTREAM) @@ -632,6 +642,7 @@ static void __stream_bev_eventcb(struct bufferevent * bev, short events, void * ref_peer_conn = &_stream->conn_upstream; ref_this_ssl_stream = &_stream->ssl_downstream; ref_peer_ssl_stream = &_stream->ssl_upstream; + ref_this_write_ctx = &_stream->w_ctx_downstream; } if (events & BEV_EVENT_ERROR || events & BEV_EVENT_EOF) @@ -665,6 +676,12 @@ __close_connection: if (*ref_this_conn != NULL) { + /* There is a frag writter setted, need to clear the reference of stream in the writter to indicate the connection is closed */ + if(*ref_this_write_ctx != NULL) + { + (*ref_this_write_ctx)->_stream = NULL; + } + __conn_private_destory_with_ssl(ev_base, *ref_this_conn, *ref_this_ssl_stream); *ref_this_conn = NULL; *ref_this_ssl_stream = NULL;