mirror of
https://github.com/clearlinux/uwsgi.git
synced 2026-06-16 02:15:48 +00:00
1419 lines
28 KiB
C
1419 lines
28 KiB
C
#include "uwsgi.h"
|
|
|
|
extern struct uwsgi_server uwsgi;
|
|
|
|
#ifdef UWSGI_EVENT_USE_POLL
|
|
#define UWSGI_EVENT_IN POLLIN
|
|
#define UWSGI_EVENT_OUT POLLOUT
|
|
|
|
int uwsgi_poll_event_queue_max = 0;
|
|
struct uwsgi_poll_event {
|
|
int nevents;
|
|
int max_events;
|
|
pthread_mutex_t lock;
|
|
struct pollfd *poll;
|
|
};
|
|
|
|
struct uwsgi_poll_event **uwsgi_poll_event_queue;
|
|
|
|
// all of the public functions must be heavy locked
|
|
|
|
static int uwsgi_poll_fd_is_registered(struct uwsgi_poll_event *upe, int fd) {
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (upe->poll[i].fd == fd) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int uwsgi_poll_fd_add(struct uwsgi_poll_event *upe, int fd, int event) {
|
|
int pos = upe->nevents;
|
|
if (pos > upe->max_events) return -1;
|
|
upe->poll[pos].fd = fd;
|
|
upe->poll[pos].events = event;
|
|
upe->nevents++;
|
|
return 0;
|
|
}
|
|
|
|
static int uwsgi_poll_fd_del(struct uwsgi_poll_event *upe, int fd) {
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (upe->poll[i].fd == fd) {
|
|
if (i < upe->nevents-1) {
|
|
memcpy(&upe->poll[i], &upe->poll[i+1], sizeof(struct uwsgi_poll_event) * (upe->nevents - (i+1)));
|
|
}
|
|
upe->nevents--;
|
|
return 0;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
static void uwsgi_poll_queue_rebuild(struct uwsgi_poll_event *upe) {
|
|
// we need to check if some file descriptor is no more valid
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (!uwsgi_valid_fd(upe->poll[i].fd)) {
|
|
uwsgi_poll_fd_del(upe, upe->poll[i].fd);
|
|
}
|
|
}
|
|
}
|
|
|
|
int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
uwsgi_poll_queue_rebuild(upe);
|
|
int ret = poll(upe->poll, upe->nevents, timeout * 1000);
|
|
if (ret > 0) {
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (upe->poll[i].revents) {
|
|
*interesting_fd = upe->poll[i].fd;
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return 1;
|
|
}
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return ret;
|
|
}
|
|
|
|
int event_queue_init() {
|
|
if (!uwsgi_poll_event_queue) {
|
|
uwsgi_poll_event_queue = uwsgi_calloc(sizeof(struct uwsgi_poll_event *) * uwsgi.max_fd);
|
|
}
|
|
int eq = uwsgi_poll_event_queue_max;
|
|
uwsgi_poll_event_queue[eq] = uwsgi_calloc(sizeof(struct uwsgi_poll_event));
|
|
uwsgi_poll_event_queue_max++;
|
|
uwsgi_poll_event_queue[eq]->poll = uwsgi_malloc(sizeof(struct pollfd) * uwsgi.max_fd);
|
|
uwsgi_poll_event_queue[eq]->max_events = uwsgi.max_fd;
|
|
pthread_mutex_init(&uwsgi_poll_event_queue[eq]->lock, NULL);
|
|
return eq;
|
|
}
|
|
|
|
void *event_queue_alloc(int nevents) {
|
|
return uwsgi_calloc(sizeof(struct pollfd) * nevents);
|
|
}
|
|
|
|
int event_queue_interesting_fd_is_read(void *events, int id) {
|
|
struct pollfd *pevents = (struct pollfd *)events;
|
|
struct pollfd *upoll = &pevents[id];
|
|
if (upoll->revents & POLLIN) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_write_to_readwrite(int eq, int fd) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (upe->poll[i].fd == fd) {
|
|
upe->poll[i].events = POLLIN|POLLOUT;
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return 0;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return -1;
|
|
}
|
|
|
|
int event_queue_fd_read_to_readwrite(int eq, int fd) {
|
|
return event_queue_fd_write_to_readwrite(eq, fd);
|
|
}
|
|
|
|
int event_queue_interesting_fd_is_write(void *events, int id) {
|
|
struct pollfd *pevents = (struct pollfd *)events;
|
|
struct pollfd *upoll = &pevents[id];
|
|
if (upoll->revents & POLLOUT) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_add_fd_read(int eq, int fd) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
if (uwsgi_poll_fd_is_registered(upe, fd)) {
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return 0;
|
|
}
|
|
int ret = uwsgi_poll_fd_add(upe, fd, POLLIN);
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return ret;
|
|
}
|
|
int event_queue_add_fd_write(int eq, int fd) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
if (uwsgi_poll_fd_is_registered(upe, fd)) {
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return 0;
|
|
}
|
|
int ret = uwsgi_poll_fd_add(upe, fd, POLLOUT);
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return ret;
|
|
}
|
|
int event_queue_del_fd(int eq, int fd, int event) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
int ret = uwsgi_poll_fd_del(upe, fd);
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return ret;
|
|
}
|
|
int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
uwsgi_poll_queue_rebuild(upe);
|
|
int ret = poll(upe->poll, upe->nevents, timeout * 1000);
|
|
int cnt = 0;
|
|
if (ret > 0) {
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (upe->poll[i].revents) {
|
|
struct pollfd *pevents = (struct pollfd *)events;
|
|
struct pollfd *upoll = &pevents[cnt];
|
|
upoll->fd = upe->poll[i].fd;
|
|
upoll->revents = upe->poll[i].revents;
|
|
upoll->events = upe->poll[i].events;
|
|
cnt++;
|
|
}
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&upe->lock);
|
|
if (ret <= 0) return ret;
|
|
return cnt;
|
|
}
|
|
int event_queue_interesting_fd_has_error(void *events, int id) {
|
|
struct pollfd *pevents = (struct pollfd *)events;
|
|
struct pollfd *upoll = &pevents[id];
|
|
if (upoll->revents & POLLERR || upoll->revents & POLLHUP || upoll->revents & POLLNVAL) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
int event_queue_interesting_fd(void *events, int id) {
|
|
struct pollfd *pevents = (struct pollfd *)events;
|
|
struct pollfd *upoll = &pevents[id];
|
|
return upoll->fd;
|
|
}
|
|
int event_queue_fd_write_to_read(int eq, int fd) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (upe->poll[i].fd == fd) {
|
|
upe->poll[i].events = POLLIN;
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return 0;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return -1;
|
|
}
|
|
int event_queue_fd_read_to_write(int eq, int fd) {
|
|
struct uwsgi_poll_event *upe = uwsgi_poll_event_queue[eq];
|
|
pthread_mutex_lock(&upe->lock);
|
|
int i;
|
|
for(i=0;i<upe->nevents;i++) {
|
|
if (upe->poll[i].fd == fd) {
|
|
upe->poll[i].events = POLLOUT;
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return 0;
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&upe->lock);
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_USE_PORT
|
|
|
|
#include <port.h>
|
|
|
|
#define UWSGI_EVENT_IN POLLIN
|
|
#define UWSGI_EVENT_OUT POLLOUT
|
|
|
|
int event_queue_init() {
|
|
|
|
int port = port_create();
|
|
|
|
if (port < 0) {
|
|
uwsgi_error("port_create()");
|
|
return -1;
|
|
}
|
|
|
|
return port;
|
|
}
|
|
|
|
int event_queue_del_fd(int eq, int fd, int event) {
|
|
|
|
if (port_dissociate(eq, PORT_SOURCE_FD, fd)) {
|
|
uwsgi_error("port_disassociate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_write_to_read(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLIN, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int event_queue_fd_read_to_write(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLOUT, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int event_queue_fd_readwrite_to_read(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLIN, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int event_queue_fd_readwrite_to_write(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLOUT, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int event_queue_fd_write_to_readwrite(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLIN | POLLOUT, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
int event_queue_fd_read_to_readwrite(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLIN | POLLOUT, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
int event_queue_interesting_fd_has_error(void *events, int id) {
|
|
port_event_t *pe = (port_event_t *) events;
|
|
if (pe[id].portev_events == POLLHUP || pe[id].portev_events == POLLERR) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_interesting_fd_is_read(void *events, int id) {
|
|
port_event_t *pe = (port_event_t *) events;
|
|
if (pe[id].portev_events == POLLIN) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_interesting_fd_is_write(void *events, int id) {
|
|
port_event_t *pe = (port_event_t *) events;
|
|
if (pe[id].portev_events == POLLOUT) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_add_fd_read(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLIN, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_add_fd_write(int eq, int fd) {
|
|
|
|
if (port_associate(eq, PORT_SOURCE_FD, fd, POLLOUT, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *event_queue_alloc(int nevents) {
|
|
|
|
return uwsgi_malloc(sizeof(port_event_t) * nevents);
|
|
}
|
|
|
|
int event_queue_interesting_fd(void *events, int id) {
|
|
port_event_t *pe = (port_event_t *) events;
|
|
#ifdef PORT_SOURCE_FILE
|
|
if (pe[id].portev_source == PORT_SOURCE_FILE || pe[id].portev_source == PORT_SOURCE_TIMER) {
|
|
#else
|
|
if (pe[id].portev_source == PORT_SOURCE_TIMER) {
|
|
#endif
|
|
return (long) pe[id].portev_user;
|
|
}
|
|
|
|
int fd = (int) pe[id].portev_object;
|
|
int eq = (long) pe[id].portev_user;
|
|
|
|
if (pe[id].portev_events == POLLOUT) {
|
|
event_queue_add_fd_write(eq, fd);
|
|
}
|
|
if (pe[id].portev_events == POLLIN) {
|
|
event_queue_add_fd_read(eq, fd);
|
|
}
|
|
|
|
return fd;
|
|
}
|
|
|
|
int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
|
|
|
int ret;
|
|
uint_t nget = 1;
|
|
timespec_t ts;
|
|
|
|
|
|
if (timeout >= 0) {
|
|
ts.tv_sec = timeout;
|
|
ts.tv_nsec = 0;
|
|
ret = port_getn(eq, events, nevents, &nget, &ts);
|
|
}
|
|
else {
|
|
ret = port_getn(eq, events, nevents, &nget, NULL);
|
|
}
|
|
|
|
if (ret < 0) {
|
|
if (errno == ETIME) return 0;
|
|
if (errno != EINTR) {
|
|
uwsgi_error("port_getn()");
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
uint_t i;
|
|
port_event_t *pe = (port_event_t *) events;
|
|
for(i=0;i<nget;i++) {
|
|
port_event_t *pe_i = &pe[i];
|
|
if (pe_i->portev_source == PORT_SOURCE_FD) {
|
|
// event must be readded (damn Oracle/Sun why the fu*k you made such a horrible choice ???? why not adding a ONESHOT flag ???)
|
|
if (port_associate(eq, pe_i->portev_source, pe_i->portev_object, pe_i->portev_events, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
}
|
|
}
|
|
}
|
|
|
|
return nget;
|
|
}
|
|
|
|
|
|
|
|
int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
|
|
|
int ret;
|
|
port_event_t pe;
|
|
timespec_t ts;
|
|
|
|
if (timeout > 0) {
|
|
ts.tv_sec = timeout;
|
|
ts.tv_nsec = 0;
|
|
ret = port_get(eq, &pe, &ts);
|
|
}
|
|
else {
|
|
ret = port_get(eq, &pe, NULL);
|
|
}
|
|
|
|
if (ret < 0) {
|
|
if (errno == ETIME) return 0;
|
|
if (errno != EINTR) {
|
|
uwsgi_error("port_get()");
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
if (pe.portev_source == PORT_SOURCE_FD) {
|
|
// event must be readded (damn Oracle/Sun why the fu*k you made such a horrible choice ???? why not adding a ONESHOT flag ???)
|
|
if (port_associate(eq, pe.portev_source, pe.portev_object, pe.portev_events, (void *)((long) eq))) {
|
|
uwsgi_error("port_associate");
|
|
}
|
|
}
|
|
|
|
|
|
#ifdef PORT_SOURCE_FILE
|
|
if (pe.portev_source == PORT_SOURCE_FILE || pe.portev_source == PORT_SOURCE_TIMER) {
|
|
#else
|
|
if (pe.portev_source == PORT_SOURCE_TIMER) {
|
|
#endif
|
|
*interesting_fd = (long) pe.portev_user;
|
|
}
|
|
else {
|
|
*interesting_fd = (int) pe.portev_object;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef UWSGI_EVENT_USE_EPOLL
|
|
|
|
#include <sys/epoll.h>
|
|
|
|
#define UWSGI_EVENT_IN EPOLLIN
|
|
#define UWSGI_EVENT_OUT EPOLLOUT
|
|
|
|
int event_queue_init() {
|
|
|
|
int epfd;
|
|
|
|
|
|
epfd = epoll_create(256);
|
|
|
|
if (epfd < 0) {
|
|
uwsgi_error("epoll_create()");
|
|
return -1;
|
|
}
|
|
|
|
return epfd;
|
|
}
|
|
|
|
|
|
int event_queue_add_fd_read(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLIN;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_ADD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_write_to_read(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLIN;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_MOD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_read_to_write(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLOUT;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_MOD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_readwrite_to_read(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLIN;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_MOD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_readwrite_to_write(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLOUT;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_MOD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int event_queue_fd_read_to_readwrite(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLIN | EPOLLOUT;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_MOD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_write_to_readwrite(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLIN | EPOLLOUT;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_MOD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int event_queue_del_fd(int eq, int fd, int event) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.data.fd = fd;
|
|
ee.events = event;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_DEL, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_add_fd_write(int eq, int fd) {
|
|
|
|
struct epoll_event ee;
|
|
|
|
memset(&ee, 0, sizeof(struct epoll_event));
|
|
ee.events = EPOLLOUT;
|
|
ee.data.fd = fd;
|
|
|
|
if (epoll_ctl(eq, EPOLL_CTL_ADD, fd, &ee)) {
|
|
uwsgi_error("epoll_ctl()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *event_queue_alloc(int nevents) {
|
|
|
|
return uwsgi_malloc(sizeof(struct epoll_event) * nevents);
|
|
}
|
|
|
|
int event_queue_interesting_fd(void *events, int id) {
|
|
struct epoll_event *ee = (struct epoll_event *) events;
|
|
return ee[id].data.fd;
|
|
}
|
|
|
|
int event_queue_interesting_fd_has_error(void *events, int id) {
|
|
struct epoll_event *ee = (struct epoll_event *) events;
|
|
if (ee[id].events == EPOLLHUP || ee[id].events == EPOLLERR || (ee[id].events == (EPOLLERR | EPOLLHUP))) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_interesting_fd_is_read(void *events, int id) {
|
|
struct epoll_event *ee = (struct epoll_event *) events;
|
|
if (ee[id].events & EPOLLIN) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_interesting_fd_is_write(void *events, int id) {
|
|
struct epoll_event *ee = (struct epoll_event *) events;
|
|
if (ee[id].events & EPOLLOUT) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
|
|
|
int ret;
|
|
|
|
if (timeout > 0) {
|
|
timeout = timeout * 1000;
|
|
}
|
|
|
|
ret = epoll_wait(eq, (struct epoll_event *) events, nevents, timeout);
|
|
if (ret < 0) {
|
|
if (errno != EINTR)
|
|
uwsgi_error("epoll_wait()");
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
|
|
|
int ret;
|
|
struct epoll_event ee;
|
|
|
|
if (timeout > 0) {
|
|
timeout = timeout * 1000;
|
|
}
|
|
|
|
ret = epoll_wait(eq, &ee, 1, timeout);
|
|
if (ret < 0) {
|
|
if (errno != EINTR)
|
|
uwsgi_error("epoll_wait()");
|
|
}
|
|
|
|
if (ret > 0) {
|
|
*interesting_fd = ee.data.fd;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_USE_KQUEUE
|
|
|
|
#define UWSGI_EVENT_IN EVFILT_READ
|
|
#define UWSGI_EVENT_OUT EVFILT_WRITE
|
|
|
|
int event_queue_init() {
|
|
|
|
int kfd = kqueue();
|
|
|
|
if (kfd < 0) {
|
|
uwsgi_error("kqueue()");
|
|
return -1;
|
|
}
|
|
|
|
return kfd;
|
|
}
|
|
|
|
int event_queue_fd_write_to_read(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_read_to_write(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_readwrite_to_read(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_readwrite_to_write(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_fd_read_to_readwrite(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int event_queue_fd_write_to_readwrite(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
int event_queue_del_fd(int eq, int fd, int event) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, event, EV_DELETE, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_add_fd_read(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_READ, EV_ADD, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_add_fd_write(int eq, int fd) {
|
|
|
|
struct kevent kev;
|
|
|
|
EV_SET(&kev, fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *event_queue_alloc(int nevents) {
|
|
|
|
return uwsgi_malloc(sizeof(struct kevent) * nevents);
|
|
}
|
|
|
|
int event_queue_wait_multi(int eq, int timeout, void *events, int nevents) {
|
|
|
|
int ret;
|
|
struct timespec ts;
|
|
|
|
if (timeout < 0) {
|
|
ret = kevent(eq, NULL, 0, events, nevents, NULL);
|
|
}
|
|
else {
|
|
memset(&ts, 0, sizeof(struct timespec));
|
|
ts.tv_sec = timeout;
|
|
ret = kevent(eq, NULL, 0, (struct kevent *) events, nevents, &ts);
|
|
}
|
|
|
|
if (ret < 0) {
|
|
if (errno != EINTR)
|
|
uwsgi_error("kevent()");
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
int event_queue_interesting_fd(void *events, int id) {
|
|
|
|
struct kevent *ev = (struct kevent *) events;
|
|
return ev[id].ident;
|
|
}
|
|
|
|
int event_queue_interesting_fd_has_error(void *events, int id) {
|
|
struct kevent *ev = (struct kevent *) events;
|
|
|
|
// DO NOT CHECK FOR EOF !!!
|
|
if (ev[id].flags & EV_ERROR) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_interesting_fd_is_read(void *events, int id) {
|
|
struct kevent *ev = (struct kevent *) events;
|
|
if (ev[id].filter == EVFILT_READ) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
int event_queue_interesting_fd_is_write(void *events, int id) {
|
|
struct kevent *ev = (struct kevent *) events;
|
|
if (ev[id].filter == EVFILT_WRITE) {
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int event_queue_wait(int eq, int timeout, int *interesting_fd) {
|
|
|
|
int ret;
|
|
struct timespec ts;
|
|
struct kevent ev;
|
|
|
|
if (timeout < 0) {
|
|
ret = kevent(eq, NULL, 0, &ev, 1, NULL);
|
|
}
|
|
else {
|
|
memset(&ts, 0, sizeof(struct timespec));
|
|
ts.tv_sec = timeout;
|
|
ret = kevent(eq, NULL, 0, &ev, 1, &ts);
|
|
}
|
|
|
|
if (ret < 0) {
|
|
if (errno != EINTR)
|
|
uwsgi_error("kevent()");
|
|
}
|
|
|
|
if (ret > 0) {
|
|
*interesting_fd = ev.ident;
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_FILEMONITOR_USE_NONE
|
|
int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
|
return -1;
|
|
}
|
|
struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_FILEMONITOR_USE_PORT
|
|
#ifdef PORT_SOURCE_FILE
|
|
int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
|
|
|
struct file_obj fo;
|
|
struct stat st;
|
|
static int fmon_id = 0xffffee00;
|
|
|
|
if (stat(filename, &st)) {
|
|
uwsgi_error("stat()");
|
|
return -1;
|
|
}
|
|
|
|
fo.fo_name = filename;
|
|
fo.fo_atime = st.st_atim;
|
|
fo.fo_mtime = st.st_mtim;
|
|
fo.fo_ctime = st.st_ctim;
|
|
|
|
fmon_id++;
|
|
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) & fo, FILE_MODIFIED | FILE_ATTRIB, (void *) (long) fmon_id)) {
|
|
uwsgi_error("port_associate()");
|
|
return -1;
|
|
}
|
|
|
|
|
|
*id = fmon_id;
|
|
|
|
uwsgi_log("added new file to monitor %s [%d]\n", filename, *id);
|
|
|
|
return *id;
|
|
}
|
|
|
|
struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
|
|
|
int i;
|
|
struct file_obj fo;
|
|
struct stat st;
|
|
|
|
for (i = 0; i < ushared->files_monitored_cnt; i++) {
|
|
if (ushared->files_monitored[i].registered) {
|
|
if (ushared->files_monitored[i].fd == id) {
|
|
if (stat(ushared->files_monitored[i].filename, &st)) {
|
|
uwsgi_error("stat()");
|
|
return NULL;
|
|
}
|
|
fo.fo_name = ushared->files_monitored[i].filename;
|
|
fo.fo_atime = st.st_atim;
|
|
fo.fo_mtime = st.st_mtim;
|
|
fo.fo_ctime = st.st_ctim;
|
|
if (port_associate(eq, PORT_SOURCE_FILE, (uintptr_t) & fo, FILE_MODIFIED | FILE_ATTRIB, (void *) (long) id)) {
|
|
uwsgi_error("port_associate()");
|
|
return NULL;
|
|
}
|
|
return &ushared->files_monitored[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#else
|
|
int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
|
return -1;
|
|
}
|
|
struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
|
return NULL;
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
#ifdef UWSGI_EVENT_FILEMONITOR_USE_KQUEUE
|
|
int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
|
|
|
struct kevent kev;
|
|
|
|
int fd = open(filename, O_RDONLY);
|
|
if (fd < 0) {
|
|
uwsgi_error_open(filename);
|
|
return -1;
|
|
}
|
|
|
|
EV_SET(&kev, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR, NOTE_WRITE | NOTE_DELETE | NOTE_EXTEND | NOTE_ATTRIB | NOTE_RENAME | NOTE_REVOKE, 0, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
*id = fd;
|
|
|
|
uwsgi_log("added new file to monitor %s\n", filename);
|
|
|
|
return fd;
|
|
}
|
|
|
|
struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ushared->files_monitored_cnt; i++) {
|
|
if (ushared->files_monitored[i].registered) {
|
|
if (ushared->files_monitored[i].fd == id) {
|
|
return &ushared->files_monitored[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_FILEMONITOR_USE_INOTIFY
|
|
|
|
|
|
#ifdef OBSOLETE_LINUX_KERNEL
|
|
int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
|
return -1;
|
|
}
|
|
struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
|
return NULL;
|
|
}
|
|
#else
|
|
#include <sys/inotify.h>
|
|
|
|
int event_queue_add_file_monitor(int eq, char *filename, int *id) {
|
|
|
|
int ifd = -1;
|
|
int i;
|
|
int add_to_queue = 0;
|
|
|
|
for (i = 0; i < ushared->files_monitored_cnt; i++) {
|
|
if (ushared->files_monitored[i].registered) {
|
|
ifd = ushared->files_monitored[0].fd;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ifd == -1) {
|
|
ifd = inotify_init();
|
|
if (ifd < 0) {
|
|
uwsgi_error("inotify_init()");
|
|
return -1;
|
|
}
|
|
add_to_queue = 1;
|
|
}
|
|
|
|
*id = inotify_add_watch(ifd, filename, IN_ATTRIB | IN_CREATE | IN_DELETE | IN_DELETE_SELF | IN_MODIFY | IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO);
|
|
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("added watch %d for filename %s\n", *id, filename);
|
|
#endif
|
|
|
|
if (add_to_queue) {
|
|
if (event_queue_add_fd_read(eq, ifd)) {
|
|
return -1;
|
|
}
|
|
}
|
|
return ifd;
|
|
}
|
|
|
|
struct uwsgi_fmon *event_queue_ack_file_monitor(int eq, int id) {
|
|
|
|
ssize_t rlen = 0;
|
|
struct inotify_event ie, *bie, *iie;
|
|
int i, j;
|
|
int items = 0;
|
|
|
|
unsigned int isize = sizeof(struct inotify_event);
|
|
struct uwsgi_fmon *uf = NULL;
|
|
|
|
if (ioctl(id, FIONREAD, &isize) < 0) {
|
|
uwsgi_error("ioctl()");
|
|
return NULL;
|
|
}
|
|
|
|
if (isize > sizeof(struct inotify_event)) {
|
|
bie = uwsgi_malloc(isize);
|
|
rlen = read(id, bie, isize);
|
|
}
|
|
else {
|
|
rlen = read(id, &ie, sizeof(struct inotify_event));
|
|
bie = &ie;
|
|
}
|
|
|
|
if (rlen < 0) {
|
|
uwsgi_error("read()");
|
|
}
|
|
else {
|
|
items = isize / (sizeof(struct inotify_event));
|
|
#ifdef UWSGI_DEBUG
|
|
uwsgi_log("inotify returned %d items\n", items);
|
|
#endif
|
|
for (j = 0; j < items; j++) {
|
|
iie = &bie[j];
|
|
for (i = 0; i < ushared->files_monitored_cnt; i++) {
|
|
if (ushared->files_monitored[i].registered) {
|
|
if (ushared->files_monitored[i].fd == id && ushared->files_monitored[i].id == iie->wd) {
|
|
uf = &ushared->files_monitored[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (items > 1) {
|
|
free(bie);
|
|
}
|
|
|
|
return uf;
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_TIMER_USE_TIMERFD
|
|
|
|
#ifndef UWSGI_EVENT_TIMER_USE_TIMERFD_NOINC
|
|
#include <sys/timerfd.h>
|
|
#endif
|
|
|
|
#ifndef TFD_CLOEXEC
|
|
|
|
// timerfd support
|
|
|
|
enum {
|
|
TFD_CLOEXEC = 02000000,
|
|
#define TFD_CLOEXEC TFD_CLOEXEC
|
|
TFD_NONBLOCK = 04000
|
|
#define TFD_NONBLOCK TFD_NONBLOCK
|
|
};
|
|
|
|
|
|
/* Bits to be set in the FLAGS parameter of `timerfd_settime'. */
|
|
enum {
|
|
TFD_TIMER_ABSTIME = 1 << 0
|
|
#define TFD_TIMER_ABSTIME TFD_TIMER_ABSTIME
|
|
};
|
|
|
|
|
|
static int timerfd_create(clockid_t __clock_id, int __flags) {
|
|
#ifdef __amd64__
|
|
return syscall(283, __clock_id, __flags);
|
|
#elif defined(__i386__)
|
|
return syscall(322, __clock_id, __flags);
|
|
#elif defined(__arm__)
|
|
return syscall(350, __clock_id, __flags);
|
|
#else
|
|
return -1;
|
|
#endif
|
|
}
|
|
|
|
static int timerfd_settime(int __ufd, int __flags, __const struct itimerspec *__utmr, struct itimerspec *__otmr) {
|
|
#ifdef __amd64__
|
|
return syscall(286, __ufd, __flags, __utmr, __otmr);
|
|
#elif defined(__i386__)
|
|
return syscall(325, __ufd, __flags, __utmr, __otmr);
|
|
#elif defined(__arm__)
|
|
return syscall(353, __ufd, __flags, __utmr, __otmr);
|
|
#else
|
|
return -1;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
int event_queue_add_timer(int eq, int *id, int sec) {
|
|
|
|
struct itimerspec it;
|
|
int tfd = timerfd_create(CLOCK_REALTIME, TFD_CLOEXEC);
|
|
|
|
if (tfd < 0) {
|
|
uwsgi_error("timerfd_create()");
|
|
return -1;
|
|
}
|
|
|
|
it.it_value.tv_sec = sec;
|
|
it.it_value.tv_nsec = 0;
|
|
|
|
it.it_interval.tv_sec = sec;
|
|
it.it_interval.tv_nsec = 0;
|
|
|
|
if (timerfd_settime(tfd, 0, &it, NULL)) {
|
|
uwsgi_error("timerfd_settime()");
|
|
close(tfd);
|
|
return -1;
|
|
}
|
|
|
|
*id = tfd;
|
|
if (event_queue_add_fd_read(eq, tfd)) {
|
|
return -1;
|
|
}
|
|
return tfd;
|
|
}
|
|
|
|
struct uwsgi_timer *event_queue_ack_timer(int id) {
|
|
|
|
int i;
|
|
ssize_t rlen;
|
|
uint64_t counter;
|
|
struct uwsgi_timer *ut = NULL;
|
|
|
|
for (i = 0; i < ushared->timers_cnt; i++) {
|
|
if (ushared->timers[i].registered) {
|
|
if (ushared->timers[i].id == id) {
|
|
ut = &ushared->timers[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
rlen = read(id, &counter, sizeof(uint64_t));
|
|
|
|
if (rlen < 0) {
|
|
uwsgi_error("read()");
|
|
}
|
|
|
|
return ut;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_TIMER_USE_NONE
|
|
int event_queue_add_timer(int eq, int *id, int sec) {
|
|
return -1;
|
|
}
|
|
struct uwsgi_timer *event_queue_ack_timer(int id) {
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
#ifdef UWSGI_EVENT_TIMER_USE_PORT
|
|
int event_queue_add_timer(int eq, int *id, int sec) {
|
|
|
|
static int timer_id = 0xffffff00;
|
|
port_notify_t pnotif;
|
|
struct sigevent sigev;
|
|
itimerspec_t it;
|
|
timer_t tid;
|
|
|
|
timer_id++;
|
|
|
|
pnotif.portnfy_port = eq;
|
|
pnotif.portnfy_user = (void *) (long) timer_id;
|
|
|
|
sigev.sigev_notify = SIGEV_PORT;
|
|
sigev.sigev_value.sival_ptr = &pnotif;
|
|
|
|
if (timer_create(CLOCK_REALTIME, &sigev, &tid) < 0) {
|
|
uwsgi_error("timer_create()");
|
|
return -1;
|
|
}
|
|
|
|
|
|
it.it_value.tv_sec = sec;
|
|
it.it_value.tv_nsec = 0;
|
|
|
|
it.it_interval.tv_sec = sec;
|
|
it.it_interval.tv_nsec = 0;
|
|
|
|
if (timer_settime(tid, 0, &it, NULL) < 0) {
|
|
uwsgi_error("timer_settime()");
|
|
return -1;
|
|
}
|
|
|
|
*id = timer_id;
|
|
|
|
return *id;
|
|
|
|
}
|
|
|
|
struct uwsgi_timer *event_queue_ack_timer(int id) {
|
|
|
|
int i;
|
|
struct uwsgi_timer *ut = NULL;
|
|
|
|
for (i = 0; i < uwsgi.shared->timers_cnt; i++) {
|
|
if (uwsgi.shared->timers[i].registered) {
|
|
if (uwsgi.shared->timers[i].id == id) {
|
|
ut = &uwsgi.shared->timers[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return ut;
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef UWSGI_EVENT_TIMER_USE_KQUEUE
|
|
int event_queue_add_timer(int eq, int *id, int sec) {
|
|
|
|
static int timer_id = 0xffffff00;
|
|
struct kevent kev;
|
|
|
|
*id = timer_id;
|
|
timer_id++;
|
|
|
|
EV_SET(&kev, *id, EVFILT_TIMER, EV_ADD, 0, sec * 1000, 0);
|
|
if (kevent(eq, &kev, 1, NULL, 0, NULL) < 0) {
|
|
uwsgi_error("kevent()");
|
|
return -1;
|
|
}
|
|
|
|
return *id;
|
|
}
|
|
|
|
struct uwsgi_timer *event_queue_ack_timer(int id) {
|
|
|
|
int i;
|
|
struct uwsgi_timer *ut = NULL;
|
|
|
|
for (i = 0; i < uwsgi.shared->timers_cnt; i++) {
|
|
if (uwsgi.shared->timers[i].registered) {
|
|
if (uwsgi.shared->timers[i].id == id) {
|
|
ut = &uwsgi.shared->timers[i];
|
|
}
|
|
}
|
|
}
|
|
|
|
return ut;
|
|
|
|
}
|
|
#endif
|
|
|
|
int event_queue_read() {
|
|
return UWSGI_EVENT_IN;
|
|
}
|
|
|
|
int event_queue_write() {
|
|
return UWSGI_EVENT_OUT;
|
|
}
|