void test_kevent_timer_dispatch(void) { struct kevent kev; test_no_kevents(kqfd); kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_ADD | EV_DISPATCH, 0, 800, NULL); /* Get one event */ kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Confirm that the knote is disabled */ sleep(1); test_no_kevents(kqfd); /* Enable the knote and make sure no events are pending */ kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_ENABLE | EV_DISPATCH, 0, 800, NULL); test_no_kevents(kqfd); /* Get the next event */ sleep(1); kev.flags = EV_ADD | EV_CLEAR | EV_DISPATCH; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Remove the knote and ensure the event no longer fires */ kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); sleep(1); test_no_kevents(kqfd); }
static void disable_and_enable(void) { const char *test_id = "kevent(EVFILT_USER, EV_DISABLE and EV_ENABLE)"; struct kevent kev; test_begin(test_id); test_no_kevents(); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL); /* Trigger the event, but since it is disabled, nothing will happen. */ kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); test_no_kevents(); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL); kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.flags = EV_CLEAR; kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kevent_cmp(&kev, kevent_get(kqfd)); success(); }
void test_kevent_socket_dispatch(struct test_context *ctx) { struct kevent kev, ret; /* Re-add the watch and make sure no events are pending */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ADD | EV_DISPATCH, 0, 0, &ctx->client_fd); test_no_kevents(ctx->kqfd); /* The event will occur only once, even though EV_CLEAR is not specified. */ kevent_socket_fill(ctx); kev.data = 1; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); /* Re-enable the kevent */ /* FIXME- is EV_DISPATCH needed when rearming ? */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ENABLE | EV_DISPATCH, 0, 0, &ctx->client_fd); kev.data = 1; kev.flags = EV_ADD | EV_DISPATCH; /* FIXME: may not be portable */ kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); /* Since the knote is disabled, the EV_DELETE operation succeeds. */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_DELETE, 0, 0, &ctx->client_fd); kevent_socket_drain(ctx); }
static void test_kevent_user_add_and_delete(struct test_context *ctx) { struct kevent kev; kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL); test_no_kevents(ctx->kqfd); }
void test_kevent_timer_get(void) { struct kevent kev; kevent_add(kqfd, &kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL); kev.flags |= EV_CLEAR; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); kevent_add(kqfd, &kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); }
static void add_and_delete(void) { const char *test_id = "kevent(EVFILT_USER, EV_ADD and EV_DELETE)"; struct kevent kev; test_begin(test_id); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); test_no_kevents(); kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL); test_no_kevents(); success(); }
void test_kevent_socket_oneshot(struct test_context *ctx) { struct kevent kev, ret; /* Re-add the watch and make sure no events are pending */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, &ctx->client_fd); test_no_kevents(ctx->kqfd); kevent_socket_fill(ctx); kev.data = 1; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); /* Verify that the kernel watch has been deleted */ kevent_socket_fill(ctx); test_no_kevents(ctx->kqfd); kevent_socket_drain(ctx); /* Verify that the kevent structure does not exist. */ kev.flags = EV_DELETE; if (kevent(ctx->kqfd, &kev, 1, NULL, 0, NULL) == 0) die("kevent() should have failed"); }
void test_kqueue_descriptor_is_pollable(void) { int kq, rv; struct kevent kev; fd_set fds; struct timeval tv; if ((kq = kqueue()) < 0) die("kqueue()"); test_no_kevents(kq); kevent_add(kq, &kev, 2, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 1000, NULL); test_no_kevents(kq); FD_ZERO(&fds); FD_SET(kq, &fds); tv.tv_sec = 5; tv.tv_usec = 0; rv = select(1, &fds, NULL, NULL, &tv); if (rv < 0) die("select() error"); if (rv == 0) die("select() no events"); if (!FD_ISSET(kq, &fds)) { die("descriptor is not ready for reading"); } close(kq); }
void test_kevent_socket_add(struct test_context *ctx) { struct kevent kev; kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ADD, 0, 0, &ctx->client_fd); }
void test_kevent_timer_add(void) { struct kevent kev; kevent_add(kqfd, &kev, 1, EVFILT_TIMER, EV_ADD, 0, 1000, NULL); }
static void event_trigger(void) { struct kevent kev; pid_t pid; test_begin("kevent(EVFILT_PROC, wait)"); /* Create a child that waits to be killed and then exits */ pid = fork(); if (pid == 0) { pause(); printf(" -- child caught signal, exiting\n"); exit(2); } printf(" -- child created (pid %d)\n", (int) pid); test_no_kevents(); kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL); /* Cause the child to exit, then retrieve the event */ printf(" -- killing process %d\n", (int) pid); if (kill(pid, SIGUSR1) < 0) err(1, "kill"); kevent_cmp(&kev, kevent_get(kqfd)); test_no_kevents(); success(); }
void zmq::kqueue_t::set_pollout (handle_t handle_) { poll_entry_t *pe = (poll_entry_t*) handle_; if (likely (!pe->flag_pollout)) { pe->flag_pollout = true; kevent_add (pe->fd, EVFILT_WRITE, pe); } }
void zmq::kqueue_t::set_pollin (handle_t handle_) { poll_entry_t *pe = (poll_entry_t*) handle_; if (likely (!pe->flag_pollin)) { pe->flag_pollin = true; kevent_add (pe->fd, EVFILT_READ, pe); } }
void test_kevent_timer_del(void) { struct kevent kev; kevent_add(kqfd, &kev, 1, EVFILT_TIMER, EV_DELETE, 0, 0, NULL); test_no_kevents(kqfd); }
static void test_kevent_user_get_hires(struct test_context *ctx) { struct kevent kev, ret; test_no_kevents(ctx->kqfd); /* Add the event, and then trigger it */ kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kev.flags = EV_CLEAR; kevent_get(&ret, ctx->kqfd); //FIXME: Shouldn't this be kevent_get_hires() ? kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); }
static void test_kevent_user_oneshot(struct test_context *ctx) { struct kevent kev, ret; test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL); puts(" -- event 1"); kevent_add(ctx->kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.flags = EV_ONESHOT; kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); }
void test_kevent_socket_eof(struct test_context *ctx) { struct kevent kev, ret; /* Re-add the watch and make sure no events are pending */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_ADD, 0, 0, &ctx->client_fd); test_no_kevents(ctx->kqfd); //if (shutdown(ctx->server_fd, SHUT_RDWR) < 0) // die("close(2)"); if (close(ctx->server_fd) < 0) die("close(2)"); kev.flags |= EV_EOF; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); /* Delete the watch */ kevent_add(ctx->kqfd, &kev, ctx->client_fd, EVFILT_READ, EV_DELETE, 0, 0, &ctx->client_fd); }
static void add_and_delete(void) { struct kevent kev; pid_t pid; /* Create a child that waits to be killed and then exits */ pid = fork(); if (pid == 0) { struct stat s; if (fstat(kqfd, &s) != -1) errx(1, "kqueue inherited across fork! (%s() at %s:%d)", __func__, __FILE__, __LINE__); pause(); exit(2); } printf(" -- child created (pid %d)\n", (int) pid); test_begin("kevent(EVFILT_PROC, EV_ADD)"); test_no_kevents(); kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_ADD, 0, 0, NULL); test_no_kevents(); success(); test_begin("kevent(EVFILT_PROC, EV_DELETE)"); sleep(1); test_no_kevents(); kevent_add(kqfd, &kev, pid, EVFILT_PROC, EV_DELETE, 0, 0, NULL); if (kill(pid, SIGKILL) < 0) err(1, "kill"); sleep(1); test_no_kevents(); success(); }
void test_kevent_user_dispatch(struct test_context *ctx) { struct kevent kev, ret; test_no_kevents(ctx->kqfd); /* Add the event, and then trigger it */ kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR | EV_DISPATCH, 0, 0, NULL); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); /* Retrieve one event */ kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kev.flags = EV_CLEAR; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); /* Confirm that the knote is disabled automatically */ test_no_kevents(ctx->kqfd); /* Re-enable the kevent */ /* FIXME- is EV_DISPATCH needed when rearming ? */ kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ENABLE | EV_CLEAR | EV_DISPATCH, 0, 0, NULL); test_no_kevents(ctx->kqfd); /* Trigger the event */ kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kev.flags = EV_CLEAR; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); /* Delete the watch */ kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_DELETE, 0, 0, NULL); test_no_kevents(ctx->kqfd); }
static void test_kevent_user_disable_and_enable(struct test_context *ctx) { struct kevent kev, ret; test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ADD, 0, 0, NULL); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_DISABLE, 0, 0, NULL); /* Trigger the event, but since it is disabled, nothing will happen. */ kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, EV_ENABLE, 0, 0, NULL); kevent_add(ctx->kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.flags = EV_CLEAR; kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); }
static void event_wait(void) { const char *test_id = "kevent(EVFILT_USER, wait)"; struct kevent kev; test_begin(test_id); test_no_kevents(); /* Add the event, and then trigger it */ kevent_add(kqfd, &kev, 1, EVFILT_USER, EV_ADD | EV_CLEAR, 0, 0, NULL); kevent_add(kqfd, &kev, 1, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kev.flags = EV_CLEAR; kevent_cmp(&kev, kevent_get(kqfd)); test_no_kevents(); success(); }
static void oneshot(void) { const char *test_id = "kevent(EVFILT_USER, EV_ONESHOT)"; struct kevent kev; test_begin(test_id); test_no_kevents(); kevent_add(kqfd, &kev, 2, EVFILT_USER, EV_ADD | EV_ONESHOT, 0, 0, NULL); puts(" -- event 1"); kevent_add(kqfd, &kev, 2, EVFILT_USER, 0, NOTE_TRIGGER, 0, NULL); kev.flags = EV_ONESHOT; kev.fflags &= ~NOTE_FFCTRLMASK; kev.fflags &= ~NOTE_TRIGGER; kevent_cmp(&kev, kevent_get(kqfd)); test_no_kevents(); success(); }
/* * Test if the data field returns 1 when a listen(2) socket has * a pending connection. */ void test_kevent_socket_listen_backlog(struct test_context *ctx) { struct kevent kev, ret; struct sockaddr_in sain; socklen_t sa_len = sizeof(sain); int one = 1; short port; int clnt, srvr; port = 14973 + ctx->iteration; /* Create a passive socket */ memset(&sain, 0, sizeof(sain)); sain.sin_family = AF_INET; sain.sin_port = htons(port); if ((srvr = socket(PF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket()"); if (setsockopt(srvr, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof(one)) != 0) err(1, "setsockopt()"); if (bind(srvr, (struct sockaddr *) &sain, sa_len) < 0) err(1, "bind-2", port); if (listen(srvr, 100) < 0) err(1, "listen()"); /* Watch for events on the socket */ test_no_kevents(ctx->kqfd); kevent_add(ctx->kqfd, &kev, srvr, EVFILT_READ, EV_ADD | EV_ONESHOT, 0, 0, NULL); test_no_kevents(ctx->kqfd); /* Simulate a client connecting to the server */ sain.sin_family = AF_INET; sain.sin_port = htons(port); sain.sin_addr.s_addr = inet_addr("127.0.0.1"); if ((clnt = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket()"); if (connect(clnt, (struct sockaddr *) &sain, sa_len) < 0) err(1, "connect()"); /* Verify that data=1 */ kev.data = 1; kevent_get(&ret, ctx->kqfd); kevent_cmp(&kev, &ret); test_no_kevents(ctx->kqfd); }
static void test_kevent_timer_oneshot(void) { struct kevent kev; test_no_kevents(kqfd); kevent_add(kqfd, &kev, 2, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 500,NULL); /* Retrieve the event */ kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Check if the event occurs again */ sleep(3); test_no_kevents(kqfd); }
static void test_kevent_timer_disable_and_enable(void) { struct kevent kev; test_no_kevents(kqfd); /* Add the watch and immediately disable it */ kevent_add(kqfd, &kev, 4, EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 2000,NULL); kev.flags = EV_DISABLE; kevent_update(kqfd, &kev); test_no_kevents(kqfd); /* Re-enable and check again */ kev.flags = EV_ENABLE; kevent_update(kqfd, &kev); kev.flags = EV_ADD | EV_CLEAR | EV_ONESHOT; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); }
static void test_kevent_timer_periodic(void) { struct kevent kev; test_no_kevents(kqfd); kevent_add(kqfd, &kev, 3, EVFILT_TIMER, EV_ADD, 0, 1000,NULL); /* Retrieve the event */ kev.flags = EV_ADD | EV_CLEAR; kev.data = 1; kevent_cmp(&kev, kevent_get(kqfd)); /* Check if the event occurs again */ sleep(1); kevent_cmp(&kev, kevent_get(kqfd)); /* Delete the event */ kev.flags = EV_DELETE; kevent_update(kqfd, &kev); }