diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h index ec1757150..851c38d70 100644 --- a/lib/libwebsockets.h +++ b/lib/libwebsockets.h @@ -38,12 +38,15 @@ namespace { using namespace mbed::Sockets::v0; struct libwebsocket; +struct libwebsocket_context; class lws_conn { public: lws_conn(): ts(NULL), - wsi(NULL) + wsi(NULL), + writeable(1), + awaiting_on_writeable(0) { } @@ -54,14 +57,16 @@ public: void onError(Socket *s, socket_error_t err); void onDisconnect(TCPStream *s); void onSent(Socket *s, uint16_t len); + void serialized_writeable(struct libwebsocket *wsi); public: TCPStream *ts; - Socket *s_HACK; public: struct libwebsocket *wsi; char buffer[BUFFER_SIZE]; + char writeable; + char awaiting_on_writeable; }; class lws_conn_listener : lws_conn { @@ -137,7 +142,7 @@ extern "C" { #include #include #else -#define getdtablesize() (10) +#define getdtablesize() (20) #endif #if defined(__GNUC__) diff --git a/lib/lws-plat-mbed3.c b/lib/lws-plat-mbed3.c index 264ee9c55..d11bfeed4 100644 --- a/lib/lws-plat-mbed3.c +++ b/lib/lws-plat-mbed3.c @@ -91,76 +91,6 @@ LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line) printf("%d: %s", level, line); } -LWS_VISIBLE int -lws_plat_service(struct libwebsocket_context *context, int timeout_ms) -{ - (void)context; - (void)timeout_ms; -#if 0 - int n; - int m; - char buf; -#ifdef LWS_OPENSSL_SUPPORT - struct libwebsocket *wsi, *wsi_next; -#endif - - /* stay dead once we are dead */ - - if (!context) - return 1; - - lws_libev_run(context); - - context->service_tid = context->protocols[0].callback(context, NULL, - LWS_CALLBACK_GET_THREAD_ID, NULL, NULL, 0); - -#ifdef LWS_OPENSSL_SUPPORT - /* if we know we have non-network pending data, do not wait in poll */ - if (lws_ssl_anybody_has_buffered_read(context)) - timeout_ms = 0; -#endif - n = poll(context->fds, context->fds_count, timeout_ms); - context->service_tid = 0; - -#ifdef LWS_OPENSSL_SUPPORT - if (!lws_ssl_anybody_has_buffered_read(context) && n == 0) { -#else - if (n == 0) /* poll timeout */ { -#endif - libwebsocket_service_fd(context, NULL); - return 0; - } - - if (n < 0) { - if (LWS_ERRNO != LWS_EINTR) - return -1; - return 0; - } - - /* any socket with events to service? */ - - for (n = 0; n < context->fds_count; n++) { - - if (!context->fds[n].revents) - continue; - - if (context->fds[n].fd == context->dummy_pipe_fds[0]) { - if (read(context->fds[n].fd, &buf, 1) != 1) - lwsl_err("Cannot read from dummy pipe."); - continue; - } - - m = libwebsocket_service_fd(context, &context->fds[n]); - if (m < 0) - return -1; - /* if something closed, retry this slot */ - if (m) - n--; - } -#endif - return 0; -} - LWS_VISIBLE int lws_plat_set_socket_options(struct libwebsocket_context *context, lws_sockfd_type fd) { @@ -215,17 +145,6 @@ lws_plat_service_periodic(struct libwebsocket_context *context) (void)context; } -LWS_VISIBLE int -lws_plat_change_pollfd(struct libwebsocket_context *context, - struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) -{ - (void)context; - (void)wsi; - (void)pfd; - - return 0; -} - LWS_VISIBLE int lws_plat_open_file(const char* filename, unsigned long* filelen) { diff --git a/lib/lws-plat-mbed3.cpp b/lib/lws-plat-mbed3.cpp index 1c9a049ae..ca0a1a339 100644 --- a/lib/lws-plat-mbed3.cpp +++ b/lib/lws-plat-mbed3.cpp @@ -21,11 +21,28 @@ extern "C" void mbed3_delete_tcp_stream_socket(void *sock) delete conn; } +void lws_conn::serialized_writeable(struct libwebsocket *_wsi) +{ + struct libwebsocket *wsi = (struct libwebsocket *)_wsi; + struct libwebsocket_pollfd pollfd; + lws_conn *conn = (lws_conn *)wsi->sock; + + conn->awaiting_on_writeable = 0; + + pollfd.fd = wsi->sock; + pollfd.events = POLLOUT; + pollfd.revents = POLLOUT; + + lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi); + + libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd); +} + extern "C" void mbed3_tcp_stream_bind(void *sock, int port, struct libwebsocket *wsi) { lws_conn_listener *srv = (lws_conn_listener *)sock; - lwsl_info("%s\r\n", __func__); + lwsl_debug("%s\r\n", __func__); /* associate us with the listening wsi */ ((lws_conn *)srv)->set_wsi(wsi); @@ -37,22 +54,44 @@ extern "C" void mbed3_tcp_stream_accept(void *sock, struct libwebsocket *wsi) { lws_conn *conn = (lws_conn *)sock; - lwsl_info("%s\r\n", __func__); + lwsl_debug("%s\r\n", __func__); conn->set_wsi(wsi); } +extern "C" LWS_VISIBLE int +lws_plat_change_pollfd(struct libwebsocket_context *context, + struct libwebsocket *wsi, struct libwebsocket_pollfd *pfd) +{ + lws_conn *conn = (lws_conn *)wsi->sock; + + (void)context; + if (pfd->events & POLLOUT) { + conn->awaiting_on_writeable = 1; + if (conn->writeable) { + mbed::util::FunctionPointer1 book(conn, &lws_conn::serialized_writeable); + minar::Scheduler::postCallback(book.bind(wsi)); + lwsl_debug("%s: wsi %p (booked callback)\r\n", __func__, (void *)wsi); + } else { + + lwsl_debug("%s: wsi %p (set awaiting_on_writeable)\r\n", __func__, (void *)wsi); + } + } else + conn->awaiting_on_writeable = 0; + + return 0; +} + extern "C" LWS_VISIBLE int lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, struct libwebsocket *wsi, unsigned char *buf, int len) { socket_error_t err; size_t _len = len; - + lwsl_debug("%s\r\n", __func__); (void)context; - /* s/s_HACK/ts/g when mbed3 listen payload bug fixed */ - err = ((lws_conn *)wsi->sock)->s_HACK->recv((char *)buf, &_len); + err = ((lws_conn *)wsi->sock)->ts->recv((char *)buf, &_len); if (err == SOCKET_ERROR_NONE) { lwsl_info("%s: got %d bytes\n", __func__, _len); return _len; @@ -66,10 +105,6 @@ lws_ssl_capable_read_no_ssl(struct libwebsocket_context *context, #endif return LWS_SSL_CAPABLE_MORE_SERVICE; - // !!! while listen payload mbed3 bug, don't error out if nothing */ -// if (((lws_conn *)wsi->sock)->s_HACK != ((Socket *)((lws_conn *)wsi->sock)->ts)) -// return 0; - lwsl_warn("error on reading from skt: %d\n", err); return LWS_SSL_CAPABLE_ERROR; } @@ -78,10 +113,14 @@ extern "C" LWS_VISIBLE int lws_ssl_capable_write_no_ssl(struct libwebsocket *wsi, unsigned char *buf, int len) { socket_error_t err; + lws_conn *conn = (lws_conn *)wsi->sock; lwsl_debug("%s: wsi %p: write %d (from %p)\n", __func__, (void *)wsi, len, (void *)buf); - err = ((lws_conn *)wsi->sock)->ts->send((char *)buf, len); + lwsl_debug("%s: wsi %p: clear writeable\n", __func__, (void *)wsi); + conn->writeable = 0; + + err = conn->ts->send((char *)buf, len); if (err == SOCKET_ERROR_NONE) return len; @@ -121,6 +160,8 @@ void lws_conn_listener::start(const uint16_t port) int lws_conn::actual_onRX(Socket *s) { struct libwebsocket_pollfd pollfd; + + (void)s; pollfd.fd = this; pollfd.events = POLLIN; @@ -128,8 +169,6 @@ int lws_conn::actual_onRX(Socket *s) lwsl_debug("%s: lws %p\n", __func__, wsi); - s_HACK = s; - return libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd); } @@ -215,20 +254,36 @@ void lws_conn_listener::onDisconnect(TCPStream *s) //if (s) //delete this; } + +extern "C" LWS_VISIBLE int +lws_plat_service(struct libwebsocket_context *context, int timeout_ms) +{ + (void)context; + (void)timeout_ms; + + return 0; +} + void lws_conn::onSent(Socket *s, uint16_t len) { struct libwebsocket_pollfd pollfd; (void)s; (void)len; + + if (!awaiting_on_writeable) { + lwsl_debug("%s: wsi %p (setting writable=1)\r\n", __func__, (void *)wsi); + writeable = 1; + return; + } + + writeable = 1; - pollfd.fd = this; + pollfd.fd = wsi->sock; pollfd.events = POLLOUT; pollfd.revents = POLLOUT; - - s_HACK = s; - lwsl_debug("%s: wsi %p\r\n", __func__, (void *)wsi); + lwsl_debug("%s: wsi %p (servicing now)\r\n", __func__, (void *)wsi); libwebsocket_service_fd(wsi->protocol->owning_server, &pollfd); } diff --git a/lib/pollfd.c b/lib/pollfd.c index b38df3d52..bdf0172a1 100644 --- a/lib/pollfd.c +++ b/lib/pollfd.c @@ -167,7 +167,10 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or) * ... and the service thread is waiting ... * then cancel it to force a restart with our changed events */ - if (pa.prev_events != pa.events) { +#if LWS_POSIX + if (pa.prev_events != pa.events) +#endif + { if (lws_plat_change_pollfd(context, wsi, pfd)) { lwsl_info("%s failed\n", __func__); diff --git a/module.json b/module.json index f2c565edd..221e2994a 100644 --- a/module.json +++ b/module.json @@ -15,6 +15,7 @@ "extraIncludes": [ "build/frdm-k64f-gcc/generated/include" ], "dependencies": { "mbed-drivers": "^0.11.1", + "sal-stack-lwip": "^1.0.4", "sockets": "^1.0.0" } }