当前位置:网站首页>Gossip about redis source code 82
Gossip about redis source code 82
2022-07-03 23:24:00 【Tao song remains the same】
Look at the last kqueue, This is to be compatible with different platforms , In fact, you can understand it as select/poll/epoll Almost :
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
typedef struct aeApiState {
int kqfd;
struct kevent *events;
/* Events mask for merge read and write event.
* To reduce memory consumption, we use 2 bits to store the mask
* of an event, so that 1 byte will store the mask of 4 events. */
char *eventsMask;
} aeApiState;
#define EVENT_MASK_MALLOC_SIZE(sz) (((sz) + 3) / 4)
#define EVENT_MASK_OFFSET(fd) ((fd) % 4 * 2)
#define EVENT_MASK_ENCODE(fd, mask) (((mask) & 0x3) << EVENT_MASK_OFFSET(fd))
static inline int getEventMask(const char *eventsMask, int fd) {
return (eventsMask[fd/4] >> EVENT_MASK_OFFSET(fd)) & 0x3;
}
static inline void addEventMask(char *eventsMask, int fd, int mask) {
eventsMask[fd/4] |= EVENT_MASK_ENCODE(fd, mask);
}
static inline void resetEventMask(char *eventsMask, int fd) {
eventsMask[fd/4] &= ~EVENT_MASK_ENCODE(fd, 0x3);
}
static int aeApiCreate(aeEventLoop *eventLoop) {
aeApiState *state = zmalloc(sizeof(aeApiState));
if (!state) return -1;
state->events = zmalloc(sizeof(struct kevent)*eventLoop->setsize);
if (!state->events) {
zfree(state);
return -1;
}
state->kqfd = kqueue();
if (state->kqfd == -1) {
zfree(state->events);
zfree(state);
return -1;
}
anetCloexec(state->kqfd);
state->eventsMask = zmalloc(EVENT_MASK_MALLOC_SIZE(eventLoop->setsize));
memset(state->eventsMask, 0, EVENT_MASK_MALLOC_SIZE(eventLoop->setsize));
eventLoop->apidata = state;
return 0;
}
static int aeApiResize(aeEventLoop *eventLoop, int setsize) {
aeApiState *state = eventLoop->apidata;
state->events = zrealloc(state->events, sizeof(struct kevent)*setsize);
state->eventsMask = zrealloc(state->eventsMask, EVENT_MASK_MALLOC_SIZE(setsize));
memset(state->eventsMask, 0, EVENT_MASK_MALLOC_SIZE(setsize));
return 0;
}
static void aeApiFree(aeEventLoop *eventLoop) {
aeApiState *state = eventLoop->apidata;
close(state->kqfd);
zfree(state->events);
zfree(state->eventsMask);
zfree(state);
}
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
aeApiState *state = eventLoop->apidata;
struct kevent ke;
if (mask & AE_READABLE) {
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1;
}
if (mask & AE_WRITABLE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
if (kevent(state->kqfd, &ke, 1, NULL, 0, NULL) == -1) return -1;
}
return 0;
}
static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
aeApiState *state = eventLoop->apidata;
struct kevent ke;
if (mask & AE_READABLE) {
EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
kevent(state->kqfd, &ke, 1, NULL, 0, NULL);
}
if (mask & AE_WRITABLE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
kevent(state->kqfd, &ke, 1, NULL, 0, NULL);
}
}
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
aeApiState *state = eventLoop->apidata;
int retval, numevents = 0;
if (tvp != NULL) {
struct timespec timeout;
timeout.tv_sec = tvp->tv_sec;
timeout.tv_nsec = tvp->tv_usec * 1000;
retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize,
&timeout);
} else {
retval = kevent(state->kqfd, NULL, 0, state->events, eventLoop->setsize,
NULL);
}
if (retval > 0) {
int j;
/* Normally we execute the read event first and then the write event.
* When the barrier is set, we will do it reverse.
*
* However, under kqueue, read and write events would be separate
* events, which would make it impossible to control the order of
* reads and writes. So we store the event's mask we've got and merge
* the same fd events later. */
for (j = 0; j < retval; j++) {
struct kevent *e = state->events+j;
int fd = e->ident;
int mask = 0;
if (e->filter == EVFILT_READ) mask = AE_READABLE;
else if (e->filter == EVFILT_WRITE) mask = AE_WRITABLE;
addEventMask(state->eventsMask, fd, mask);
}
/* Re-traversal to merge read and write events, and set the fd's mask to
* 0 so that events are not added again when the fd is encountered again. */
numevents = 0;
for (j = 0; j < retval; j++) {
struct kevent *e = state->events+j;
int fd = e->ident;
int mask = getEventMask(state->eventsMask, fd);
if (mask) {
eventLoop->fired[numevents].fd = fd;
eventLoop->fired[numevents].mask = mask;
resetEventMask(state->eventsMask, fd);
numevents++;
}
}
}
return numevents;
}
static char *aeApiName(void) {
return "kqueue";
}
边栏推荐
- SQL data update
- How to prevent malicious crawling of information by one-to-one live broadcast source server
- [note] IPC traditional interprocess communication and binder interprocess communication principle
- Ningde times and BYD have refuted rumors one after another. Why does someone always want to harm domestic brands?
- The difference between single power amplifier and dual power amplifier
- Scratch uses runner Py run or debug crawler
- Format cluster and start cluster
- Ningde times and BYD have refuted rumors one after another. Why does someone always want to harm domestic brands?
- finalize finalization finally final
- QT creator source code learning note 05, how does the menu bar realize plug-in?
猜你喜欢

Deep learning ----- using NN, CNN, RNN neural network to realize MNIST data set processing

leetcode-43. String multiplication

Blue Bridge Cup -- Mason prime

The interviewer's biggest lie to deceive you, bypassing three years of less struggle

Hcip day 12 notes

Selenium check box

2/14 (regular expression, sed streaming editor)

How to quickly build high availability of service discovery

How to make icons easily

Take you to master the formatter of visual studio code
随机推荐
D28:maximum sum (maximum sum, translation)
The interviewer's biggest lie to deceive you, bypassing three years of less struggle
Pyqt5 sensitive word detection tool production, operator's Gospel
540. Single element in ordered array
What are the securities companies with the lowest Commission for stock account opening? Would you recommend it? Is it safe to open an account on your mobile phone
Errors taken 1 Position1 argument but 2 were given in Mockingbird
How can I get the Commission discount of stock trading account opening? Is it safe to open an account online
Ningde times and BYD have refuted rumors one after another. Why does someone always want to harm domestic brands?
. Net ADO splicing SQL statement with parameters
How to quickly build high availability of service discovery
In 2022, 6G development has indeed warmed up
Sort merge sort
[Android reverse] use DB browser to view and modify SQLite database (download DB browser installation package | install DB browser tool)
[network security] what is emergency response? What indicators should you pay attention to in emergency response?
Amway by head has this project management tool to improve productivity in a straight line
[source code] VB6 chat robot
C # basic knowledge (3)
Comparable interface and comparator interface
Minimum commission for stock account opening. Stock account opening is free. Is online account opening safe
Pyqt5 sensitive word detection tool production, operator's Gospel