mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-16 00:00:07 +01:00
clean libwebsockets.c
Signed-off-by: None <None>
This commit is contained in:
parent
b13eed4dcc
commit
bfaea95f60
3 changed files with 321 additions and 281 deletions
|
@ -88,6 +88,13 @@ static const char * const log_level_names[] = {
|
|||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#include "lws-plat-win.c"
|
||||
#else
|
||||
#include "lws-plat-unix.c"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* lws_get_library_version: get version and git hash library built from
|
||||
*
|
||||
|
@ -102,44 +109,6 @@ lws_get_library_version(void)
|
|||
return library_version;
|
||||
}
|
||||
|
||||
static unsigned long long time_in_microseconds()
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
FILETIME filetime;
|
||||
ULARGE_INTEGER datetime;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
GetCurrentFT(&filetime);
|
||||
#else
|
||||
GetSystemTimeAsFileTime(&filetime);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a
|
||||
* ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can
|
||||
* prevent alignment faults on 64-bit Windows).
|
||||
*/
|
||||
memcpy(&datetime, &filetime, sizeof(datetime));
|
||||
|
||||
/* Windows file times are in 100s of nanoseconds. */
|
||||
return (datetime.QuadPart - DELTA_EPOCH_IN_MICROSECS) / 10;
|
||||
#else
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
static inline time_t time(time_t *t)
|
||||
{
|
||||
time_t ret = time_in_microseconds() / 1000000;
|
||||
*t = ret;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
insert_wsi_socket_into_fds(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi)
|
||||
|
@ -201,6 +170,13 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context,
|
|||
int m;
|
||||
struct libwebsocket_pollargs pa = { wsi->sock, 0, 0};
|
||||
|
||||
#ifdef LWS_USE_LIBEV
|
||||
if (LWS_LIBEV_ENABLED(context)) {
|
||||
ev_io_stop(context->io_loop, (struct ev_io *)&wsi->w_read);
|
||||
ev_io_stop(context->io_loop, (struct ev_io *)&wsi->w_write);
|
||||
}
|
||||
#endif /* LWS_USE_LIBEV */
|
||||
|
||||
if (!--context->fds_count) {
|
||||
context->protocols[0].callback(context, wsi,
|
||||
LWS_CALLBACK_LOCK_POLL,
|
||||
|
@ -214,7 +190,7 @@ remove_wsi_socket_from_fds(struct libwebsocket_context *context,
|
|||
return 1;
|
||||
}
|
||||
|
||||
lwsl_info("remove_wsi_socket_from_fds: wsi=%p, sock=%d, fds pos=%d\n",
|
||||
lwsl_info("%s: wsi=%p, sock=%d, fds pos=%d\n", __func__,
|
||||
wsi, wsi->sock, wsi->position_in_fds_table);
|
||||
|
||||
context->protocols[0].callback(context, wsi,
|
||||
|
@ -442,13 +418,6 @@ just_kill_connection:
|
|||
* delete socket from the internal poll list if still present
|
||||
*/
|
||||
|
||||
#ifdef LWS_USE_LIBEV
|
||||
if (LWS_LIBEV_ENABLED(context)) {
|
||||
ev_io_stop(context->io_loop,(struct ev_io *)&wsi->w_read);
|
||||
ev_io_stop(context->io_loop,(struct ev_io *)&wsi->w_write);
|
||||
}
|
||||
#endif /* LWS_USE_LIBEV */
|
||||
|
||||
remove_wsi_socket_from_fds(context, wsi);
|
||||
|
||||
wsi->state = WSI_STATE_DEAD_SOCKET;
|
||||
|
@ -673,22 +642,6 @@ bail:
|
|||
lws_latency(context, wsi, "libwebsockets_get_peer_addresses", ret, 1);
|
||||
}
|
||||
|
||||
LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context,
|
||||
void *buf, int len)
|
||||
{
|
||||
int n;
|
||||
char *p = (char *)buf;
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
for (n = 0; n < len; n++)
|
||||
p[n] = (unsigned char)rand();
|
||||
#else
|
||||
n = read(context->fd_random, p, len);
|
||||
#endif
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
int lws_set_socket_options(struct libwebsocket_context *context, int fd)
|
||||
{
|
||||
int optval = 1;
|
||||
|
@ -763,36 +716,9 @@ int lws_set_socket_options(struct libwebsocket_context *context, int fd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return wsi->sock_send_blocking;
|
||||
#else
|
||||
struct libwebsocket_pollfd fds;
|
||||
|
||||
/* treat the fact we got a truncated send pending as if we're choked */
|
||||
if (wsi->truncated_send_len)
|
||||
return 1;
|
||||
|
||||
fds.fd = wsi->sock;
|
||||
fds.events = POLLOUT;
|
||||
fds.revents = 0;
|
||||
|
||||
if (poll(&fds, 1, 0) != 1)
|
||||
return 1;
|
||||
|
||||
if ((fds.revents & POLLOUT) == 0)
|
||||
return 1;
|
||||
|
||||
/* okay to send another packet without blocking */
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
lws_handle_POLLOUT_event(struct libwebsocket_context *context,
|
||||
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd)
|
||||
struct libwebsocket *wsi, struct libwebsocket_pollfd *pollfd)
|
||||
{
|
||||
int n;
|
||||
|
||||
|
@ -978,23 +904,6 @@ libwebsocket_service_timeout_check(struct libwebsocket_context *context,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int lws_poll_listen_fd(struct libwebsocket_pollfd* fd)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fd_set readfds;
|
||||
struct timeval tv = { 0, 0 };
|
||||
|
||||
assert(fd->events == LWS_POLLIN);
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd->fd, &readfds);
|
||||
|
||||
return select(fd->fd + 1, &readfds, NULL, NULL, &tv);
|
||||
#else
|
||||
return poll(fd, 1, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsocket_service_fd() - Service polled socket with something waiting
|
||||
* @context: Websocket context
|
||||
|
@ -1052,12 +961,12 @@ libwebsocket_service_fd(struct libwebsocket_context *context,
|
|||
if (context->last_timeout_check_s != now) {
|
||||
context->last_timeout_check_s = now;
|
||||
|
||||
#ifndef WIN32
|
||||
#ifndef WIN32
|
||||
/* if our parent went down, don't linger around */
|
||||
if (context->started_with_parent &&
|
||||
kill(context->started_with_parent, 0) < 0)
|
||||
kill(getpid(), SIGTERM);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* global timeout check once per second */
|
||||
|
||||
|
@ -1214,7 +1123,7 @@ read_pending:
|
|||
|
||||
if (eff_buf.token_len < 0) {
|
||||
lwsl_debug("service_fd read ret = %d, errno = %d\n",
|
||||
eff_buf.token_len, LWS_ERRNO);
|
||||
eff_buf.token_len, LWS_ERRNO);
|
||||
if (LWS_ERRNO != LWS_EINTR && LWS_ERRNO != LWS_EAGAIN)
|
||||
goto close_and_handled;
|
||||
n = 0;
|
||||
|
@ -1314,37 +1223,6 @@ handled:
|
|||
return n;
|
||||
}
|
||||
|
||||
#ifdef LWS_USE_LIBEV
|
||||
LWS_VISIBLE void
|
||||
libwebsocket_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||
{
|
||||
struct libwebsocket_pollfd eventfd;
|
||||
struct lws_io_watcher *lws_io = (struct lws_io_watcher*)watcher;
|
||||
struct libwebsocket_context *context = lws_io->context;
|
||||
|
||||
if (revents & EV_ERROR)
|
||||
return;
|
||||
|
||||
eventfd.fd = watcher->fd;
|
||||
eventfd.revents = EV_NONE;
|
||||
if (revents & EV_READ)
|
||||
eventfd.revents |= LWS_POLLIN;
|
||||
|
||||
if (revents & EV_WRITE)
|
||||
eventfd.revents |= LWS_POLLOUT;
|
||||
|
||||
libwebsocket_service_fd(context,&eventfd);
|
||||
}
|
||||
|
||||
LWS_VISIBLE void
|
||||
libwebsocket_sigint_cb(
|
||||
struct ev_loop *loop, struct ev_signal* watcher, int revents)
|
||||
{
|
||||
ev_break(loop, EVBREAK_ALL);
|
||||
}
|
||||
#endif /* LWS_USE_LIBEV */
|
||||
|
||||
|
||||
/**
|
||||
* libwebsocket_context_destroy() - Destroy the websocket context
|
||||
* @context: Websocket context
|
||||
|
@ -1531,7 +1409,8 @@ libwebsocket_service(struct libwebsocket_context *context, int timeout_ms)
|
|||
}
|
||||
}
|
||||
|
||||
ev = WSAWaitForMultipleEvents(context->fds_count + 1, context->events, FALSE, timeout_ms, FALSE);
|
||||
ev = WSAWaitForMultipleEvents(context->fds_count + 1,
|
||||
context->events, FALSE, timeout_ms, FALSE);
|
||||
context->service_tid = 0;
|
||||
|
||||
if (ev == WSA_WAIT_TIMEOUT) {
|
||||
|
@ -1601,82 +1480,8 @@ libwebsocket_service(struct libwebsocket_context *context, int timeout_ms)
|
|||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsocket_cancel_service() - Cancel servicing of pending websocket activity
|
||||
* @context: Websocket context
|
||||
*
|
||||
* This function let a call to libwebsocket_service() waiting for a timeout
|
||||
* immediately return.
|
||||
*/
|
||||
LWS_VISIBLE void
|
||||
libwebsocket_cancel_service(struct libwebsocket_context *context)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
WSASetEvent(context->events[0]);
|
||||
#else
|
||||
char buf = 0;
|
||||
if (write(context->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1)
|
||||
lwsl_err("Cannot write to dummy pipe.");
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LWS_USE_LIBEV
|
||||
LWS_VISIBLE int
|
||||
libwebsocket_initloop(
|
||||
struct libwebsocket_context *context,
|
||||
struct ev_loop *loop)
|
||||
{
|
||||
int status = 0;
|
||||
int backend;
|
||||
const char * backend_name;
|
||||
struct ev_io *w_accept = (ev_io *)&context->w_accept;
|
||||
struct ev_signal *w_sigint = (ev_signal *)&context->w_sigint;
|
||||
|
||||
if (!loop)
|
||||
loop = ev_default_loop(0);
|
||||
|
||||
context->io_loop = loop;
|
||||
|
||||
/*
|
||||
* Initialize the accept w_accept with the listening socket
|
||||
* and register a callback for read operations:
|
||||
*/
|
||||
ev_io_init(w_accept, libwebsocket_accept_cb,
|
||||
context->listen_service_fd, EV_READ);
|
||||
ev_io_start(context->io_loop,w_accept);
|
||||
ev_signal_init(w_sigint, libwebsocket_sigint_cb, SIGINT);
|
||||
ev_signal_start(context->io_loop,w_sigint);
|
||||
backend = ev_backend(loop);
|
||||
|
||||
switch (backend) {
|
||||
case EVBACKEND_SELECT:
|
||||
backend_name = "select";
|
||||
break;
|
||||
case EVBACKEND_POLL:
|
||||
backend_name = "poll";
|
||||
break;
|
||||
case EVBACKEND_EPOLL:
|
||||
backend_name = "epoll";
|
||||
break;
|
||||
case EVBACKEND_KQUEUE:
|
||||
backend_name = "kqueue";
|
||||
break;
|
||||
case EVBACKEND_DEVPOLL:
|
||||
backend_name = "/dev/poll";
|
||||
break;
|
||||
case EVBACKEND_PORT:
|
||||
backend_name = "Solaris 10 \"port\"";
|
||||
break;
|
||||
default:
|
||||
backend_name = "Unknown libev backend";
|
||||
break;
|
||||
};
|
||||
|
||||
lwsl_notice(" libev backend: %s\n", backend_name);
|
||||
|
||||
return status;
|
||||
}
|
||||
#endif /* LWS_USE_LIBEV */
|
||||
|
||||
#ifndef LWS_NO_EXTENSIONS
|
||||
int
|
||||
|
@ -1766,7 +1571,8 @@ lws_change_pollfd(struct libwebsocket *wsi, int _and, int _or)
|
|||
if (WSAEventSelect(wsi->sock,
|
||||
context->events[wsi->position_in_fds_table + 1],
|
||||
networkevents) == SOCKET_ERROR) {
|
||||
lwsl_err("WSAEventSelect() failed with error %d\n", LWS_ERRNO);
|
||||
lwsl_err("WSAEventSelect() failed with error %d\n",
|
||||
LWS_ERRNO);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1818,8 +1624,7 @@ libwebsocket_callback_on_writable(struct libwebsocket_context *context,
|
|||
return 1;
|
||||
#endif
|
||||
if (wsi->position_in_fds_table < 0) {
|
||||
lwsl_err("libwebsocket_callback_on_writable: failed to find socket %d\n",
|
||||
wsi->sock);
|
||||
lwsl_err("%s: failed to find socket %d\n", __func__, wsi->sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -1935,34 +1740,34 @@ lws_latency(struct libwebsocket_context *context, struct libwebsocket *wsi,
|
|||
|
||||
u = time_in_microseconds();
|
||||
|
||||
if (action) {
|
||||
if (completed) {
|
||||
if (wsi->action_start == wsi->latency_start)
|
||||
sprintf(buf,
|
||||
"Completion first try lat %luus: %p: ret %d: %s\n",
|
||||
u - wsi->latency_start,
|
||||
(void *)wsi, ret, action);
|
||||
else
|
||||
sprintf(buf,
|
||||
"Completion %luus: lat %luus: %p: ret %d: %s\n",
|
||||
u - wsi->action_start,
|
||||
u - wsi->latency_start,
|
||||
(void *)wsi, ret, action);
|
||||
wsi->action_start = 0;
|
||||
} else
|
||||
sprintf(buf, "lat %luus: %p: ret %d: %s\n",
|
||||
u - wsi->latency_start,
|
||||
(void *)wsi, ret, action);
|
||||
if (u - wsi->latency_start > context->worst_latency) {
|
||||
context->worst_latency = u - wsi->latency_start;
|
||||
strcpy(context->worst_latency_info, buf);
|
||||
}
|
||||
lwsl_latency("%s", buf);
|
||||
} else {
|
||||
if (!action) {
|
||||
wsi->latency_start = u;
|
||||
if (!wsi->action_start)
|
||||
wsi->action_start = u;
|
||||
return;
|
||||
}
|
||||
if (completed) {
|
||||
if (wsi->action_start == wsi->latency_start)
|
||||
sprintf(buf,
|
||||
"Completion first try lat %luus: %p: ret %d: %s\n",
|
||||
u - wsi->latency_start,
|
||||
(void *)wsi, ret, action);
|
||||
else
|
||||
sprintf(buf,
|
||||
"Completion %luus: lat %luus: %p: ret %d: %s\n",
|
||||
u - wsi->action_start,
|
||||
u - wsi->latency_start,
|
||||
(void *)wsi, ret, action);
|
||||
wsi->action_start = 0;
|
||||
} else
|
||||
sprintf(buf, "lat %luus: %p: ret %d: %s\n",
|
||||
u - wsi->latency_start, (void *)wsi, ret, action);
|
||||
|
||||
if (u - wsi->latency_start > context->worst_latency) {
|
||||
context->worst_latency = u - wsi->latency_start;
|
||||
strcpy(context->worst_latency_info, buf);
|
||||
}
|
||||
lwsl_latency("%s", buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -2067,8 +1872,6 @@ libwebsocket_rx_flow_allow_all_protocol(
|
|||
*
|
||||
* @context: Websocket context
|
||||
*/
|
||||
|
||||
|
||||
LWS_VISIBLE extern const char *
|
||||
libwebsocket_canonical_hostname(struct libwebsocket_context *context)
|
||||
{
|
||||
|
@ -2205,6 +2008,14 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
|
|||
lwsl_notice("IPV6 compiled in but disabled\n");
|
||||
#else
|
||||
lwsl_notice("IPV6 not compiled in\n");
|
||||
#endif
|
||||
#ifdef LWS_USE_LIBEV
|
||||
if (LWS_LIBEV_ENABLED(context))
|
||||
lwsl_notice("libev support compiled in and enabled\n");
|
||||
else
|
||||
lwsl_notice("libev support compiled in but disabled\n");
|
||||
#else
|
||||
lwsl_notice("libev support not compiled in\n");
|
||||
#endif
|
||||
lwsl_info(" LWS_MAX_HEADER_LEN: %u\n", LWS_MAX_HEADER_LEN);
|
||||
lwsl_info(" LWS_MAX_PROTOCOLS: %u\n", LWS_MAX_PROTOCOLS);
|
||||
|
@ -2231,9 +2042,11 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
|
|||
wVersionRequested = MAKEWORD(2, 2);
|
||||
|
||||
err = WSAStartup(wVersionRequested, &wsaData);
|
||||
if (err != 0) {
|
||||
/* Tell the user that we could not find a usable */
|
||||
/* Winsock DLL. */
|
||||
if (err) {
|
||||
/*
|
||||
* Tell the user that we could not find a usable
|
||||
* Winsock DLL
|
||||
*/
|
||||
lwsl_err("WSAStartup failed with error: %d\n", err);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2263,13 +2076,16 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
|
|||
context->max_fds = getdtablesize();
|
||||
lwsl_notice(" static allocation: %u + (%u x %u fds) = %u bytes\n",
|
||||
sizeof(struct libwebsocket_context),
|
||||
sizeof(struct libwebsocket_pollfd) + sizeof(struct libwebsocket *),
|
||||
sizeof(struct libwebsocket_pollfd) +
|
||||
sizeof(struct libwebsocket *),
|
||||
context->max_fds,
|
||||
sizeof(struct libwebsocket_context) +
|
||||
((sizeof(struct libwebsocket_pollfd) + sizeof(struct libwebsocket *)) *
|
||||
((sizeof(struct libwebsocket_pollfd) +
|
||||
sizeof(struct libwebsocket *)) *
|
||||
context->max_fds));
|
||||
|
||||
context->fds = (struct libwebsocket_pollfd *)malloc(sizeof(struct libwebsocket_pollfd) *
|
||||
context->fds = (struct libwebsocket_pollfd *)
|
||||
malloc(sizeof(struct libwebsocket_pollfd) *
|
||||
context->max_fds);
|
||||
if (context->fds == NULL) {
|
||||
lwsl_err("Unable to allocate fds array for %d connections\n",
|
||||
|
@ -2383,9 +2199,9 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
|
|||
p = getenv("http_proxy");
|
||||
if (p) {
|
||||
strncpy(context->http_proxy_address, p,
|
||||
sizeof(context->http_proxy_address) - 1);
|
||||
sizeof(context->http_proxy_address) - 1);
|
||||
context->http_proxy_address[
|
||||
sizeof(context->http_proxy_address) - 1] = '\0';
|
||||
sizeof(context->http_proxy_address) - 1] = '\0';
|
||||
|
||||
p = strchr(context->http_proxy_address, ':');
|
||||
if (p == NULL) {
|
||||
|
@ -2591,7 +2407,8 @@ libwebsocket_create_context(struct lws_context_creation_info *info)
|
|||
}
|
||||
|
||||
/* verify private key */
|
||||
if (!SSL_CTX_check_private_key(context->ssl_client_ctx)) {
|
||||
if (!SSL_CTX_check_private_key(
|
||||
context->ssl_client_ctx)) {
|
||||
lwsl_err("Private SSL key doesn't match cert\n");
|
||||
goto bail;
|
||||
}
|
||||
|
@ -2943,33 +2760,6 @@ static void lwsl_emit_stderr(int level, const char *line)
|
|||
fprintf(stderr, "%s%s", buf, line);
|
||||
}
|
||||
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
|
||||
{
|
||||
lwsl_emit_stderr(level, line);
|
||||
}
|
||||
#else
|
||||
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
|
||||
{
|
||||
int syslog_level = LOG_DEBUG;
|
||||
|
||||
switch (level) {
|
||||
case LLL_ERR:
|
||||
syslog_level = LOG_ERR;
|
||||
break;
|
||||
case LLL_WARN:
|
||||
syslog_level = LOG_WARNING;
|
||||
break;
|
||||
case LLL_NOTICE:
|
||||
syslog_level = LOG_NOTICE;
|
||||
break;
|
||||
case LLL_INFO:
|
||||
syslog_level = LOG_INFO;
|
||||
break;
|
||||
}
|
||||
syslog(syslog_level, "%s", line);
|
||||
}
|
||||
#endif
|
||||
|
||||
LWS_VISIBLE void _lws_log(int filter, const char *format, ...)
|
||||
{
|
||||
|
|
169
lib/lws-plat-unix.c
Normal file
169
lib/lws-plat-unix.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* included from libwebsockets.c for unix builds
|
||||
*/
|
||||
|
||||
static unsigned long long time_in_microseconds(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (tv.tv_sec * 1000000) + tv.tv_usec;
|
||||
}
|
||||
|
||||
LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context,
|
||||
void *buf, int len)
|
||||
{
|
||||
return read(context->fd_random, (char *)buf, len);
|
||||
}
|
||||
|
||||
LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi)
|
||||
{
|
||||
struct libwebsocket_pollfd fds;
|
||||
|
||||
/* treat the fact we got a truncated send pending as if we're choked */
|
||||
if (wsi->truncated_send_len)
|
||||
return 1;
|
||||
|
||||
fds.fd = wsi->sock;
|
||||
fds.events = POLLOUT;
|
||||
fds.revents = 0;
|
||||
|
||||
if (poll(&fds, 1, 0) != 1)
|
||||
return 1;
|
||||
|
||||
if ((fds.revents & POLLOUT) == 0)
|
||||
return 1;
|
||||
|
||||
/* okay to send another packet without blocking */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lws_poll_listen_fd(struct libwebsocket_pollfd *fd)
|
||||
{
|
||||
return poll(fd, 1, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef LWS_USE_LIBEV
|
||||
LWS_VISIBLE void
|
||||
libwebsocket_accept_cb(struct ev_loop *loop, struct ev_io *watcher, int revents)
|
||||
{
|
||||
struct libwebsocket_pollfd eventfd;
|
||||
struct lws_io_watcher *lws_io = (struct lws_io_watcher*)watcher;
|
||||
struct libwebsocket_context *context = lws_io->context;
|
||||
|
||||
if (revents & EV_ERROR)
|
||||
return;
|
||||
|
||||
eventfd.fd = watcher->fd;
|
||||
eventfd.revents = EV_NONE;
|
||||
if (revents & EV_READ)
|
||||
eventfd.revents |= LWS_POLLIN;
|
||||
|
||||
if (revents & EV_WRITE)
|
||||
eventfd.revents |= LWS_POLLOUT;
|
||||
|
||||
libwebsocket_service_fd(context,&eventfd);
|
||||
}
|
||||
|
||||
LWS_VISIBLE void
|
||||
libwebsocket_sigint_cb(
|
||||
struct ev_loop *loop, struct ev_signal* watcher, int revents)
|
||||
{
|
||||
ev_break(loop, EVBREAK_ALL);
|
||||
}
|
||||
|
||||
LWS_VISIBLE int
|
||||
libwebsocket_initloop(
|
||||
struct libwebsocket_context *context,
|
||||
struct ev_loop *loop)
|
||||
{
|
||||
int status = 0;
|
||||
int backend;
|
||||
const char * backend_name;
|
||||
struct ev_io *w_accept = (ev_io *)&context->w_accept;
|
||||
struct ev_signal *w_sigint = (ev_signal *)&context->w_sigint;
|
||||
|
||||
if (!loop)
|
||||
loop = ev_default_loop(0);
|
||||
|
||||
context->io_loop = loop;
|
||||
|
||||
/*
|
||||
* Initialize the accept w_accept with the listening socket
|
||||
* and register a callback for read operations:
|
||||
*/
|
||||
ev_io_init(w_accept, libwebsocket_accept_cb,
|
||||
context->listen_service_fd, EV_READ);
|
||||
ev_io_start(context->io_loop,w_accept);
|
||||
ev_signal_init(w_sigint, libwebsocket_sigint_cb, SIGINT);
|
||||
ev_signal_start(context->io_loop,w_sigint);
|
||||
backend = ev_backend(loop);
|
||||
|
||||
switch (backend) {
|
||||
case EVBACKEND_SELECT:
|
||||
backend_name = "select";
|
||||
break;
|
||||
case EVBACKEND_POLL:
|
||||
backend_name = "poll";
|
||||
break;
|
||||
case EVBACKEND_EPOLL:
|
||||
backend_name = "epoll";
|
||||
break;
|
||||
case EVBACKEND_KQUEUE:
|
||||
backend_name = "kqueue";
|
||||
break;
|
||||
case EVBACKEND_DEVPOLL:
|
||||
backend_name = "/dev/poll";
|
||||
break;
|
||||
case EVBACKEND_PORT:
|
||||
backend_name = "Solaris 10 \"port\"";
|
||||
break;
|
||||
default:
|
||||
backend_name = "Unknown libev backend";
|
||||
break;
|
||||
};
|
||||
|
||||
lwsl_notice(" libev backend: %s\n", backend_name);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
#endif /* LWS_USE_LIBEV */
|
||||
|
||||
/**
|
||||
* libwebsocket_cancel_service() - Cancel servicing of pending websocket activity
|
||||
* @context: Websocket context
|
||||
*
|
||||
* This function let a call to libwebsocket_service() waiting for a timeout
|
||||
* immediately return.
|
||||
*/
|
||||
LWS_VISIBLE void
|
||||
libwebsocket_cancel_service(struct libwebsocket_context *context)
|
||||
{
|
||||
char buf = 0;
|
||||
|
||||
if (write(context->dummy_pipe_fds[1], &buf, sizeof(buf)) != 1)
|
||||
lwsl_err("Cannot write to dummy pipe");
|
||||
}
|
||||
|
||||
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
|
||||
{
|
||||
int syslog_level = LOG_DEBUG;
|
||||
|
||||
switch (level) {
|
||||
case LLL_ERR:
|
||||
syslog_level = LOG_ERR;
|
||||
break;
|
||||
case LLL_WARN:
|
||||
syslog_level = LOG_WARNING;
|
||||
break;
|
||||
case LLL_NOTICE:
|
||||
syslog_level = LOG_NOTICE;
|
||||
break;
|
||||
case LLL_INFO:
|
||||
syslog_level = LOG_INFO;
|
||||
break;
|
||||
}
|
||||
syslog(syslog_level, "%s", line);
|
||||
}
|
81
lib/lws-plat-win.c
Normal file
81
lib/lws-plat-win.c
Normal file
|
@ -0,0 +1,81 @@
|
|||
static unsigned long long
|
||||
time_in_microseconds()
|
||||
{
|
||||
#if defined(WIN32) || defined(_WIN32)
|
||||
#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL
|
||||
FILETIME filetime;
|
||||
ULARGE_INTEGER datetime;
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
GetCurrentFT(&filetime);
|
||||
#else
|
||||
GetSystemTimeAsFileTime(&filetime);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a
|
||||
* ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can
|
||||
* prevent alignment faults on 64-bit Windows).
|
||||
*/
|
||||
memcpy(&datetime, &filetime, sizeof(datetime));
|
||||
|
||||
/* Windows file times are in 100s of nanoseconds. */
|
||||
return (datetime.QuadPart - DELTA_EPOCH_IN_MICROSECS) / 10;
|
||||
}
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
static inline time_t time(time_t *t)
|
||||
{
|
||||
time_t ret = time_in_microseconds() / 1000000;
|
||||
*t = ret;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
LWS_VISIBLE int libwebsockets_get_random(struct libwebsocket_context *context,
|
||||
void *buf, int len)
|
||||
{
|
||||
int n;
|
||||
char *p = (char *)buf;
|
||||
|
||||
for (n = 0; n < len; n++)
|
||||
p[n] = (unsigned char)rand();
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
LWS_VISIBLE int lws_send_pipe_choked(struct libwebsocket *wsi)
|
||||
{
|
||||
return wsi->sock_send_blocking;
|
||||
}
|
||||
|
||||
static int lws_poll_listen_fd(struct libwebsocket_pollfd *fd)
|
||||
{
|
||||
fd_set readfds;
|
||||
struct timeval tv = { 0, 0 };
|
||||
|
||||
assert(fd->events == LWS_POLLIN);
|
||||
|
||||
FD_ZERO(&readfds);
|
||||
FD_SET(fd->fd, &readfds);
|
||||
|
||||
return select(fd->fd + 1, &readfds, NULL, NULL, &tv);
|
||||
}
|
||||
|
||||
/**
|
||||
* libwebsocket_cancel_service() - Cancel servicing of pending websocket activity
|
||||
* @context: Websocket context
|
||||
*
|
||||
* This function let a call to libwebsocket_service() waiting for a timeout
|
||||
* immediately return.
|
||||
*/
|
||||
LWS_VISIBLE void
|
||||
libwebsocket_cancel_service(struct libwebsocket_context *context)
|
||||
{
|
||||
WSASetEvent(context->events[0]);
|
||||
}
|
||||
|
||||
LWS_VISIBLE void lwsl_emit_syslog(int level, const char *line)
|
||||
{
|
||||
lwsl_emit_stderr(level, line);
|
||||
}
|
Loading…
Add table
Reference in a new issue