Esempio n. 1
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;
}
Esempio n. 2
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);
}
Esempio n. 3
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);
}
Esempio n. 4
0
bool master_udp::run_alone(const char* addrs, const char* path /* = NULL */,
	unsigned int count /* = 1 */)
{
	// 每个进程只能有一个实例在运行
	acl_assert(has_called == false);
	has_called = true;
	daemon_mode_ = false;
	__count_limit = count;
	acl_assert(addrs && *addrs);

#ifdef ACL_WINDOWS
	acl_init();
#endif
	ACL_EVENT* eventp = acl_event_new_select(1, 0);
	set_event(eventp);  // 设置基类的事件句柄

	ACL_ARGV* tokens = acl_argv_split(addrs, ";,| \t");
	ACL_ITER iter;

	acl_foreach(iter, tokens)
	{
		const char* addr = (const char*) iter.data;
		ACL_VSTREAM* sstream = acl_vstream_bind(addr, 0);
		if (sstream == NULL)
		{
			logger_error("bind %s error %s",
				addr, last_serror());
			close_sstreams();
			acl_event_free(eventp);
			acl_argv_free(tokens);
			return false;
		}
		acl_event_enable_read(eventp, sstream, 0,
			read_callback, sstream);
		socket_stream* ss = NEW socket_stream();
		if (ss->open(sstream) == false)
			logger_fatal("open stream error!");
		sstream->context = ss;
		sstreams_.push_back(ss);
	}

	acl_argv_free(tokens);

	// 初始化配置参数
	conf_.load(path);

	service_pre_jail(NULL, NULL);
	service_init(NULL, NULL);

	while (!__stop)
		acl_event_loop(eventp);

	service_exit(NULL, NULL);

	// 必须在调用 acl_event_free 前调用 close_sstreams,因为在关闭
	// 网络流对象时依然有对 ACL_EVENT 引擎的使用
	close_sstreams();
	acl_event_free(eventp);
	return true;
}
Esempio n. 5
0
static void read_fn(int event_type acl_unused, void *context)
{
	EVENT_DOG *evdog = (EVENT_DOG*) context;
	char  buf[2];

	evdog->client->rw_timeout = 1;
	if (acl_vstream_readn(evdog->client, buf, 1) == ACL_VSTREAM_EOF) {
	        acl_event_disable_read(evdog->eventp, evdog->client);
		event_dog_reopen(evdog);
	} else
		acl_event_enable_read(evdog->eventp, evdog->client, 0, read_fn, evdog);
}
Esempio n. 6
0
static void run(ACL_EVENT* event)
{
	acl::socket_stream udp;

	// 绑定本地地址
	if (udp.bind_udp(__local_addr) == false)
	{
		printf("bind addr %s error %s\r\n",
			__server_addr, acl::last_serror());
		return;
	}

	// 设置远程服务地址
	else
		udp.set_peer(__server_addr);

	udp.set_rw_timeout(100);
	ACL_VSTREAM* udp_stream = udp.get_vstream();

	acl::socket_stream stdio_in;
	stdio_in.open(0);

	ACL_VSTREAM* in = stdio_in.get_vstream();
	acl::socket_stream out;
	out.open(2);

	udp.set_tcp_non_blocking(true);
	stdio_in.set_tcp_non_blocking(true);

	acl_event_enable_read(event, in, 0, stdin_read_callback, &udp);
	acl_event_enable_read(event, udp_stream, 0, udp_read_callback, &out);

	out.write("Escape character is '^]'.\r\n");

	while (true)
	{
		acl_event_loop(event);
	}
}
Esempio n. 7
0
static void http_server(ACL_VSTREAM *cstream)
{
	ACL_EVENT *event = (ACL_EVENT *) cstream->context;
	acl::socket_stream conn;

	conn.open(cstream);
	acl::memcache_session session("127.0.0.1:11211");
	http_servlet servlet(&conn, &session);
	servlet.setLocalCharset("gb2312");

	if (servlet.doRun() == false)
		return;

	conn.unbind();
	acl_event_enable_read(event, cstream, 120, client_callback, NULL);
}
Esempio n. 8
0
static void read_fn(int event_type acl_unused, ACL_EVENT *event,
	ACL_VSTREAM *stream, void *context)
{
	const char *myname = "read_fn";
	EVENT_DOG *evdog = (EVENT_DOG*) context;
	char  buf[2];

	if (evdog->client != stream)
		acl_msg_fatal("%s(%d), %s: stream != evdog->client",
			__FILE__, __LINE__, myname);

	evdog->client->rw_timeout = 1;
	if (acl_vstream_readn(evdog->client, buf, 1) == ACL_VSTREAM_EOF) {
	        acl_event_disable_read(event, stream);
		event_dog_reopen(evdog);
	} else
		acl_event_enable_read(event, stream, 0, read_fn, evdog);
}
Esempio n. 9
0
static void echo_client(ACL_VSTREAM *cstream)
{
	ACL_EVENT *event = (ACL_EVENT *) cstream->context;
	const char* res = "HTTP/1.1 200 OK\r\n"
		"Date: Tue, 31 May 2016 14:20:28 GMT\r\n"
		"Server: acl\r\n"
		"Content-Type: text/html\r\n"
		"Content-Length: 12\r\n"
		"Connection: Keep-Alive\r\n"
		"\r\n"
		"hello world!";
	size_t len = strlen(res);

	if (http_demo(cstream, res, len) < 0 || __stop)
		acl_vstream_close(cstream);
	else
		acl_event_enable_read(event, cstream, 120, client_callback, NULL);
}
Esempio n. 10
0
static void event_dog_open(EVENT_DOG *evdog)
{
	const char *myname = "event_dog_open";
	const char *addr = "127.0.0.1:0";
	char  ebuf[256];

	evdog->sstream = acl_vstream_listen(addr, 32);
	if (evdog->sstream == NULL)
		acl_msg_fatal("%s(%d): listen on addr(%s) error(%s)",
			myname, __LINE__, addr,
			acl_last_strerror(ebuf, sizeof(ebuf)));

	evdog->server = acl_vstream_connect(evdog->sstream->local_addr,
			ACL_BLOCKING, 0, 0, 1024);
	if (evdog->server == NULL)
		acl_msg_fatal("%s(%d): connect to addr(%s) error(%s)",
			myname, __LINE__, addr,
			acl_last_strerror(ebuf, sizeof(ebuf)));

	if (acl_vstream_writen(evdog->server, ebuf, 1) == ACL_VSTREAM_EOF)
		acl_msg_fatal("%s(%d): pre write error(%s)",
			myname, __LINE__,
			acl_last_strerror(ebuf, sizeof(ebuf)));

	evdog->client = acl_vstream_accept(evdog->sstream, ebuf, sizeof(ebuf));
	if (evdog->client == NULL)
		acl_msg_fatal("%s(%d): accept error(%s)",
			myname, __LINE__,
			acl_last_strerror(ebuf, sizeof(ebuf)));

	if (acl_vstream_readn(evdog->client, ebuf, 1) == ACL_VSTREAM_EOF)
		acl_msg_fatal("%s(%d): pre read error(%s)",
			myname, __LINE__,
			acl_last_strerror(ebuf, sizeof(ebuf)));

	acl_vstream_close(evdog->sstream);
	evdog->sstream = NULL;

	acl_event_enable_read(evdog->eventp, evdog->client, 0, read_fn, evdog);
}
Esempio n. 11
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));
}