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> 11*ab4c1f9fSAlexey Budankov #include <string.h> 121b85337dSArnaldo Carvalho de Melo 131b85337dSArnaldo Carvalho de Melo void fdarray__init(struct fdarray *fda, int nr_autogrow) 141b85337dSArnaldo Carvalho de Melo { 151b85337dSArnaldo Carvalho de Melo fda->entries = NULL; 162171a925SArnaldo Carvalho de Melo fda->priv = NULL; 171b85337dSArnaldo Carvalho de Melo fda->nr = fda->nr_alloc = 0; 181b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 191b85337dSArnaldo Carvalho de Melo } 201b85337dSArnaldo Carvalho de Melo 211b85337dSArnaldo Carvalho de Melo int fdarray__grow(struct fdarray *fda, int nr) 221b85337dSArnaldo Carvalho de Melo { 23*ab4c1f9fSAlexey Budankov struct priv *priv; 241b85337dSArnaldo Carvalho de Melo int nr_alloc = fda->nr_alloc + nr; 252171a925SArnaldo Carvalho de Melo size_t psize = sizeof(fda->priv[0]) * nr_alloc; 261b85337dSArnaldo Carvalho de Melo size_t size = sizeof(struct pollfd) * nr_alloc; 271b85337dSArnaldo Carvalho de Melo struct pollfd *entries = realloc(fda->entries, size); 281b85337dSArnaldo Carvalho de Melo 291b85337dSArnaldo Carvalho de Melo if (entries == NULL) 301b85337dSArnaldo Carvalho de Melo return -ENOMEM; 311b85337dSArnaldo Carvalho de Melo 322171a925SArnaldo Carvalho de Melo priv = realloc(fda->priv, psize); 332171a925SArnaldo Carvalho de Melo if (priv == NULL) { 342171a925SArnaldo Carvalho de Melo free(entries); 352171a925SArnaldo Carvalho de Melo return -ENOMEM; 362171a925SArnaldo Carvalho de Melo } 372171a925SArnaldo Carvalho de Melo 38*ab4c1f9fSAlexey Budankov memset(&entries[fda->nr_alloc], 0, sizeof(struct pollfd) * nr); 39*ab4c1f9fSAlexey Budankov memset(&priv[fda->nr_alloc], 0, sizeof(fda->priv[0]) * nr); 40*ab4c1f9fSAlexey Budankov 411b85337dSArnaldo Carvalho de Melo fda->nr_alloc = nr_alloc; 421b85337dSArnaldo Carvalho de Melo fda->entries = entries; 432171a925SArnaldo Carvalho de Melo fda->priv = priv; 441b85337dSArnaldo Carvalho de Melo return 0; 451b85337dSArnaldo Carvalho de Melo } 461b85337dSArnaldo Carvalho de Melo 471b85337dSArnaldo Carvalho de Melo struct fdarray *fdarray__new(int nr_alloc, int nr_autogrow) 481b85337dSArnaldo Carvalho de Melo { 491b85337dSArnaldo Carvalho de Melo struct fdarray *fda = calloc(1, sizeof(*fda)); 501b85337dSArnaldo Carvalho de Melo 511b85337dSArnaldo Carvalho de Melo if (fda != NULL) { 521b85337dSArnaldo Carvalho de Melo if (fdarray__grow(fda, nr_alloc)) { 531b85337dSArnaldo Carvalho de Melo free(fda); 541b85337dSArnaldo Carvalho de Melo fda = NULL; 551b85337dSArnaldo Carvalho de Melo } else { 561b85337dSArnaldo Carvalho de Melo fda->nr_autogrow = nr_autogrow; 571b85337dSArnaldo Carvalho de Melo } 581b85337dSArnaldo Carvalho de Melo } 591b85337dSArnaldo Carvalho de Melo 601b85337dSArnaldo Carvalho de Melo return fda; 611b85337dSArnaldo Carvalho de Melo } 621b85337dSArnaldo Carvalho de Melo 631b85337dSArnaldo Carvalho de Melo void fdarray__exit(struct fdarray *fda) 641b85337dSArnaldo Carvalho de Melo { 651b85337dSArnaldo Carvalho de Melo free(fda->entries); 662171a925SArnaldo Carvalho de Melo free(fda->priv); 671b85337dSArnaldo Carvalho de Melo fdarray__init(fda, 0); 681b85337dSArnaldo Carvalho de Melo } 691b85337dSArnaldo Carvalho de Melo 701b85337dSArnaldo Carvalho de Melo void fdarray__delete(struct fdarray *fda) 711b85337dSArnaldo Carvalho de Melo { 721b85337dSArnaldo Carvalho de Melo fdarray__exit(fda); 731b85337dSArnaldo Carvalho de Melo free(fda); 741b85337dSArnaldo Carvalho de Melo } 751b85337dSArnaldo Carvalho de Melo 76*ab4c1f9fSAlexey Budankov int fdarray__add(struct fdarray *fda, int fd, short revents, enum fdarray_flags flags) 771b85337dSArnaldo Carvalho de Melo { 782171a925SArnaldo Carvalho de Melo int pos = fda->nr; 792171a925SArnaldo Carvalho de Melo 801b85337dSArnaldo Carvalho de Melo if (fda->nr == fda->nr_alloc && 811b85337dSArnaldo Carvalho de Melo fdarray__grow(fda, fda->nr_autogrow) < 0) 821b85337dSArnaldo Carvalho de Melo return -ENOMEM; 831b85337dSArnaldo Carvalho de Melo 841b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].fd = fd; 851b85337dSArnaldo Carvalho de Melo fda->entries[fda->nr].events = revents; 86*ab4c1f9fSAlexey Budankov fda->priv[fda->nr].flags = flags; 871b85337dSArnaldo Carvalho de Melo fda->nr++; 882171a925SArnaldo Carvalho de Melo return pos; 891b85337dSArnaldo Carvalho de Melo } 901b85337dSArnaldo Carvalho de Melo 912171a925SArnaldo Carvalho de Melo int fdarray__filter(struct fdarray *fda, short revents, 92258e4bfcSWang Nan void (*entry_destructor)(struct fdarray *fda, int fd, void *arg), 93258e4bfcSWang Nan void *arg) 941b85337dSArnaldo Carvalho de Melo { 951b85337dSArnaldo Carvalho de Melo int fd, nr = 0; 961b85337dSArnaldo Carvalho de Melo 971b85337dSArnaldo Carvalho de Melo if (fda->nr == 0) 981b85337dSArnaldo Carvalho de Melo return 0; 991b85337dSArnaldo Carvalho de Melo 1001b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) { 10159b4412fSAlexey Budankov if (!fda->entries[fd].events) 10259b4412fSAlexey Budankov continue; 10359b4412fSAlexey Budankov 1042171a925SArnaldo Carvalho de Melo if (fda->entries[fd].revents & revents) { 1052171a925SArnaldo Carvalho de Melo if (entry_destructor) 106258e4bfcSWang Nan entry_destructor(fda, fd, arg); 1071b85337dSArnaldo Carvalho de Melo 10859b4412fSAlexey Budankov fda->entries[fd].revents = fda->entries[fd].events = 0; 1092171a925SArnaldo Carvalho de Melo continue; 1102171a925SArnaldo Carvalho de Melo } 1112171a925SArnaldo Carvalho de Melo 1121b85337dSArnaldo Carvalho de Melo ++nr; 1131b85337dSArnaldo Carvalho de Melo } 1141b85337dSArnaldo Carvalho de Melo 11559b4412fSAlexey Budankov return nr; 1161b85337dSArnaldo Carvalho de Melo } 1171b85337dSArnaldo Carvalho de Melo 1181b85337dSArnaldo Carvalho de Melo int fdarray__poll(struct fdarray *fda, int timeout) 1191b85337dSArnaldo Carvalho de Melo { 1201b85337dSArnaldo Carvalho de Melo return poll(fda->entries, fda->nr, timeout); 1211b85337dSArnaldo Carvalho de Melo } 1221b85337dSArnaldo Carvalho de Melo 1231b85337dSArnaldo Carvalho de Melo int fdarray__fprintf(struct fdarray *fda, FILE *fp) 1241b85337dSArnaldo Carvalho de Melo { 1251b85337dSArnaldo Carvalho de Melo int fd, printed = fprintf(fp, "%d [ ", fda->nr); 1261b85337dSArnaldo Carvalho de Melo 1271b85337dSArnaldo Carvalho de Melo for (fd = 0; fd < fda->nr; ++fd) 1281b85337dSArnaldo Carvalho de Melo printed += fprintf(fp, "%s%d", fd ? ", " : "", fda->entries[fd].fd); 1291b85337dSArnaldo Carvalho de Melo 1301b85337dSArnaldo Carvalho de Melo return printed + fprintf(fp, " ]"); 1311b85337dSArnaldo Carvalho de Melo } 132