mirror of
https://gitee.com/acl-dev/acl.git
synced 2024-11-30 02:47:56 +08:00
add one ping sample which can ping any host in fiber mode
This commit is contained in:
parent
271fc96cdf
commit
3c8dc7b019
@ -17,7 +17,7 @@ static errno_fn __sys_errno = NULL;
|
||||
static fcntl_fn __sys_fcntl = NULL;
|
||||
|
||||
typedef struct {
|
||||
ACL_RING queue; /* ready fiber queue */
|
||||
ACL_RING ready; /* ready fiber queue */
|
||||
ACL_RING dead; /* dead fiber queue */
|
||||
ACL_FIBER **fibers;
|
||||
size_t size;
|
||||
@ -28,9 +28,6 @@ typedef struct {
|
||||
size_t idgen;
|
||||
int count;
|
||||
int switched;
|
||||
#ifdef USE_DBUF
|
||||
ACL_DBUF_POOL *dbuf;
|
||||
#endif
|
||||
} FIBER_TLS;
|
||||
|
||||
static FIBER_TLS *__main_fiber = NULL;
|
||||
@ -51,10 +48,6 @@ static void thread_free(void *ctx)
|
||||
if (__thread_fiber == NULL)
|
||||
return;
|
||||
|
||||
#ifdef USE_DBUF
|
||||
acl_dbuf_pool_destroy(tf->dbuf);
|
||||
#endif
|
||||
|
||||
if (tf->fibers)
|
||||
acl_myfree(tf->fibers);
|
||||
acl_myfree(tf);
|
||||
@ -92,11 +85,8 @@ static void fiber_check(void)
|
||||
__thread_fiber->size = 0;
|
||||
__thread_fiber->idgen = 0;
|
||||
__thread_fiber->count = 0;
|
||||
#ifdef USE_DBUF
|
||||
__thread_fiber->dbuf = acl_dbuf_pool_create(640000);
|
||||
#endif
|
||||
|
||||
acl_ring_init(&__thread_fiber->queue);
|
||||
acl_ring_init(&__thread_fiber->ready);
|
||||
acl_ring_init(&__thread_fiber->dead);
|
||||
|
||||
if ((unsigned long) acl_pthread_self() == acl_main_thread_self()) {
|
||||
@ -219,14 +209,14 @@ void fiber_exit(int exit_code)
|
||||
void acl_fiber_ready(ACL_FIBER *fiber)
|
||||
{
|
||||
fiber->status = FIBER_STATUS_READY;
|
||||
acl_ring_prepend(&__thread_fiber->queue, &fiber->me);
|
||||
acl_ring_prepend(&__thread_fiber->ready, &fiber->me);
|
||||
}
|
||||
|
||||
int acl_fiber_yield(void)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (acl_ring_size(&__thread_fiber->queue) == 0)
|
||||
if (acl_ring_size(&__thread_fiber->ready) == 0)
|
||||
return 0;
|
||||
|
||||
n = __thread_fiber->switched;
|
||||
@ -273,12 +263,8 @@ static void fiber_start(unsigned int x, unsigned int y)
|
||||
|
||||
static void fiber_free(FIBER_TLS *tls, ACL_FIBER *fiber)
|
||||
{
|
||||
#ifdef USE_DBUF
|
||||
acl_dbuf_pool_free(tls->dbuf, fiber);
|
||||
#else
|
||||
(void) tls;
|
||||
acl_myfree(fiber);
|
||||
#endif
|
||||
}
|
||||
|
||||
static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *),
|
||||
@ -306,20 +292,10 @@ static ACL_FIBER *fiber_alloc(void (*fn)(ACL_FIBER *, void *),
|
||||
|
||||
head = acl_ring_pop_head(&__thread_fiber->dead);
|
||||
if (head == NULL)
|
||||
#ifdef USE_DBUF
|
||||
fiber = (ACL_FIBER *) acl_dbuf_pool_calloc(
|
||||
__thread_fiber->dbuf, sizeof(ACL_FIBER) + size);
|
||||
#else
|
||||
fiber = (ACL_FIBER *) acl_mycalloc(1, sizeof(ACL_FIBER) + size);
|
||||
#endif
|
||||
else if ((fiber = ACL_RING_TO_APPL(head, ACL_FIBER, me))->size < size) {
|
||||
fiber_free(__thread_fiber, fiber);
|
||||
#ifdef USE_DBUF
|
||||
fiber = (ACL_FIBER *) acl_dbuf_pool_calloc(
|
||||
__thread_fiber->dbuf, sizeof(ACL_FIBER) + size);
|
||||
#else
|
||||
fiber = (ACL_FIBER *) acl_mycalloc(1, sizeof(ACL_FIBER) + size);
|
||||
#endif
|
||||
} else
|
||||
size = fiber->size;
|
||||
|
||||
@ -414,7 +390,7 @@ void acl_fiber_schedule(void)
|
||||
acl_fiber_hook_api(1);
|
||||
|
||||
for (;;) {
|
||||
head = acl_ring_pop_head(&__thread_fiber->queue);
|
||||
head = acl_ring_pop_head(&__thread_fiber->ready);
|
||||
if (head == NULL) {
|
||||
acl_msg_info("------- NO ACL_FIBER NOW --------");
|
||||
break;
|
||||
@ -476,7 +452,7 @@ void acl_fiber_switch(void)
|
||||
acl_ring_append(&__thread_fiber->dead, ¤t->me);
|
||||
}
|
||||
|
||||
head = acl_ring_pop_head(&__thread_fiber->queue);
|
||||
head = acl_ring_pop_head(&__thread_fiber->ready);
|
||||
|
||||
if (head == NULL) {
|
||||
fiber_swap(current, &__thread_fiber->schedule);
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include "fiber.h"
|
||||
|
||||
typedef unsigned int (*sleep_fn)(unsigned int seconds);
|
||||
typedef int (*pipe_fn)(int pipefd[2]);
|
||||
#ifdef HAS_PIPE2
|
||||
typedef int (*pipe2_fn)(int pipefd[2], int flags);
|
||||
@ -32,6 +33,7 @@ typedef ssize_t (*sendto_fn)(int, const void *, size_t, int,
|
||||
const struct sockaddr *, socklen_t);
|
||||
typedef ssize_t (*sendmsg_fn)(int, const struct msghdr *, int);
|
||||
|
||||
static sleep_fn __sys_sleep = NULL;
|
||||
static pipe_fn __sys_pipe = NULL;
|
||||
#ifdef HAS_PIPE2
|
||||
static pipe2_fn __sys_pipe2 = NULL;
|
||||
@ -60,6 +62,7 @@ void hook_io(void)
|
||||
|
||||
__called++;
|
||||
|
||||
__sys_sleep = (sleep_fn) dlsym(RTLD_NEXT, "sleep");
|
||||
__sys_pipe = (pipe_fn) dlsym(RTLD_NEXT, "pipe");
|
||||
#ifdef HAS_PIPE2
|
||||
__sys_pipe2 = (pipe2_fn) dlsym(RTLD_NEXT, "pipe2");
|
||||
@ -80,6 +83,14 @@ void hook_io(void)
|
||||
__sys_sendmsg = (sendmsg_fn) dlsym(RTLD_NEXT, "sendmsg");
|
||||
}
|
||||
|
||||
unsigned int sleep(unsigned int seconds)
|
||||
{
|
||||
if (!acl_var_hook_sys_api)
|
||||
return __sys_sleep(seconds);
|
||||
|
||||
return acl_fiber_sleep(seconds);
|
||||
}
|
||||
|
||||
int pipe(int pipefd[2])
|
||||
{
|
||||
int ret = __sys_pipe(pipefd);
|
||||
|
@ -848,28 +848,34 @@ int gethostbyname_r(const char *name, struct hostent *ret,
|
||||
|
||||
acl_foreach(iter, res) {
|
||||
ACL_HOSTNAME *h = (ACL_HOSTNAME*) iter.data;
|
||||
struct in_addr addr;
|
||||
|
||||
len = strlen(h->ip);
|
||||
len = sizeof(struct in_addr);
|
||||
n += len;
|
||||
memcpy(buf, h->ip, len);
|
||||
buf[len] = 0;
|
||||
if (n > buflen)
|
||||
break;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.s_addr = inet_addr(h->ip);
|
||||
memcpy(buf, &addr, len);
|
||||
|
||||
if (i >= MAX_COUNT)
|
||||
break;
|
||||
ret->h_addr_list[i++] = buf;
|
||||
buf += len + 1;
|
||||
buf += len;
|
||||
ret->h_length += len;
|
||||
}
|
||||
|
||||
if (i == 0) {
|
||||
acl_msg_error("%s(%d), %s: i == 0",
|
||||
__FILE__, __LINE__, __FUNCTION__);
|
||||
if (h_errnop)
|
||||
*h_errnop = ERANGE;
|
||||
RETURN (-1);
|
||||
if (i > 0) {
|
||||
*result = ret;
|
||||
RETURN (0);
|
||||
}
|
||||
|
||||
*result = ret;
|
||||
acl_msg_error("%s(%d), %s: i == 0, n: %d, buflen: %d",
|
||||
__FILE__, __LINE__, __FUNCTION__, (int) n, (int) buflen);
|
||||
|
||||
RETURN (0);
|
||||
if (h_errnop)
|
||||
*h_errnop = ERANGE;
|
||||
|
||||
RETURN (-1);
|
||||
}
|
||||
|
@ -1,4 +1,11 @@
|
||||
|
||||
17) 2016.8.5
|
||||
17.1) feature: hook_io.c 中增加系统 API sleep 的 hook 函数
|
||||
|
||||
16) 2016.8.4
|
||||
16.1) bugfix: hook_net.c 中的 gethostbyname_r 在解析域名时的地址所用字节序有误
|
||||
--- found by 陈晓勇
|
||||
|
||||
15) 2016.7.28
|
||||
15.1) bugfix: hook_net.c 中的 poll/epoll_wait 对于超时的计数有误,会导致超时
|
||||
时间提前
|
||||
|
@ -100,13 +100,18 @@ ACL_PATH = ../../../lib_acl
|
||||
ACL_INC = $(ACL_PATH)/include
|
||||
ACL_LIB = $(ACL_PATH)/lib
|
||||
|
||||
PRO_PATH = ../../../lib_protocol
|
||||
PRO_INC = $(PRO_PATH)/include
|
||||
PRO_LIB = $(PRO_PATH)/lib
|
||||
|
||||
FIBER_PATH = ../../../lib_fiber
|
||||
FIBER_INC = $(FIBER_PATH)/c/include
|
||||
FIBER_LIB = $(FIBER_PATH)/lib
|
||||
|
||||
EXTLIBS =
|
||||
CFLAGS += -I.. -I$(ACL_INC) -I$(FIBER_INC)
|
||||
LDFLAGS = -L$(ACL_LIB) -L$(FIBER_LIB) -l_fiber -l_acl $(EXTLIBS) $(SYSLIB)
|
||||
CFLAGS += -I.. -I$(PRO_INC) -I$(ACL_INC) -I$(FIBER_INC)
|
||||
LDFLAGS = -L$(PRO_LIB) -l_protocol -L$(FIBER_LIB) -l_fiber \
|
||||
-L$(ACL_LIB) -l_acl $(EXTLIBS) $(SYSLIB)
|
||||
|
||||
###########################################################
|
||||
|
||||
|
2
lib_fiber/samples/ping/Makefile
Normal file
2
lib_fiber/samples/ping/Makefile
Normal file
@ -0,0 +1,2 @@
|
||||
include ../Makefile.in
|
||||
PROG = ping
|
110
lib_fiber/samples/ping/main.c
Normal file
110
lib_fiber/samples/ping/main.c
Normal file
@ -0,0 +1,110 @@
|
||||
#include "lib_acl.h"
|
||||
#include "lib_protocol.h"
|
||||
#include "fiber/lib_fiber.h"
|
||||
#include <signal.h>
|
||||
|
||||
static int __nfibers = 0;
|
||||
static int __npkt = 10;
|
||||
|
||||
static void display_res(ICMP_CHAT *chat)
|
||||
{
|
||||
if (chat) {
|
||||
/* 显示 PING 的结果总结 */
|
||||
icmp_stat(chat);
|
||||
printf(">>>max pkts: %d\r\n", icmp_chat_seqno(chat));
|
||||
}
|
||||
}
|
||||
|
||||
/* PING 线程入口 */
|
||||
static void fiber_ping(ACL_FIBER *fiber acl_unused, void *arg)
|
||||
{
|
||||
const char *dest = (const char *) arg;
|
||||
ACL_DNS_DB* dns_db;
|
||||
const char *ip;
|
||||
int delay = 1; /* 发送 ping 包的时间间隔(秒)*/
|
||||
ICMP_CHAT *chat;
|
||||
|
||||
/* 通过域名解析出IP地址 */
|
||||
dns_db = acl_gethostbyname(dest, NULL);
|
||||
if (dns_db == NULL) {
|
||||
acl_msg_warn("Can't find domain %s", dest);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 只取出域名第一个 IP 地址 PING */
|
||||
ip = acl_netdb_index_ip(dns_db, 0);
|
||||
if (ip == NULL || *ip == 0) {
|
||||
acl_msg_error("ip invalid");
|
||||
acl_netdb_free(dns_db);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 创建 ICMP 对象 */
|
||||
chat = icmp_chat_create(NULL, 1);
|
||||
|
||||
/* 开始 PING */
|
||||
if (strcmp(dest, ip) == 0)
|
||||
icmp_ping_one(chat, NULL, ip, __npkt, delay, 1);
|
||||
else
|
||||
icmp_ping_one(chat, dest, ip, __npkt, delay, 1);
|
||||
|
||||
acl_netdb_free(dns_db); /* 释放域名解析对象 */
|
||||
display_res(chat); /* 显示 PING 结果 */
|
||||
icmp_chat_free(chat); /* 释放 ICMP 对象 */
|
||||
|
||||
if (--__nfibers == 0)
|
||||
acl_fiber_stop();
|
||||
}
|
||||
|
||||
static void usage(const char* progname)
|
||||
{
|
||||
printf("usage: %s [-h help] [-n npkt] [\"dest1 dest2 dest3...\"]\r\n",
|
||||
progname);
|
||||
printf("example: %s -n 10 www.sina.com.cn www.qq.com\r\n", progname);
|
||||
}
|
||||
|
||||
/* 当收到 SIGINT 信号(即在 PING 过程中用户按下 ctrl + c)时的信号处理函数 */
|
||||
static void on_sigint(int signo acl_unused)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
char ch;
|
||||
int i;
|
||||
|
||||
signal(SIGINT, on_sigint); /* 用户按下 ctr + c 时中断 PING 程序 */
|
||||
acl_msg_stdout_enable(1); /* 允许 acl_msg_xxx 记录的信息输出至屏幕 */
|
||||
|
||||
while ((ch = getopt(argc, argv, "hn:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'n':
|
||||
__npkt = atoi(optarg);
|
||||
break;
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (optind == argc) {
|
||||
usage(argv[0]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (__npkt <= 0)
|
||||
__npkt = 10;
|
||||
|
||||
/* 记录要启动的协程的总数 */
|
||||
__nfibers = argc - optind;
|
||||
|
||||
for (i = optind; i < argc; i++)
|
||||
acl_fiber_create(fiber_ping, argv[i], 32000);
|
||||
|
||||
acl_fiber_schedule();
|
||||
|
||||
return 0;
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include <unistd.h>
|
||||
#include "fiber/lib_fiber.h"
|
||||
|
||||
static int __stack_size = 32000;
|
||||
static int __rw_timeout = 0;
|
||||
static int __echo_data = 0;
|
||||
|
||||
@ -57,7 +58,7 @@ static void fiber_accept(ACL_FIBER *fiber acl_unused, void *ctx)
|
||||
}
|
||||
|
||||
printf("accept one, fd: %d\r\n", ACL_VSTREAM_SOCK(cstream));
|
||||
acl_fiber_create(echo_client, cstream, 32768);
|
||||
acl_fiber_create(echo_client, cstream, __stack_size);
|
||||
}
|
||||
|
||||
acl_vstream_close(sstream);
|
||||
@ -94,6 +95,7 @@ static void usage(const char *procname)
|
||||
" -r rw_timeout\r\n"
|
||||
" -S [if sleep]\r\n"
|
||||
" -q listen_queue\r\n"
|
||||
" -z stack_size\r\n"
|
||||
" -w [if echo data, default: no]\r\n", procname);
|
||||
}
|
||||
|
||||
@ -107,7 +109,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
snprintf(addr, sizeof(addr), "%s", "127.0.0.1:9002");
|
||||
|
||||
while ((ch = getopt(argc, argv, "hs:r:Sq:w")) > 0) {
|
||||
while ((ch = getopt(argc, argv, "hs:r:Sq:wz:")) > 0) {
|
||||
switch (ch) {
|
||||
case 'h':
|
||||
usage(argv[0]);
|
||||
@ -127,6 +129,9 @@ int main(int argc, char *argv[])
|
||||
case 'w':
|
||||
__echo_data = 1;
|
||||
break;
|
||||
case 'z':
|
||||
__stack_size = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
|
||||
1) 增加针对协程调度器的监控机制
|
||||
2) 增加更方便的协程异步调用接口
|
||||
3) 支持信号跳转方式
|
||||
4) 支持 read 读缓冲
|
||||
|
Loading…
Reference in New Issue
Block a user