poll.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* Licensed to the Apache Software Foundation (ASF) under one or more
  2. * contributor license agreements. See the NOTICE file distributed with
  3. * this work for additional information regarding copyright ownership.
  4. * The ASF licenses this file to You under the Apache License, Version 2.0
  5. * (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "fspr.h"
  17. #include "fspr_poll.h"
  18. #include "fspr_arch_networkio.h"
  19. APR_DECLARE(fspr_status_t) fspr_poll(fspr_pollfd_t *aprset, fspr_int32_t num,
  20. fspr_int32_t *nsds, fspr_interval_time_t timeout)
  21. {
  22. int *pollset;
  23. int i;
  24. int num_read = 0, num_write = 0, num_except = 0, num_total;
  25. int pos_read, pos_write, pos_except;
  26. for (i = 0; i < num; i++) {
  27. if (aprset[i].desc_type == APR_POLL_SOCKET) {
  28. num_read += (aprset[i].reqevents & APR_POLLIN) != 0;
  29. num_write += (aprset[i].reqevents & APR_POLLOUT) != 0;
  30. num_except += (aprset[i].reqevents & APR_POLLPRI) != 0;
  31. }
  32. }
  33. num_total = num_read + num_write + num_except;
  34. pollset = alloca(sizeof(int) * num_total);
  35. memset(pollset, 0, sizeof(int) * num_total);
  36. pos_read = 0;
  37. pos_write = num_read;
  38. pos_except = pos_write + num_write;
  39. for (i = 0; i < num; i++) {
  40. if (aprset[i].desc_type == APR_POLL_SOCKET) {
  41. if (aprset[i].reqevents & APR_POLLIN) {
  42. pollset[pos_read++] = aprset[i].desc.s->socketdes;
  43. }
  44. if (aprset[i].reqevents & APR_POLLOUT) {
  45. pollset[pos_write++] = aprset[i].desc.s->socketdes;
  46. }
  47. if (aprset[i].reqevents & APR_POLLPRI) {
  48. pollset[pos_except++] = aprset[i].desc.s->socketdes;
  49. }
  50. aprset[i].rtnevents = 0;
  51. }
  52. }
  53. if (timeout > 0) {
  54. timeout /= 1000; /* convert microseconds to milliseconds */
  55. }
  56. i = select(pollset, num_read, num_write, num_except, timeout);
  57. (*nsds) = i;
  58. if ((*nsds) < 0) {
  59. return APR_FROM_OS_ERROR(sock_errno());
  60. }
  61. if ((*nsds) == 0) {
  62. return APR_TIMEUP;
  63. }
  64. pos_read = 0;
  65. pos_write = num_read;
  66. pos_except = pos_write + num_write;
  67. for (i = 0; i < num; i++) {
  68. if (aprset[i].desc_type == APR_POLL_SOCKET) {
  69. if (aprset[i].reqevents & APR_POLLIN) {
  70. if (pollset[pos_read++] > 0) {
  71. aprset[i].rtnevents |= APR_POLLIN;
  72. }
  73. }
  74. if (aprset[i].reqevents & APR_POLLOUT) {
  75. if (pollset[pos_write++] > 0) {
  76. aprset[i].rtnevents |= APR_POLLOUT;
  77. }
  78. }
  79. if (aprset[i].reqevents & APR_POLLPRI) {
  80. if (pollset[pos_except++] > 0) {
  81. aprset[i].rtnevents |= APR_POLLPRI;
  82. }
  83. }
  84. }
  85. }
  86. return APR_SUCCESS;
  87. }