Exemplo n.º 1
0
/*检查超时的提案,进行重新提议*/
static void proposer_check_timeouts(evutil_socket_t fd, short event, void* arg)
{
	struct evproposer* p = arg;
	struct timeout_iterator* iter = proposer_timeout_iterator(p->state);

	/*第一个阶段超时提案*/
	prepare_req* pr;
	while((pr == timeout_iterator_prepare(iter)) != NULL){ /*获取超时的提案(第一阶段)*/
		paxos_log_info("Instance %d timed out.", pr->iid);
		/*对超时提案重新发起提议过程*/
		send_prepares(p, pr);
		free(pr);
	}
	
	accept_req* ar;
	while((ar = timeout_iterator_accept(iter)) != NULL){ /*获得超时提案(第二阶段)*/
		paxos_log_info("Instance %d timed out.", ar->iid);
		send_accepts(p, ar);
		free(ar);
	}

	/*释放超时管理的迭代器*/
	timeout_iterator_free(iter);
	/*插入一个定时器*/
	event_add(p->timeout_ev, &p->tv);
}
Exemplo n.º 2
0
static void
connect_peer(struct peer* p)
{
	bufferevent_enable(p->bev, EV_READ|EV_WRITE);
	bufferevent_socket_connect(p->bev, 
		(struct sockaddr*)&p->addr, sizeof(p->addr));
	socket_set_nodelay(bufferevent_getfd(p->bev));
	paxos_log_info("Connect to %s:%d", 
		inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port));
}
Exemplo n.º 3
0
static void
proposer_check_timeouts(evutil_socket_t fd, short event, void *arg)
{
	struct evproposer* p = arg;
	struct timeout_iterator* iter = proposer_timeout_iterator(p->state);
	
	prepare_req* pr;
	while ((pr = timeout_iterator_prepare(iter)) != NULL) {
		paxos_log_info("Instance %d timed out.", pr->iid);
		send_prepares(p, pr);
		free(pr);
	}
	
	accept_req* ar;
	while ((ar = timeout_iterator_accept(iter)) != NULL) {
		paxos_log_info("Instance %d timed out.", ar->iid);
		send_accepts(p, ar);
		free(ar);
	}
	
	timeout_iterator_free(iter);
	event_add(p->timeout_ev, &p->tv);   //Thus, if you want to make the event pending again, you can call event_add() on it again from inside the callback function.将超时事件重新加入
}
Exemplo n.º 4
0
static void on_accept(struct evconnlistener* l, evutil_socket_t* fd, struct sockaddr* addr, int socklen, void *arg)
{
	struct tcp_receiver* r = arg;
	struct event_base* b = evconnlistener_get_base(l);
	struct bufferevent *bev = bufferevent_socket_new(b, fd, BEV_OPT_CLOSE_ON_FREE);
	/*设置读事件函数和错误函数*/
	bufferevent_setcb(bev, on_read, NULL, on_error, arg);
	/*设置监视的socket事件*/
	bufferevent_enable(bev, EV_READ|EV_WRITE);
	/*添加到事件管理器中*/
	carray_push_back(r->bevs, bev);

	paxos_log_info("Accepted connection from %s:%d", inet_ntoa(((struct sockaddr_in*)addr)->sin_addr), ntohs(((struct sockaddr_in*)addr)->sin_port));
}
Exemplo n.º 5
0
static int
lmdb_storage_open(void* handle)
{
	struct lmdb_storage* s = handle;
	char* lmdb_env_path = NULL;
	struct stat sb;
	int dir_exists, result;
	size_t lmdb_env_path_length = strlen(paxos_config.lmdb_env_path) + 16;

	lmdb_env_path = malloc(lmdb_env_path_length);
	snprintf(lmdb_env_path, lmdb_env_path_length, "%s_%d",
	  paxos_config.lmdb_env_path, s->acceptor_id);

	// Trash bdb files -- testing only
	if (paxos_config.trash_files) {
		char rm_command[600];
		sprintf(rm_command, "rm -r %s", lmdb_env_path);
		system(rm_command);
	}

	dir_exists = (stat(lmdb_env_path, &sb) == 0);

	if (!dir_exists && (mkdir(lmdb_env_path, S_IRWXU) != 0)) {
		paxos_log_error("Failed to create env dir %s: %s",
		lmdb_env_path, strerror(errno));
		goto error;
	}

	if ((result = lmdb_storage_init(s, lmdb_env_path) != 0)) {
		paxos_log_error("Failed to open DB handle");
	} else {
		paxos_log_info("lmdb storage opened successfully");
		goto cleanup_exit;
	}

error:
	if (s) {
		lmdb_storage_close(s);
	}
	return -1;

cleanup_exit:
	if (lmdb_env_path) {
		free(lmdb_env_path);
	}

	return 0;
}
Exemplo n.º 6
0
static int
lmdb_storage_close(void* handle)
{
	struct lmdb_storage* s = handle;
	if (s->txn) {
		mdb_txn_abort(s->txn);
	}
	if (s->dbi) {
		mdb_close(s->env, s->dbi);
	}
	if (s->env) {
		mdb_env_close(s->env);
	}

	free(s);
	paxos_log_info("lmdb storage closed successfully");
	return 0;
}
Exemplo n.º 7
0
int
storage_close(struct storage* s)
{	
	int result = 0;
	DB* dbp = s->db;
	DB_ENV* dbenv = s->env;
	
	if (dbp->close(dbp, 0) != 0) {
		paxos_log_error("DB_ENV close failed");
		result = -1;
	}
	
	if (dbenv->close(dbenv, 0) != 0) {
		paxos_log_error("DB close failed");
		result = -1;
	}
	 
	free(s);
	paxos_log_info("Berkeley DB storage closed successfully");
	return result;
}
Exemplo n.º 8
0
struct tcp_receiver* tcp_receiver_new(struct event_base* b, int port, bufferevent_data_cb cb, void* arg)
{
	struct tcp_receiver* r;
	struct sockaddr_in sin;
	unsigned flags = LEV_OPT_CLOSE_ON_EXEC | LEV_OPT_CLOSE_ON_FREE | LEV_OPT_REUSEABLE;

