acl/lib_acl/samples/msgio/main.c
zsxxsz cf2528eb7c 完善了非阻塞IO的SSL功能;将 samples 移到 lib_acl 目录下
完善了非阻塞IO的SSL功能;将 acl/samples/ 下的示例分别移到 lib_acl 及 lib_protocol 目录下
2014-11-30 21:15:35 +08:00

222 lines
5.4 KiB
C
Raw Blame History

#include "lib_acl.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct {
ACL_SOCKET fd;
int i;
} IPC_CTX;
typedef struct {
ACL_AIO *aio;
ACL_MSGIO *mio;
ACL_VSTREAM *stream;
int n;
int stop;
acl_pthread_t tid;
} IPC;
typedef struct {
IPC *ipc;
ACL_MSGIO *local_mio;
ACL_VSTREAM *local_stream;
} IPC_CLIENT;
#define MSG_IPC_ACCEPT 100
#define MSG_IPC_STOP 101
#if 0
#define USE_IPC_SYNC
#endif
static ACL_MSGIO *__ipc_listener = NULL;
static IPC_CLIENT *__ipc_clients = NULL;
static ACL_AIO *__aio_listener = NULL;
static char __ipc_addr[256];
static int msg_ipc_stop(int msg_type acl_unused, ACL_MSGIO *mio acl_unused,
const ACL_MSGIO_INFO *info acl_unused, void *arg)
{
IPC *ipc = (IPC*) arg;
ipc->stop = 1;
printf("close now(%s)\n", acl_last_serror());
return (0);
}
static int msg_ipc_accept(int msg_type acl_unused, ACL_MSGIO *mio acl_unused,
const ACL_MSGIO_INFO *info, void *arg)
{
IPC *ipc = (IPC*) arg;
IPC_CTX ctx;
memcpy(&ctx, acl_vstring_str(info->body.buf), ACL_VSTRING_LEN(info->body.buf));
if (ipc->n % 10000 == 0)
printf("tid: %ld, fd: %d\n", (long) acl_pthread_self(), ctx.fd);
ipc->n++;
return (0);
}
#ifdef USE_IPC_SYNC
static int service_sync_loop_read(ACL_MSGIO *mio)
{
ACL_VSTREAM *vstream = acl_msgio_vstream(mio);
int i = 0;
acl_non_blocking(ACL_VSTREAM_SOCK(vstream), ACL_BLOCKING);
while (1) {
char buf[256];
int ret = acl_vstream_read(vstream, buf, sizeof(buf));
if (ret == ACL_VSTREAM_EOF) {
printf("tid: %ld, read error(%s)\n",
acl_pthread_self(), acl_last_serror());
return (0);
}
if (0 && i++ % 10000 == 0)
printf("tid: %ld, i: %d\n", acl_pthread_self(), i);
}
return (i);
}
#endif
static void *service_thread(void *arg)
{
IPC *ipc = (IPC*) arg;
ACL_MSGIO *mio = ipc->mio;
ACL_AIO *aio = acl_msgio_aio(mio);
acl_tcp_set_rcvbuf(ACL_VSTREAM_SOCK(acl_msgio_vstream(mio)), 1024000);
#ifdef USE_IPC_SYNC
service_sync_loop_read(mio);
return (NULL);
#endif
/* <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ѭ<EFBFBD><D1AD> */
while (1) {
acl_aio_loop(aio);
if (ipc->stop) {
printf("tid: %ld, stop now, n: %d\n",
(long) acl_pthread_self(), ipc->n);
break;
}
}
return (NULL);
}
static void init(int nthread)
{
acl_pthread_attr_t attr;
int i;
acl_init();
__ipc_clients = (IPC_CLIENT*) acl_mycalloc(nthread, sizeof(IPC_CLIENT));
acl_pthread_attr_init(&attr);
acl_pthread_attr_setdetachstate(&attr, 0);
__aio_listener = acl_aio_create(ACL_EVENT_SELECT);
__ipc_listener = acl_msgio_listen(__aio_listener, NULL);
assert(__ipc_listener);
acl_msgio_addr(__ipc_listener, __ipc_addr, sizeof(__ipc_addr));
printf("listening on: %s\n", __ipc_addr);
for (i = 0; i < nthread; i++) {
__ipc_clients[i].ipc = (IPC*) acl_mycalloc(1, sizeof(IPC));
__ipc_clients[i].ipc->aio = acl_aio_create(ACL_EVENT_SELECT);
__ipc_clients[i].ipc->mio = acl_msgio_connect(__ipc_clients[i].ipc->aio, __ipc_addr, 0);
/*
acl_msgio_set_noblock(__ipc_clients[i].ipc->aio, __ipc_clients[i].ipc->mio);
*/
acl_msgio_reg(__ipc_clients[i].ipc->mio, MSG_IPC_ACCEPT,
msg_ipc_accept, __ipc_clients[i].ipc);
acl_msgio_reg(__ipc_clients[i].ipc->mio, MSG_IPC_STOP,
msg_ipc_stop, __ipc_clients[i].ipc);
acl_msgio_reg(__ipc_clients[i].ipc->mio, ACL_MSGIO_EXCEPT,
msg_ipc_stop, __ipc_clients[i].ipc);
acl_pthread_create(&__ipc_clients[i].ipc->tid, &attr, service_thread, __ipc_clients[i].ipc);
__ipc_clients[i].local_mio = acl_msgio_accept(__ipc_listener);
assert(__ipc_clients[i].local_mio);
__ipc_clients[i].local_stream = acl_msgio_vstream(__ipc_clients[i].local_mio);
acl_non_blocking(ACL_VSTREAM_SOCK(__ipc_clients[i].local_stream), ACL_NON_BLOCKING);
acl_tcp_set_sndbuf(ACL_VSTREAM_SOCK(__ipc_clients[i].local_stream), 1024000);
acl_tcp_set_nodelay(ACL_VSTREAM_SOCK(__ipc_clients[i].local_stream));
}
}
static void run(int nthread, int nloop)
{
int i, ret;
IPC_CTX ctx;
time_t begin = time(NULL);
for (i = 0; i < nloop; i++) {
memset(&ctx, 0, sizeof(ctx));
ctx.fd = i;
#ifdef USE_IPC_SYNC
acl_vstream_write(__ipc_clients[i % nthread].local_stream, &ctx, sizeof(IPC_CTX));
#else
ret = acl_msgio_send(__ipc_clients[i % nthread].local_mio, MSG_IPC_ACCEPT, &ctx, sizeof(IPC_CTX));
if (ret < 0)
break;
#endif
if (i % 10000 == 0)
printf("run(tid=%ld): i=%d\n", (long) acl_pthread_self(), i);
}
for (i = 0; i < nthread; i++) {
memset(&ctx, 0, sizeof(ctx));
ctx.fd = -1;
acl_msgio_send(__ipc_clients[i].local_mio, MSG_IPC_STOP, &ctx, sizeof(IPC_CTX));
}
for (i = 0; i < nthread; i++)
acl_pthread_join(__ipc_clients[i].ipc->tid, NULL);
for (i = 0; i < nthread; i++)
acl_msgio_close(__ipc_clients[i].local_mio);
acl_myfree(__ipc_clients);
printf(">>>time cost: %ld\n", time(NULL) - begin);
}
static void usage(const char *procname)
{
printf("usage: %s -h [help] -c nthreads -n nloop\n", procname);
}
int main(int argc, char *argv[])
{
int nthread = 2, nloop = 1000000, ch;
acl_msg_stdout_enable(1);
while ((ch = getopt(argc, argv, "hc:n:")) > 0) {
switch (ch) {
case 'h':
usage(argv[0]);
return (0);
case 'n':
nloop = atoi(optarg);
break;
case 'c':
nthread = atoi(optarg);
break;
default:
break;
}
}
if (nthread <= 0)
nthread = 2;
if (nloop <= 0)
nloop = 1000;
init(nthread);
run(nthread, nloop);
return (0);
}