| 321 | } |
| 322 | |
| 323 | void* run() { |
| 324 | const int initial_epfd = _epfd; |
| 325 | const size_t MAX_EVENTS = 32; |
| 326 | #if defined(OS_LINUX) |
| 327 | epoll_event* e = new (std::nothrow) epoll_event[MAX_EVENTS]; |
| 328 | #elif defined(OS_MACOSX) |
| 329 | typedef struct kevent KEVENT; |
| 330 | struct kevent* e = new (std::nothrow) KEVENT[MAX_EVENTS]; |
| 331 | #endif |
| 332 | if (NULL == e) { |
| 333 | LOG(FATAL) << "Fail to new epoll_event"; |
| 334 | return NULL; |
| 335 | } |
| 336 | |
| 337 | #if defined(OS_LINUX) |
| 338 | # ifndef BAIDU_KERNEL_FIXED_EPOLLONESHOT_BUG |
| 339 | DLOG(INFO) << "Use DEL+ADD instead of EPOLLONESHOT+MOD due to kernel bug. Performance will be much lower."; |
| 340 | # endif |
| 341 | #endif |
| 342 | while (!_stop) { |
| 343 | const int epfd = _epfd; |
| 344 | #if defined(OS_LINUX) |
| 345 | const int n = epoll_wait(epfd, e, MAX_EVENTS, -1); |
| 346 | #elif defined(OS_MACOSX) |
| 347 | const int n = kevent(epfd, NULL, 0, e, MAX_EVENTS, NULL); |
| 348 | #endif |
| 349 | if (_stop) { |
| 350 | break; |
| 351 | } |
| 352 | |
| 353 | if (n < 0) { |
| 354 | if (errno == EINTR) { |
| 355 | #ifndef NDEBUG |
| 356 | break_nums.fetch_add(1, butil::memory_order_relaxed); |
| 357 | int* p = &errno; |
| 358 | const char* b = berror(); |
| 359 | const char* b2 = berror(errno); |
| 360 | DLOG(FATAL) << "Fail to epoll epfd=" << epfd << ", " |
| 361 | << errno << " " << p << " " << b << " " << b2; |
| 362 | #endif |
| 363 | continue; |
| 364 | } |
| 365 | |
| 366 | PLOG(INFO) << "Fail to epoll epfd=" << epfd; |
| 367 | break; |
| 368 | } |
| 369 | |
| 370 | #if defined(OS_LINUX) |
| 371 | # ifndef BAIDU_KERNEL_FIXED_EPOLLONESHOT_BUG |
| 372 | for (int i = 0; i < n; ++i) { |
| 373 | epoll_ctl(epfd, EPOLL_CTL_DEL, e[i].data.fd, NULL); |
| 374 | } |
| 375 | # endif |
| 376 | #endif |
| 377 | for (int i = 0; i < n; ++i) { |
| 378 | #if defined(OS_LINUX) |
| 379 | # ifdef BAIDU_KERNEL_FIXED_EPOLLONESHOT_BUG |
| 380 | EpollButex* butex = static_cast<EpollButex*>(e[i].data.ptr); |
no test coverage detected