Create one KQUEUE for the specified kqfd. Allocate and initialize a KQUEUE object for a kqueue fd.
| 216 | // Create one KQUEUE for the specified kqfd. |
| 217 | // Allocate and initialize a KQUEUE object for a kqueue fd. |
| 218 | static KQUEUE *kqueue_alloc(int kqfd) |
| 219 | { |
| 220 | KQUEUE *kq; |
| 221 | int maxfd = open_limit(0), i; |
| 222 | |
| 223 | if (maxfd <= 0) { |
| 224 | msg_fatal("%s(%d), %s: open_limit error %s", |
| 225 | __FILE__, __LINE__, __FUNCTION__, last_serror()); |
| 226 | } |
| 227 | |
| 228 | /* Using thread local to store the kqueue handles for each thread. */ |
| 229 | if (__kqfds == NULL) { |
| 230 | if (pthread_once(&__once_control, thread_init) != 0) { |
| 231 | msg_error("%s(%d), %s: pthread_once error %s", |
| 232 | __FILE__, __LINE__, __FUNCTION__, last_serror()); |
| 233 | return NULL; |
| 234 | } |
| 235 | |
| 236 | __kqfds = array_create(5, ARRAY_F_UNORDER); |
| 237 | if (thread_self() == main_thread_self()) { |
| 238 | __main_kqfds = __kqfds; |
| 239 | atexit(main_thread_free); |
| 240 | } else if (pthread_setspecific(__once_key, __kqfds) != 0) { |
| 241 | msg_error("pthread_setspecific error!"); |
| 242 | return NULL; |
| 243 | } |
| 244 | } |
| 245 | |
| 246 | kq = (KQUEUE*) mem_malloc(sizeof(KQUEUE)); |
| 247 | array_append(__kqfds, kq); |
| 248 | |
| 249 | kq->kqfd = kqfd; |
| 250 | kq->nfds = maxfd; |
| 251 | kq->fds = (KQUEUE_CTX **) mem_malloc(maxfd * sizeof(KQUEUE_CTX *)); |
| 252 | |
| 253 | for (i = 0; i < maxfd; i++) { |
| 254 | kq->fds[i] = NULL; |
| 255 | } |
| 256 | |
| 257 | ring_init(&kq->kes); |
| 258 | return kq; |
| 259 | } |
| 260 | |
| 261 | // Release a KQUEUE object and its fd table. |
| 262 | static void kqueue_free(KQUEUE *kq) |
no test coverage detected
searching dependent graphs…