191007045SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only 21b85337dSArnaldo Carvalho de Melo /* 31b85337dSArnaldo Carvalho de Melo * Copyright (C) 2014, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 41b85337dSArnaldo Carvalho de Melo */ 51b85337dSArnaldo Carvalho de Melo #include "array.h" 61b85337dSArnaldo Carvalho de Melo #include <errno.h> 71b85337dSArnaldo Carvalho de Melo #include <fcntl.h> 81b85337dSArnaldo Carvalho de Melo #include <poll.h> 91b85337dSArnaldo Carvalho de Melo #include <stdlib.h> 101b85337dSArnaldo Carvalho de Melo #include <unistd.h> 111b85337dSArnaldo Carvalho de Melo 121b85337dSArnaldo Carvalho de Melo void fdarray__init(struct fdarray *fda, int nr_autogrow) 131b85337dSArnaldo Carvalho de Melo { 141b85337dSArnaldo Carvalho de Melo fda->entries = NULL; 152171a925SArnaldo Carvalho de Melo fda->priv = NULL; 161b85337dSArnaldo Carvalho de Melo fda->nr = fda->nr_alloc = 0; 171b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 181b85337dSArnaldo Carvalho de Melo } 191b85337dSArnaldo Carvalho de Melo 201b85337dSArnaldo Carvalho de Melo int fdarray__grow(struct fdarray *fda, int nr) 211b85337dSArnaldo Carvalho de Melo { 222171a925SArnaldo Carvalho de Melo void *priv; 231b85337dSArnaldo Carvalho de Melo int nr_alloc = fda->nr_alloc + nr; 242171a925SArnaldo Carvalho de Melo size_t psize = sizeof(fda->priv[0]) * nr_alloc; 251b85337dSArnaldo Carvalho de Melo size_t size = sizeof(struct pollfd) * nr_alloc; 261b85337dSArnaldo Carvalho de Melo struct pollfd *entries = realloc(fda->entries, size); 271b85337dSArnaldo Carvalho de Melo 281b85337dSArnaldo Carvalho de Melo if (entries == NULL) 291b85337dSArnaldo Carvalho de Melo return -ENOMEM; 301b85337dSArnaldo Carvalho de Melo 312171a925SArnaldo Carvalho de Melo priv = realloc(fda->priv, psize); 322171a925SArnaldo Carvalho de Melo if (priv == NULL) { 332171a925SArnaldo Carvalho de Melo free(entries); 342171a925SArnaldo Carvalho de Melo return -ENOMEM; 352171a925SArnaldo Carvalho de Melo } 362171a925SArnaldo Carvalho de Melo 371b85337dSArnaldo Carvalho de Melo fda->nr_alloc = nr_alloc; 381b85337dSArnaldo Carvalho de Melo fda->entries = entries; 392171a925SArnaldo Carvalho de Melo fda->priv = priv; 401b85337dSArnaldo Carvalho de Melo return 0; 411b85337dSArnaldo Carvalho de Melo } 421b85337dSArnaldo Carvalho de Melo 431b85337dSArnaldo Carvalho de Melo struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow) 441b85337dSArnaldo Carvalho de Melo { 451b85337dSArnaldo Carvalho de Melo struct fdarray *fda = calloc(1, sizeof(*fda)); 461b85337dSArnaldo Carvalho de Melo 471b85337dSArnaldo Carvalho de Melo if (fda != NULL) { 481b85337dSArnaldo Carvalho de Melo if (fdarray__grow(fda, nr_alloc)) { 491b85337dSArnaldo Carvalho de Melo free(fda); 501b85337dSArnaldo Carvalho de Melo fda = NULL; 511b85337dSArnaldo Carvalho de Melo } else { 521b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 531b85337dSArnaldo Carvalho de Melo } 541b85337dSArnaldo Carvalho de Melo } 551b85337dSArnaldo Carvalho de Melo 561b85337dSArnaldo Carvalho de Melo return fda; 571b85337dSArnaldo Carvalho de Melo } 581b85337dSArnaldo Carvalho de Melo 591b85337dSArnaldo Carvalho de Melo void fdarray__exit(struct fdarray *fda) 601b85337dSArnaldo Carvalho de Melo { 611b85337dSArnaldo Carvalho de Melo free(fda->entries); 622171a925SArnaldo Carvalho de Melo free(fda->priv); 631b85337dSArnaldo Carvalho de Melo fdarray__init(fda, 0); 641b85337dSArnaldo Carvalho de Melo } 651b85337dSArnaldo Carvalho de Melo 661b85337dSArnaldo Carvalho de Melo void fdarray__delete(struct fdarray *fda) 671b85337dSArnaldo Carvalho de Melo { 681b85337dSArnaldo Carvalho de Melo fdarray__exit(fda); 691b85337dSArnaldo Carvalho de Melo free(fda); 701b85337dSArnaldo Carvalho de Melo } 711b85337dSArnaldo Carvalho de Melo 721b85337dSArnaldo Carvalho de Melo int fdarray__add(struct fdarray *fda, int fd, short revents) 731b85337dSArnaldo Carvalho de Melo { 742171a925SArnaldo Carvalho de Melo int pos = fda->nr; 752171a925SArnaldo Carvalho de Melo 761b85337dSArnaldo Carvalho de Melo if (fda->nr == fda->nr_alloc && 771b85337dSArnaldo Carvalho de Melo fdarray__grow(fda, fda->nr_autogrow) < 0) 781b85337dSArnaldo Carvalho de Melo return -ENOMEM; 791b85337dSArnaldo Carvalho de Melo 801b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].fd = fd; 811b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].events = revents; 821b85337dSArnaldo Carvalho de Melo fda->nr++; 832171a925SArnaldo Carvalho de Melo return pos; 841b85337dSArnaldo Carvalho de Melo } 851b85337dSArnaldo Carvalho de Melo 862171a925SArnaldo Carvalho de Melo int fdarray__filter(struct fdarray *fda, short revents, 87258e4bfcSWang Nan void (*entry_destructor)(struct fdarray *fda, int fd, void *arg), 88258e4bfcSWang Nan void *arg) 891b85337dSArnaldo Carvalho de Melo { 901b85337dSArnaldo Carvalho de Melo int fd, nr = 0; 911b85337dSArnaldo Carvalho de Melo 921b85337dSArnaldo Carvalho de Melo if (fda->nr == 0) 931b85337dSArnaldo Carvalho de Melo return 0; 941b85337dSArnaldo Carvalho de Melo 951b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) { 96*59b4412fSAlexey Budankov if (!fda->entries[fd].events) 97*59b4412fSAlexey Budankov continue; 98*59b4412fSAlexey Budankov 992171a925SArnaldo Carvalho de Melo if (fda->entries[fd].revents & revents) { 1002171a925SArnaldo Carvalho de Melo if (entry_destructor) 101258e4bfcSWang Nan entry_destructor(fda, fd, arg); 1021b85337dSArnaldo Carvalho de Melo 103*59b4412fSAlexey Budankov fda->entries[fd].revents = fda->entries[fd].events = 0; 1042171a925SArnaldo Carvalho de Melo continue; 1052171a925SArnaldo Carvalho de Melo } 1062171a925SArnaldo Carvalho de Melo 1071b85337dSArnaldo Carvalho de Melo ++nr; 1081b85337dSArnaldo Carvalho de Melo } 1091b85337dSArnaldo Carvalho de Melo 110*59b4412fSAlexey Budankov return nr; 1111b85337dSArnaldo Carvalho de Melo } 1121b85337dSArnaldo Carvalho de Melo 1131b85337dSArnaldo Carvalho de Melo int fdarray__poll(struct fdarray *fda, int timeout) 1141b85337dSArnaldo Carvalho de Melo { 1151b85337dSArnaldo Carvalho de Melo return poll(fda->entries, fda->nr, timeout); 1161b85337dSArnaldo Carvalho de Melo } 1171b85337dSArnaldo Carvalho de Melo 1181b85337dSArnaldo Carvalho de Melo int fdarray__fprintf(struct fdarray *fda, FILE *fp) 1191b85337dSArnaldo Carvalho de Melo { 1201b85337dSArnaldo Carvalho de Melo int fd, printed = fprintf(fp, "%d [ ", fda->nr); 1211b85337dSArnaldo Carvalho de Melo 1221b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) 1231b85337dSArnaldo Carvalho de Melo printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd); 1241b85337dSArnaldo Carvalho de Melo 1251b85337dSArnaldo Carvalho de Melo return printed + fprintf(fp, " ]"); 1261b85337dSArnaldo Carvalho de Melo } 127