ngx-queue.h
libuv のソースを見ていたら、ngx_queue_*
という API が出てきてびっくり。どうやら nginx から ngx-queue.h
っていうリンクドリストの実装を持ってきているようだ。
include/uv-private/ngx-queue.h at master from joyent/libuv - GitHub
なかなかおもしろい。これ、いろんなところで使えそうなので手元でも試してみた。
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "ngx-queue.h"
typedef struct {
ngx_queue_t queue;
char* data;
} chunk_t;
chunk_t* chunk_init(const char* data, size_t len) {
chunk_t* c = malloc(sizeof(chunk_t));
assert(c);
ngx_queue_init(&c->queue);
c->data = malloc(len + 1);
assert(c->data);
memcpy(c->data, data, len);
c->data[len] = '\0';
return c;
}
void chunk_delete(chunk_t* c) {
ngx_queue_remove(&c->queue);
free(c->data);
free(c);
}
int main(int argc, char** argv) {
ngx_queue_t queue;
chunk_t* chunk;
ngx_queue_init(&queue);
chunk = chunk_init("foo", 3);
ngx_queue_insert_tail(&queue, &chunk->queue);
chunk = chunk_init("bar", 3);
ngx_queue_insert_tail(&queue, &chunk->queue);
chunk = chunk_init("buz", 3);
ngx_queue_insert_tail(&queue, &chunk->queue);
while (!ngx_queue_empty(&queue)) {
ngx_queue_t* q = ngx_queue_head(&queue);
chunk_t* c = ngx_queue_data(q, chunk_t, queue);
printf("data: %s\n", c->data);
chunk_delete(c);
}
chunk = chunk_init("foo", 3);
ngx_queue_insert_tail(&queue, &chunk->queue);
chunk = chunk_init("bar", 3);
ngx_queue_insert_tail(&queue, &chunk->queue);
chunk = chunk_init("buz", 3);
ngx_queue_insert_tail(&queue, &chunk->queue);
while (!ngx_queue_empty(&queue)) {
ngx_queue_t* q = ngx_queue_last(&queue);
chunk_t* c = ngx_queue_data(q, chunk_t, queue);
printf("data: %s\n", c->data);
chunk_delete(c);
}
return 0;
}
出力は
$ ./a.out
data: foo
data: bar
data: buz
data: buz
data: bar
data: foo
これは使えるなぁ。