代码语言:javascript复制
// 创建轮询数组包装器
/**
* typedef struct pollfd {
* SOCKET fd; // 4 bytes
* short events; // 2 bytes
* } pollfd_t;
*/
pollWrapper = new PollArrayWrapper(INIT_CAP);
代码语言:javascript复制PollArrayWrapper(int newSize) {
int allocationSize = newSize * SIZE_POLLFD;
// 给轮询数组分配本地对象(分配内存)
pollArray = new AllocatedNativeObject(allocationSize, true);
pollArrayAddress = pollArray.address();
this.size = newSize;
}
代码语言:javascript复制// 本地对象(内存对象)
protected NativeObject(int size, boolean pageAligned) {
if (!pageAligned) {
this.allocationAddress = unsafe.allocateMemory(size);
this.address = this.allocationAddress;
} else {
int ps = pageSize();
// 使用非安全操作工具, 直接分配JAVA堆外内存
long a = unsafe.allocateMemory(size ps);
this.allocationAddress = a;
// 使用位运算& 进行页对齐
this.address = a ps - (a & (ps - 1));
}
}
pollArray添加需要唤醒的Socket
代码语言:javascript复制// 添加需要唤醒的文件描述符
pollWrapper.addWakeupSocket(wakeupSourceFd, 0);
代码语言:javascript复制// 添加文件描述符
void addWakeupSocket(int fdVal, int index) {
// 在特定位置index, PUT文件描述符
putDescriptor(index, fdVal);
// 在特定位置index, PUT事件类型(POLLIN 代表:普通数据读取)
putEventOps(index, Net.POLLIN);
}
void putDescriptor(int i, int fd) {
// 根据index下标位和偏移量, 计算要PUT fd到的内存位置
pollArray.putInt(SIZE_POLLFD * i FD_OFFSET, fd);
}
void putEventOps(int i, int event) {
// 根据index下标位和偏移量, 计算要PUT event到的内存位置
pollArray.putShort(SIZE_POLLFD * i EVENT_OFFSET, (short)event);
}