A clone of btpd with my configuration changes.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

98 lignes
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. }