	r = malloc(sizeof(struct tcp_receiver));
	set_sockaddr_in(&sin, port);
	r->callback = cb;
	r->arg = arg;
	/*libevent listener和bind端口*/
	r->listener = evconnlistener_new_bind(b, on_accept, r, flags,	-1, (struct sockaddr*)&sin, sizeof(sin));
	assert(r->listener != NULL);
	/*设置listen error 回调处理*/
	evconnlistener_set_error_cb(r->listener, on_listener_error);

	r->bevs = carray_new(10);

	paxos_log_info("Listening on port %d", port);

	return r;
}
Exemplo n.º 9
0
static void
on_accept(struct evconnlistener *l, evutil_socket_t fd,
	struct sockaddr* addr, int socklen, void *arg)
{
	struct peer* peer;
	struct peers* peers = arg;

	peers->clients = realloc(peers->clients,
		sizeof(struct peer*) * (peers->clients_count+1));
	peers->clients[peers->clients_count] = 
		make_peer(peers, peers->clients_count, (struct sockaddr_in*)addr);
	
	peer = peers->clients[peers->clients_count];
	bufferevent_setfd(peer->bev, fd);
	bufferevent_setcb(peer->bev, on_read, NULL, on_client_event, peer);
	bufferevent_enable(peer->bev, EV_READ|EV_WRITE);
	socket_set_nodelay(fd);
	
	paxos_log_info("Accepted connection from %s:%d",
		inet_ntoa(((struct sockaddr_in*)addr)->sin_addr),
		ntohs(((struct sockaddr_in*)addr)->sin_port));
	
