Advertisement
Guest User

Untitled

a guest
May 22nd, 2019
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.03 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <sys/epoll.h>
  3. #include <sys/stat.h>
  4. #include <fcntl.h>
  5. #include <stdbool.h>
  6. #include <stdint.h>
  7. #include <errno.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11.  
  12. static void
  13. make_non_blocking (int fd) {
  14. int flags = fcntl(fd, F_GETFL);
  15. fcntl(fd, F_SETFL, flags | O_NONBLOCK);
  16. }
  17.  
  18. enum {
  19. InitialCapacity = 65536,
  20. MaxPendingEvents = 10000
  21. };
  22.  
  23. typedef struct {
  24. int fd;
  25. size_t count;
  26. bool done;
  27. } data_t;
  28.  
  29. static data_t*
  30. create_event_data (int epoll_fd, int fd) {
  31. make_non_blocking(fd);
  32. data_t* data = calloc(1, sizeof(*data));
  33. data->fd = fd;
  34.  
  35. struct epoll_event event_ready_read;
  36. event_ready_read.events = EPOLLIN;
  37. event_ready_read.data.ptr = data;
  38. epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &event_ready_read);
  39.  
  40. return data;
  41. }
  42.  
  43. static void
  44. process_pair_ready_read (data_t* data) {
  45. char buffer[4096];
  46. ssize_t cnt = read(data->fd, buffer, sizeof(buffer));
  47. if (cnt > 0) {
  48. data->count += cnt;
  49. } else if (cnt == 0) {
  50. data->done = true;
  51. close(data->fd);
  52. }
  53. }
  54.  
  55. static void
  56. process_epoll_event (struct epoll_event *event, size_t *files_left) {
  57. const uint32_t mask = event->events;
  58. data_t *data = event->data.ptr;
  59.  
  60. if (mask & EPOLLIN) {
  61. process_pair_ready_read(data);
  62. }
  63.  
  64. if (data->done) {
  65. *files_left -= 1;
  66. }
  67. }
  68.  
  69. extern size_t
  70. read_data_and_count (size_t N, int in[N]) {
  71. data_t **entries = calloc(N, sizeof(*entries));
  72.  
  73. int epoll_fd = epoll_create1(0);
  74.  
  75. for (size_t i = 0; i < N; ++i) {
  76. entries[i] = create_event_data(epoll_fd, in[i]);
  77. }
  78.  
  79. size_t files_left = N;
  80. struct epoll_event pending[MaxPendingEvents];
  81. while (files_left > 0) {
  82. int n = epoll_wait(epoll_fd, pending, MaxPendingEvents, -1);
  83. for (int i = 0; i < n; ++i) {
  84. process_epoll_event(&pending[i], &files_left);
  85. }
  86. }
  87.  
  88. close(epoll_fd);
  89.  
  90. size_t result = 0;
  91. for (int i = 0; i < N; ++i) {
  92. result += entries[i]->count;
  93. free(entries[i]);
  94. }
  95.  
  96. return result;
  97. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement