ソースを参照

Add a thread for performing asynchronous getaddrinfo's.

master
Richard Nyberg 16年前
コミット
a34d4da755
4個のファイルの変更106行の追加1行の削除
  1. +1
    -1
      btpd/Makefile.am
  2. +97
    -0
      btpd/addrinfo.c
  3. +2
    -0
      btpd/btpd.c
  4. +6
    -0
      btpd/btpd.h

+ 1
- 1
btpd/Makefile.am ファイルの表示

@@ -1,6 +1,6 @@
bin_PROGRAMS=btpd
btpd_SOURCES=\
active.c active.h\
active.c active.h addrinfo.c\
btpd.c btpd.h\
cli_if.c content.c content.h\
download.c download_subr.c download.h\


+ 97
- 0
btpd/addrinfo.c ファイルの表示

@@ -0,0 +1,97 @@
#include "btpd.h"

#include <pthread.h>

struct ai_ctx {
BTPDQ_ENTRY(ai_ctx) entry;
struct addrinfo hints;
struct addrinfo *res;
char node[255], service[6];
void (*cb)(void *, int, struct addrinfo *);
void *arg;
int cancel;
int error;
short port;
};

BTPDQ_HEAD(ai_ctx_tq, ai_ctx);

static struct ai_ctx_tq m_aiq = BTPDQ_HEAD_INITIALIZER(m_aiq);
static pthread_mutex_t m_aiq_lock;
static pthread_cond_t m_aiq_cond;

struct ai_ctx *
btpd_addrinfo(const char *node, short port, struct addrinfo *hints,
void (*cb)(void *, int, struct addrinfo *), void *arg)
{
struct ai_ctx *ctx = btpd_calloc(1, sizeof(*ctx));
ctx->hints = *hints;
ctx->cb = cb;
ctx->arg = arg;
snprintf(ctx->node, sizeof(ctx->node), "%s", node);
ctx->port = port;
if (port > 0)
snprintf(ctx->service, sizeof(ctx->service), "%hd", port);

pthread_mutex_lock(&m_aiq_lock);
BTPDQ_INSERT_TAIL(&m_aiq, ctx, entry);
pthread_mutex_unlock(&m_aiq_lock);
pthread_cond_signal(&m_aiq_cond);

return ctx;
}

void
btpd_addrinfo_cancel(struct ai_ctx *ctx)
{
ctx->cancel = 1;
}

static void
addrinfo_td_cb(void *arg)
{
struct ai_ctx *ctx = arg;
if (!ctx->cancel)
ctx->cb(ctx->arg, ctx->error, ctx->res);
else if (ctx->error != 0)
freeaddrinfo(ctx->res);
free(ctx);
}

static void *
addrinfo_td(void *arg)
{
struct ai_ctx *ctx;
char *service;
while (1) {
pthread_mutex_lock(&m_aiq_lock);
while (BTPDQ_EMPTY(&m_aiq))
pthread_cond_wait(&m_aiq_cond, &m_aiq_lock);
ctx = BTPDQ_FIRST(&m_aiq);
BTPDQ_REMOVE(&m_aiq, ctx, entry);
pthread_mutex_unlock(&m_aiq_lock);

service = ctx->port > 0 ? ctx->service : NULL;
ctx->error = getaddrinfo(ctx->node, service, &ctx->hints, &ctx->res);

td_post_begin();
td_post(addrinfo_td_cb, ctx);
td_post_end();
}
}

static void
errdie(int err, const char *str)
{
if (err != 0)
btpd_err("addrinfo_init: %s (%s).\n", str, strerror(errno));
}

void
addrinfo_init(void)
{
pthread_t td;
errdie(pthread_mutex_init(&m_aiq_lock, NULL), "pthread_mutex_init");
errdie(pthread_cond_init(&m_aiq_cond, NULL), "pthread_cond_init");
errdie(pthread_create(&td, NULL, addrinfo_td, NULL), "pthread_create");
}

+ 2
- 0
btpd/btpd.c ファイルの表示

@@ -77,6 +77,7 @@ heartbeat_cb(int fd, short type, void *arg)
void tr_init(void);
void ipc_init(void);
void td_init(void);
void addrinfo_init(void);

void
btpd_init(void)
@@ -102,6 +103,7 @@ btpd_init(void)
srandom(seed);

td_init();
addrinfo_init();
net_init();
ipc_init();
ul_init();


+ 6
- 0
btpd/btpd.h ファイルの表示

@@ -8,6 +8,7 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#include <assert.h>
#include <errno.h>
@@ -84,4 +85,9 @@ void td_post(void (*cb)(void *), void *arg);
void td_post_end();
#define td_post_begin td_acquire_lock

typedef struct ai_ctx * aictx_t;
aictx_t btpd_addrinfo(const char *node, short port, struct addrinfo *hints,
void (*cb)(void *, int, struct addrinfo *), void *arg);
void btpd_addrinfo_cancel(aictx_t ctx);

#endif

読み込み中…
キャンセル
保存