	peers->clients_count++;
}
Exemplo n.º 10
0
static void
on_peer_event(struct bufferevent* bev, short ev, void *arg)
{
	struct peer* p = (struct peer*)arg;
	
	if (ev & BEV_EVENT_CONNECTED) {
		paxos_log_info("Connected to %s:%d",
			inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port));
		p->status = ev;
	} else if (ev & BEV_EVENT_ERROR || ev & BEV_EVENT_EOF) {
		struct event_base* base;
		int err = EVUTIL_SOCKET_ERROR();
		paxos_log_error("%s (%s:%d)", evutil_socket_error_to_string(err),
			inet_ntoa(p->addr.sin_addr), ntohs(p->addr.sin_port));
		base = bufferevent_get_base(p->bev);
		bufferevent_free(p->bev);
		p->bev = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE);
		bufferevent_setcb(p->bev, on_read, NULL, on_peer_event, p);
		event_add(p->reconnect_ev, &reconnect_timeout);
		p->status = ev;
	} else {
		paxos_log_error("Event %d not handled", ev);
	}
}
Exemplo n.º 11
0
int
peers_listen(struct peers* p, int port)
{
	struct sockaddr_in addr;
	unsigned flags = LEV_OPT_CLOSE_ON_EXEC
		| LEV_OPT_CLOSE_ON_FREE
		| LEV_OPT_REUSEABLE;
	
	/* listen on the given port at address 0.0.0.0 */
	memset(&addr, 0, sizeof(struct sockaddr_in));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = htonl(0);
	addr.sin_port = htons(port);
	
	p->listener = evconnlistener_new_bind(p->base, on_accept, p, flags, -1,
		(struct sockaddr*)&addr, sizeof(addr));
	if (p->listener == NULL) {
		paxos_log_error("Failed to bind on port %d", port);
		return 0;
	}
	evconnlistener_set_error_cb(p->listener, on_listener_error);
	paxos_log_info("Listening on port %d", port);
	return 1;
}
Exemplo n.º 12
0
static int 
bdb_init_tx_handle(struct storage* s, char* db_env_path)
{
	int result;
	DB_ENV* dbenv; 
	
	//Create environment handle
	result = db_env_create(&dbenv, 0);
	if (result != 0) {
		paxos_log_error("DB_ENV creation failed: %s", db_strerror(result));
		return -1;
	}
	
	//Durability mode
	if (!paxos_config.bdb_sync)
		result = dbenv->set_flags(dbenv, DB_TXN_WRITE_NOSYNC, 1);
	
	if (result != 0) {
		paxos_log_error("DB_ENV set_flags failed: %s", db_strerror(result));
		return -1;
	}
	
	//Redirect errors to sdout
	dbenv->set_errfile(dbenv, stdout);

	//Set the size of the memory cache
	result = dbenv->set_cachesize(dbenv, 0, paxos_config.bdb_cachesize, 1);
	if (result != 0) {
		paxos_log_error("DB_ENV set_cachesize failed: %s",
			db_strerror(result));
		return -1;
	}
	
	//TODO see page size impact
	//Set page size for this db
	// result = dbp->set_pagesize(dbp, pagesize);
	// assert(result  == 0);

	//FIXME set log size


	// Environment open flags
	int flags;
	flags =
		DB_CREATE       |  /* Create if not existing */ 
		DB_RECOVER      |  /* Run normal recovery. */
		DB_INIT_LOCK    |  /* Initialize the locking subsystem */
		DB_INIT_LOG     |  /* Initialize the logging subsystem */
		DB_INIT_TXN     |  /* Initialize the transactional subsystem. */
		DB_THREAD       |  /* Cause the environment to be free-threaded */  
		DB_REGISTER 	|
		DB_INIT_MPOOL;     /* Initialize the memory pool (in-memory cache) */

	//Open the DB environment
	result = dbenv->open(dbenv, 
		db_env_path,            /* Environment directory */
		flags,                  /* Open flags */
		0);                     /* Default file permissions */

	if (result != 0) {
		paxos_log_error("DB_ENV open failed: %s", db_strerror(result));
		return -1;
	}

	paxos_log_info("Berkeley DB storage opened successfully");
	
	s->env = dbenv;
	return 0;
}