A clone of btpd with my configuration changes.
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

98 строки
2.3 KiB

  1. #include "btpd.h"
  2. #include <pthread.h>
  3. struct ai_ctx {
  4. BTPDQ_ENTRY(ai_ctx) entry;
  5. struct addrinfo hints;
  6. struct addrinfo *res;
  7. char node[255], service[6];
  8. void (*cb)(void *, int, struct addrinfo *);
  9. void *arg;
  10. int cancel;
  11. int error;
  12. short port;
  13. };
  14. BTPDQ_HEAD(ai_ctx_tq, ai_ctx);
  15. static struct ai_ctx_tq m_aiq = BTPDQ_HEAD_INITIALIZER(m_aiq);
  16. static pthread_mutex_t m_aiq_lock;
  17. static pthread_cond_t m_aiq_cond;
  18. struct ai_ctx *
  19. btpd_addrinfo(const char *node, short port, struct addrinfo *hints,
  20. void (*cb)(void *, int, struct addrinfo *), void *arg)
  21. {
  22. struct ai_ctx *ctx = btpd_calloc(1, sizeof(*ctx));
  23. ctx->hints = *hints;
  24. ctx->cb = cb;
  25. ctx->arg = arg;
  26. snprintf(ctx->node, sizeof(ctx->node), "%s", node);
  27. ctx->port = port;
  28. if (port > 0)
  29. snprintf(ctx->service, sizeof(ctx->service), "%hd", port);
  30. pthread_mutex_lock(&m_aiq_lock);
  31. BTPDQ_INSERT_TAIL(&m_aiq, ctx, entry);
  32. pthread_mutex_unlock(&m_aiq_lock);
  33. pthread_cond_signal(&m_aiq_cond);
  34. return ctx;
  35. }
  36. void
  37. btpd_addrinfo_cancel(struct ai_ctx *ctx)
  38. {
  39. ctx->cancel = 1;
  40. }
  41. static void
  42. addrinfo_td_cb(void *arg)
  43. {
  44. struct ai_ctx *ctx = arg;
  45. if (!ctx->cancel)
  46. ctx->cb(ctx->arg, ctx->error, ctx->res);
  47. else if (ctx->error != 0)
  48. freeaddrinfo(ctx->res);
  49. free(ctx);
  50. }
  51. static void *
  52. addrinfo_td(void *arg)
  53. {
  54. struct ai_ctx *ctx;
  55. char *service;
  56. while (1) {
  57. pthread_mutex_lock(&m_aiq_lock);
  58. while (BTPDQ_EMPTY(&m_aiq))
  59. pthread_cond_wait(&m_aiq_cond, &m_aiq_lock);
  60. ctx = BTPDQ_FIRST(&m_aiq);
  61. BTPDQ_REMOVE(&m_aiq, ctx, entry);
  62. pthread_mutex_unlock(&m_aiq_lock);
  63. service = ctx->port > 0 ? ctx->service : NULL;
  64. ctx->error = getaddrinfo(ctx->node, service, &ctx->hints, &ctx->res);
  65. td_post_begin();
  66. td_post(addrinfo_td_cb, ctx);
  67. td_post_end();
  68. }
  69. }
  70. static void
  71. errdie(int err, const char *str)
  72. {
  73. if (err != 0)
  74. btpd_err("addrinfo_init: %s (%s).\n", str, strerror(errno));
  75. }
  76. void
  77. addrinfo_init(void)
  78. {
  79. pthread_t td;
  80. errdie(pthread_mutex_init(&m_aiq_lock, NULL), "pthread_mutex_init");
  81. errdie(pthread_cond_init(&m_aiq_cond, NULL), "pthread_cond_init");
  82. errdie(pthread_create(&td, NULL, addrinfo_td, NULL), "pthread_create");
  83. }