示例#1
0
文件: acl_mbox.c 项目: LazyPlanet/acl
ACL_MBOX *acl_mbox_create(void)
{
	ACL_MBOX *mbox;
	ACL_SOCKET fds[2];

	if (acl_sane_socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0) {
		acl_msg_error("%s(%d), %s: acl_duplex_pipe error %s",
			__FILE__, __LINE__, __FUNCTION__, acl_last_serror());
		return NULL;
	}

	mbox        = (ACL_MBOX *) acl_mymalloc(sizeof(ACL_MBOX));
	mbox->in    = acl_vstream_fdopen(fds[0], O_RDONLY, sizeof(__key),
			0, ACL_VSTREAM_TYPE_SOCK);
	mbox->out   = acl_vstream_fdopen(fds[1], O_WRONLY, sizeof(__key),
			0, ACL_VSTREAM_TYPE_SOCK);
	mbox->nsend = 0;
	mbox->nread = 0;
	mbox->ypipe = acl_ypipe_new();
	mbox->lock  = (acl_pthread_mutex_t *)
		acl_mycalloc(1, sizeof(acl_pthread_mutex_t));
	if (acl_pthread_mutex_init(mbox->lock, NULL) != 0)
		acl_msg_fatal("%s(%d), %s: acl_pthread_mutex_init error",
			__FILE__, __LINE__, __FUNCTION__);

	return mbox;
}
示例#2
0
void    acl_master_status_init(ACL_MASTER_SERV *serv)
{
	const char *myname = "acl_master_status_init";

	/*
	 * Sanity checks.
	 */
	if (serv->status_fd[0] >= 0 || serv->status_fd[1] >= 0)
		acl_msg_panic("%s: status events already enabled", myname);
	if (acl_msg_verbose)
		acl_msg_info("%s: %s", myname, serv->name);

	/*
	 * Make the read end of this service's status pipe non-blocking so that
	 * we can detect partial writes on the child side. We use a duplex pipe
	 * so that the child side becomes readable when the master goes away.
	 */
	if (acl_duplex_pipe(serv->status_fd) < 0)
		acl_msg_fatal("pipe: %s", strerror(errno));
	acl_non_blocking(serv->status_fd[0], ACL_BLOCKING);
	acl_close_on_exec(serv->status_fd[0], ACL_CLOSE_ON_EXEC);
	acl_close_on_exec(serv->status_fd[1], ACL_CLOSE_ON_EXEC);
	serv->status_read_stream = acl_vstream_fdopen(serv->status_fd[0],
		O_RDWR, acl_var_master_buf_size,
		acl_var_master_rw_timeout, ACL_VSTREAM_TYPE_SOCK);

	if (acl_msg_verbose)
		acl_msg_info("%s(%d)->%s: call acl_event_enable_read, "
			"status_fd = %d", __FILE__, __LINE__,
			myname, serv->status_fd[0]);

	acl_event_enable_read(acl_var_master_global_event,
		serv->status_read_stream, 0, master_status_event,
		(void *) serv);
}
示例#3
0
文件: watchdog.c 项目: 10jschen/acl
int     main(int unused_argc, char **unused_argv)
{
	char      myname[] = "main";
	ACL_WATCHDOG *wp;
	ACL_VSTREAM  *vp;
	char      buf[256] = "test before";

	unused_argc = unused_argc;
	unused_argv = unused_argv;

	acl_msg_verbose = 2;

	printf("buf=%s\n", buf);
	vp = acl_vstream_fdopen(0, 0, 0600, 4096, 0);
	if (vp == NULL)
		acl_msg_fatal("%s(%d)->%s: vstream_fdopen err %s",
				__FILE__, __LINE__, myname,
				strerror(errno));

	wp = acl_watchdog_create(10, __watchdog_fn, (char *) buf);
	acl_watchdog_start(wp);

	while (acl_vstream_gets_nonl(vp, buf, sizeof(buf) - 1) != ACL_VSTREAM_EOF) {
		acl_msg_info(">>> your input:%s", buf);
		if (strcasecmp(buf, "quit") == 0 || strcasecmp(buf, "exit") == 0)
			break;
		acl_watchdog_pat();
	}

	acl_watchdog_destroy(wp);

	exit (0);
}
示例#4
0
文件: stream.cpp 项目: Tim9Liu9/acl
void stream::open_stream(void)
{
	if (stream_ != NULL)
		return;
	stream_ = acl_vstream_fdopen(ACL_SOCKET_INVALID, O_RDWR,
		8192, 0, ACL_VSTREAM_TYPE_SOCK);
}
示例#5
0
void stream::open_stream(bool is_file /* = false */)
{
	if (stream_ != NULL)
		return;
	stream_ = acl_vstream_fdopen(ACL_SOCKET_INVALID, O_RDWR, 8192, 0,
		is_file ? ACL_VSTREAM_TYPE_FILE : ACL_VSTREAM_TYPE_SOCK);
}
示例#6
0
bool socket_stream::open(ACL_SOCKET fd)
{
	ACL_VSTREAM* conn = acl_vstream_fdopen(fd, O_RDWR,
		8192, 0, ACL_VSTREAM_TYPE_SOCK);
	acl_assert(conn);
	return open(conn);
}
示例#7
0
int acl_unix_trigger(ACL_EVENT *event, const char *service,
	const char *buf, int len, int timeout)
{
	const char *myname = "acl_unix_trigger";
	struct ACL_UNIX_TRIGGER *up;
	ACL_SOCKET fd;

	if (acl_msg_verbose > 0)
		acl_msg_info("%s: service %s", myname, service);

	/*
	 * Connect...
	 */
	if ((fd = acl_unix_connect(service, ACL_BLOCKING, timeout)) < 0) {
		if (acl_msg_verbose)
			acl_msg_warn("%s: connect to %s: %s",
				myname, service, strerror(errno));
		return -1;
	}
	acl_close_on_exec(fd, ACL_CLOSE_ON_EXEC);

	/*
	 * Stash away context.
	 */
	up = (struct ACL_UNIX_TRIGGER *) acl_mymalloc(sizeof(*up));
	up->service = acl_mystrdup(service);
	up->stream = acl_vstream_fdopen(fd, O_RDWR, 4096,
			timeout, ACL_VSTREAM_TYPE_LISTEN_UNIX);

	/*
	 * Write the request...
	 */
	if (acl_vstream_writen(up->stream, buf, len) < 0
		|| acl_vstream_writen(up->stream, "", 1) < 0)
	{
		if (acl_msg_verbose)
			acl_msg_warn("%s: write to %s: %s",
				myname, service, strerror(errno));
	}

	/*
	 * Wakeup when the peer disconnects, or when we lose patience.
	 */
#ifdef	__USE_TIMER
	if (timeout > 0)
		acl_event_request_timer(event, acl_unix_trigger_timer,
			(void *) up, (timeout + 100) * 1000000);
	acl_event_enable_read(event, up->stream, 0,
		acl_unix_trigger_event, (void *) up);
#else
	if (timeout > 0)
		acl_event_enable_read(event, up->stream, timeout + 100,
			acl_unix_trigger_event, (void *) up);
	else
		acl_event_enable_read(event, up->stream, 0,
			acl_unix_trigger_event, (void *) up);
#endif

	return 0;
}
示例#8
0
bool socket_stream::open(ACL_SOCKET fd, bool udp_mode /* = false */)
{
	ACL_VSTREAM* conn = acl_vstream_fdopen(fd, O_RDWR,
		8192, 0, ACL_VSTREAM_TYPE_SOCK);
	acl_assert(conn);
	return open(conn, udp_mode);
}
示例#9
0
acl_int64 gid_cmdline_get(int fd, const char *tag, int *errnum)
{
	acl_int64  gid;
	ACL_VSTREAM *client = acl_vstream_fdopen(fd, 0, 1024,
			var_gid_rw_timeout, ACL_VSTREAM_TYPE_SOCK);

	gid = gid_cmdline_next(client, tag, errnum);
	acl_vstream_free(client);
	return (gid);
}
示例#10
0
int acl_inet_trigger(ACL_EVENT *eventp, const char *service,
	const char *buf, int len, int timeout)
{
	const char *myname = "acl_inet_trigger";
	struct ACL_INET_TRIGGER *ip;
	int     fd;

	if (acl_msg_verbose > 1)
		acl_msg_info("%s: service %s", myname, service);

	/*
	 * Connect...
	 */
	if ((fd = acl_inet_connect(service, ACL_BLOCKING, timeout)) < 0) {
		if (acl_msg_verbose)
			acl_msg_warn("%s: connect to %s: %s",
				myname, service, strerror(errno));
		return (-1);
	}
	acl_close_on_exec(fd, ACL_CLOSE_ON_EXEC);

	/*
	 * Stash away context.
	 */
	ip = (struct ACL_INET_TRIGGER *) acl_mymalloc(sizeof(*ip));
	ip->fd = fd;
	ip->service = acl_mystrdup(service);
	ip->stream = acl_vstream_fdopen(fd, O_RDWR, 4096,
		timeout, ACL_VSTREAM_TYPE_LISTEN_INET);
	ip->eventp = eventp;

	/*
	 * Write the request...
	 */
	if (acl_write_buf(fd, buf, len, timeout) < 0
		|| acl_write_buf(fd, "", 1, timeout) < 0)
	{
		if (acl_msg_verbose)
			acl_msg_warn("%s: write to %s: %s",
				myname, service, strerror(errno));
	}

	/*
	 * Wakeup when the peer disconnects, or when we lose patience.
	 */

	if (timeout > 0)
		acl_event_enable_read(ip->eventp, ip->stream, timeout + 100,
			acl_inet_trigger_event, (void *) ip);
	else
		acl_event_enable_read(ip->eventp, ip->stream, 0,
			acl_inet_trigger_event, (void *) ip);

	return (0);
}
示例#11
0
void    acl_master_vars_init(int buf_size, int rw_timeout)
{
	const char *myname = "acl_master_vars_init";

	if (ACL_MASTER_STAT_STREAM != NULL)
		acl_vstream_free(ACL_MASTER_STAT_STREAM);
	if (ACL_MASTER_FLOW_READ_STREAM != NULL)
		acl_vstream_free(ACL_MASTER_FLOW_READ_STREAM);
	if (ACL_MASTER_FLOW_WRITE_STREAM != NULL)
		acl_vstream_free(ACL_MASTER_FLOW_WRITE_STREAM);

	ACL_MASTER_STAT_STREAM = acl_vstream_fdopen(ACL_MASTER_STATUS_FD,
			O_RDWR, buf_size, rw_timeout, ACL_VSTREAM_TYPE_SOCK);
	ACL_MASTER_FLOW_READ_STREAM = acl_vstream_fdopen(ACL_MASTER_FLOW_READ,
			O_RDONLY, buf_size, rw_timeout, ACL_VSTREAM_TYPE_SOCK);
	ACL_MASTER_FLOW_WRITE_STREAM = acl_vstream_fdopen(ACL_MASTER_FLOW_WRITE,
			O_WRONLY, buf_size, rw_timeout, ACL_VSTREAM_TYPE_SOCK);
	if (acl_var_master_thread_pool == NULL)
		acl_var_master_thread_pool = acl_thread_pool_create(100, 60);
	if (acl_var_master_thread_pool == NULL)
		acl_msg_fatal("%s(%d): create thread pool error(%s)",
			myname, __LINE__, strerror(errno));
}
示例#12
0
ACL_VSTREAM *acl_vstream_listen_ex(const char *addr, int qlen,
	int block_mode, int io_bufsize, int io_timeout)
{
	const char *myname = "acl_vstream_listen_ex";
	ACL_SOCKET  listenfd;
	struct sockaddr_in local;
	ACL_VSTREAM *listen_stream;
	int   len;

	if (addr == 0 || *addr == 0 || qlen <= 0)
	{
		acl_msg_error("%s: input invalid", myname);
		return NULL;
	}

#ifdef	ACL_UNIX
	/* this maybe unix addr, such as '/home/test/listen.sock' */
	if (strchr(addr, '/') != NULL) {
		listenfd = acl_unix_listen(addr, qlen, 0);
		if (listenfd == ACL_SOCKET_INVALID)
			return NULL;
		acl_non_blocking(listenfd, block_mode);
		listen_stream = acl_vstream_fdopen(listenfd,
			ACL_VSTREAM_FLAG_RW, io_bufsize,
			io_timeout, ACL_VSTREAM_TYPE_LISTEN_UNIX);

		if (listen_stream == NULL) {
			acl_socket_close(listenfd);
			acl_msg_error("%s: open vstream error, addr(%s)",
				myname, addr);
			return NULL;
		}

		acl_vstream_set_local(listen_stream, addr);

		sprintf(listen_stream->errbuf, "+OK");
		return (listen_stream);
	}
#endif
	/* addr such as '192.168.0.1:80' */
	listenfd = acl_inet_listen(addr, qlen, block_mode);
	if (listenfd == ACL_SOCKET_INVALID) {
		acl_msg_error("%s: listen addr(%s) error(%s)",
			myname, addr, acl_last_serror());
		return NULL;
	}
	listen_stream = acl_vstream_fdopen(listenfd,
		ACL_VSTREAM_FLAG_RW, io_bufsize,
		io_timeout, ACL_VSTREAM_TYPE_LISTEN_INET);
	if (listen_stream == NULL) {
		acl_socket_close(listenfd);
		acl_msg_error("%s: open vstream error addr(%s)", myname, addr);
		return NULL;
	}

	memset(&local, 0, sizeof(local));
	len = (int) sizeof(struct sockaddr);
	if (getsockname(listenfd, (struct sockaddr*) &local,
		(socklen_t *) &len) < 0)
	{
		acl_msg_warn("%s: getsockname error(%s) for sock(%d)",
			myname, acl_last_serror(), listenfd);
		acl_vstream_set_local(listen_stream, addr);
	} else {
		char  ip[32], buf[64];
		int   port;

		acl_inet_ntoa(local.sin_addr, ip, sizeof(ip));
		port = ntohs(local.sin_port);
		snprintf(buf, sizeof(buf), "%s:%d", ip, port);
		acl_vstream_set_local(listen_stream, buf);
	}

	sprintf(listen_stream->errbuf, "+OK");
	return listen_stream;
}
示例#13
0
ACL_VSTREAM *acl_vstream_accept_ex(ACL_VSTREAM *listen_stream,
	ACL_VSTREAM *client_stream, char *addr, int size)
{
	const char *myname = "acl_vstream_accept_ex";
	ACL_SOCKET connfd = ACL_SOCKET_INVALID;
	ACL_SOCKET servfd = ACL_VSTREAM_SOCK(listen_stream);
	char buf[256];

	if ((listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_INET)) {
#ifdef WIN32
		if (!(listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_IOCP))
			connfd = acl_inet_accept_ex(servfd, buf, sizeof(buf));
		else if (listen_stream->iocp_sock == ACL_SOCKET_INVALID)
			return NULL;
		else {
			int   ret;

			connfd = listen_stream->iocp_sock;
			listen_stream->iocp_sock = ACL_SOCKET_INVALID;

			/* iocp 方式下,需调用下面过程以允许调用
			 * getpeername/getsockname
			 */
			ret = setsockopt(connfd, SOL_SOCKET,
				SO_UPDATE_ACCEPT_CONTEXT,
				(char *)&servfd, sizeof(servfd));
			buf[0] = 0;
			if (ret != SOCKET_ERROR)
				acl_getpeername(connfd, buf, sizeof(buf));
		}
#else
		connfd = acl_inet_accept_ex(servfd, buf, sizeof(buf));
#endif

		if (connfd != ACL_SOCKET_INVALID && addr != NULL && size > 0)
			ACL_SAFE_STRNCPY(addr, buf, size);
#ifdef	ACL_UNIX
	} else if ((listen_stream->type & ACL_VSTREAM_TYPE_LISTEN_UNIX)) {
		connfd = acl_unix_accept(servfd);
		if (acl_getpeername(connfd, buf, sizeof(buf)) < 0)
			buf[0] = 0;
		if (addr)
			ACL_SAFE_STRNCPY(addr, buf, size);
#endif
	} else
		acl_msg_fatal("%s(%d)->%s: invalid listen stream(%d)",
			__FILE__, __LINE__, myname, listen_stream->flag);

	if (connfd == ACL_SOCKET_INVALID)
		return NULL;

	if (client_stream != NULL) {
		acl_vstream_reset(client_stream);
		ACL_VSTREAM_SET_SOCK(client_stream, connfd);
	} else {
		client_stream = acl_vstream_fdopen(connfd,
			ACL_VSTREAM_FLAG_RW,
			(int) listen_stream->read_buf_len,
			listen_stream->rw_timeout,
			ACL_VSTREAM_TYPE_SOCK);
		/* 让 client_stream 的 context 成员继承 listen_stream 的
		 * context 成员变量.
		 */
		client_stream->context = listen_stream->context;
	}
	if (client_stream == NULL)
		return NULL;

	acl_vstream_set_peer(client_stream, buf);
	return client_stream;
}
示例#14
0
static module_service_main_fn __service_callback = NULL;

