| /* |
| * 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); |
| } |