169 lines
No EOL
3.6 KiB
C
169 lines
No EOL
3.6 KiB
C
/*
|
|
* 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);
|
|
} |