/* 某个线程服务实例接收到一个新的远程客户端连接请求 */

static int msg_ipc_accept(int msg_type acl_unused, ACL_MSGIO *mio acl_unused,
        const ACL_MSGIO_INFO *info, void *arg)
{
	IPC_CTX ctx;
	ACL_VSTREAM *stream;
	ACL_ASTREAM *client;
	SERVICE *service = (SERVICE*) arg;

	memcpy(&ctx, acl_vstring_str(info->body.buf), ACL_VSTRING_LEN(info->body.buf));

	/* 打开异步流 */
	stream = acl_vstream_fdopen(ctx.fd, O_RDWR, var_cfg_aio_buf_size,
			0, ACL_VSTREAM_TYPE_SOCK);
	client = acl_aio_open(ctx.aio, stream);

	/* 开始处理该客户端连接 */
	__service_callback(service, client);
	return (0);
}

/* 单线程实例非阻塞处理过程 */

static void *service_thread(void *arg)
{
	ACL_MSGIO *ipc_client = (ACL_MSGIO*) arg;
	ACL_AIO *aio = acl_msgio_aio(ipc_client);

	/* 内存垃圾回收定时器 */
示例#15
0
void    acl_master_sigsetup(void)
{
	char   *myname = "acl_master_sigsetup";
	struct sigaction action;
	static int sigs[] = {
		SIGINT, SIGQUIT, SIGILL, SIGBUS, /* SIGSEGV, only for test */ SIGTERM,
	};
	unsigned i;

	sigemptyset(&action.sa_mask);
	action.sa_flags = 0;

	/*
	 * Prepare to kill our children
	 * when we receive any of the above signals.
	 */
	action.sa_handler = master_sigdeath;
	for (i = 0; i < sizeof(sigs) / sizeof(sigs[0]); i++)
		if (sigaction(sigs[i], &action, (struct sigaction *) 0) < 0)
			acl_msg_fatal("%s: sigaction(%d): %s",
				myname, sigs[i], strerror(errno));


#ifdef USE_SIG_PIPE
	if (pipe(acl_master_sig_pipe))
		acl_msg_fatal("pipe: %s", strerror(errno));
	acl_non_blocking(ACL_SIG_PIPE_WRITE_FD, ACL_NON_BLOCKING);
	acl_non_blocking(ACL_SIG_PIPE_READ_FD, ACL_NON_BLOCKING);
	acl_close_on_exec(ACL_SIG_PIPE_WRITE_FD, ACL_CLOSE_ON_EXEC);
	acl_close_on_exec(ACL_SIG_PIPE_READ_FD, ACL_CLOSE_ON_EXEC);

	ACL_SIG_PIPE_READ_STREAM = acl_vstream_fdopen(ACL_SIG_PIPE_READ_FD,
			O_RDONLY, acl_var_master_buf_size,
			acl_var_master_rw_timeout, ACL_VSTREAM_TYPE_SOCK);
	if (ACL_SIG_PIPE_READ_STREAM == NULL)
		acl_msg_fatal("%s(%d)->%s: acl_vstream_fdopen error=%s",
			__FILE__, __LINE__, myname, strerror(errno));

	if (acl_msg_verbose)
		acl_msg_info("%s(%d)->%s: call acl_event_enable_read, "
			"SIG_PIPE_READ_FD = %d", __FILE__, __LINE__, myname,
			ACL_SIG_PIPE_READ_FD);
	acl_event_enable_read(acl_var_master_global_event,
		ACL_SIG_PIPE_READ_STREAM, 0, master_sig_event, (void *) 0);
#endif

	/*
	 * Intercept SIGHUP (re-read config file) and SIGCHLD (child exit).
	 */
#ifdef SA_RESTART
	action.sa_flags |= SA_RESTART;
#endif
	action.sa_handler = master_sighup;
	if (sigaction(SIGHUP, &action, (struct sigaction *) 0) < 0)
		acl_msg_fatal("%s: sigaction(%d): %s",
			myname, SIGHUP, strerror(errno));

	action.sa_flags |= SA_NOCLDSTOP;
	action.sa_handler = master_sigchld;
	if (sigaction(SIGCHLD, &action, (struct sigaction *) 0) < 0)
		acl_msg_fatal("%s: sigaction(%d): %s",
			myname, SIGCHLD, strerror(errno));
}