1
0
Fork 0
mirror of https://github.com/warmcat/libwebsockets.git synced 2025-03-30 00:00:16 +01:00

lws_raw_transaction_completed

This provides a way to defer closing if the output buflist has
unsent content for the wsi, until the buflist is drained.

It doesn't make any assumption about the content being related
to http, so you can use it on raw.

It follows the semantics of the http transaction completed, ie

     if (lws_raw_transaction_completed(wsi))
	return -1

     return 0;
This commit is contained in:
Andy Green 2018-12-01 06:45:23 +08:00
parent 43cf8bb391
commit d78457425d
4 changed files with 58 additions and 1 deletions

View file

@ -123,6 +123,7 @@ struct lws_write_passthru {
/** /**
* lws_write() - Apply protocol then write data to client * lws_write() - Apply protocol then write data to client
*
* \param wsi: Websocket instance (available from user callback) * \param wsi: Websocket instance (available from user callback)
* \param buf: The data to send. For data being sent on a websocket * \param buf: The data to send. For data being sent on a websocket
* connection (ie, not default http), this buffer MUST have * connection (ie, not default http), this buffer MUST have
@ -216,7 +217,17 @@ lws_write(struct lws *wsi, unsigned char *buf, size_t len,
#define lws_write_http(wsi, buf, len) \ #define lws_write_http(wsi, buf, len) \
lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP) lws_write(wsi, (unsigned char *)(buf), len, LWS_WRITE_HTTP)
/* helper for multi-frame ws message flags */ /**
* lws_write_ws_flags() - Helper for multi-frame ws message flags
*
* \param initial: the lws_write flag to use for the start fragment, eg,
* LWS_WRITE_TEXT
* \param is_start: nonzero if this is the first fragment of the message
* \param is_end: nonzero if this is the last fragment of the message
*
* Returns the correct LWS_WRITE_ flag to use for each fragment of a message
* in turn.
*/
static LWS_INLINE int static LWS_INLINE int
lws_write_ws_flags(int initial, int is_start, int is_end) lws_write_ws_flags(int initial, int is_start, int is_end)
{ {
@ -232,4 +243,21 @@ lws_write_ws_flags(int initial, int is_start, int is_end)
return r; return r;
} }
/**
* lws_raw_transaction_completed() - Helper for flushing before close
*
* \param wsi: the struct lws to operate on
*
* Returns -1 if the wsi can close now. However if there is buffered, unsent
* data, the wsi is marked as to be closed when the output buffer data is
* drained, and it returns 0.
*
* For raw cases where the transaction completed without failure,
* `return lws_raw_transaction_completed(wsi)` should better be used than
* return -1.
*/
LWS_VISIBLE int LWS_WARN_UNUSED_RESULT
lws_raw_transaction_completed(struct lws *wsi);
///@} ///@}

View file

@ -1437,6 +1437,29 @@ lws_get_network_wsi(struct lws *wsi)
return wsi; return wsi;
} }
LWS_VISIBLE int LWS_WARN_UNUSED_RESULT
lws_raw_transaction_completed(struct lws *wsi)
{
if (lws_has_buffered_out(wsi)) {
/*
* ...so he tried to send something large, but it went out
* as a partial, but he immediately called us to say he wants
* to close the connection.
*
* Defer the close until the last part of the partial is sent.
*
*/
lwsl_debug("%s: %p: deferring due to partial\n", __func__, wsi);
wsi->close_when_buffered_out_drained = 1;
lws_callback_on_writable(wsi);
return 0;
}
return -1;
}
LWS_VISIBLE LWS_EXTERN const struct lws_protocols * LWS_VISIBLE LWS_EXTERN const struct lws_protocols *
lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name) lws_vhost_name_to_protocol(struct lws_vhost *vh, const char *name)
{ {

View file

@ -150,6 +150,11 @@ int lws_issue_raw(struct lws *wsi, unsigned char *buf, size_t len)
return -1; /* retry closing now */ return -1; /* retry closing now */
} }
if (wsi->close_when_buffered_out_drained) {
wsi->close_when_buffered_out_drained = 0;
return -1;
}
#if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2) #if defined(LWS_ROLE_H1) || defined(LWS_ROLE_H2)
#if !defined(LWS_WITHOUT_SERVER) #if !defined(LWS_WITHOUT_SERVER)
if (wsi->http.deferred_transaction_completed) { if (wsi->http.deferred_transaction_completed) {

View file

@ -980,6 +980,7 @@ struct lws {
unsigned int handling_404:1; unsigned int handling_404:1;
unsigned int protocol_bind_balance:1; unsigned int protocol_bind_balance:1;
unsigned int unix_skt:1; unsigned int unix_skt:1;
unsigned int close_when_buffered_out_drained:1;
unsigned int could_have_pending:1; /* detect back-to-back writes */ unsigned int could_have_pending:1; /* detect back-to-back writes */
unsigned int outer_will_close:1; unsigned int outer_will_close:1;