Exemplo n.º 1
0
static int
setup_master(void)
{
    rstatus_t status;
    uint32_t j;
    vr_listen **vlisten;
    vr_worker *worker;

    for (j = 0; j < darray_n(&workers); j ++) {
        worker = darray_get(&workers, j);
        status = aeCreateFileEvent(master.vel.el, worker->socketpairs[0], 
            AE_READABLE, thread_event_process, worker);
        if (status == AE_ERR) {
            log_error("Unrecoverable error creating master ipfd file event.");
            return VR_ERROR;
        }
    }

    for (j = 0; j < darray_n(&master.listens); j ++) {
        vlisten = darray_get(&master.listens,j);
        status = aeCreateFileEvent(master.vel.el, (*vlisten)->sd, AE_READABLE, 
            client_accept, *vlisten);
        if (status == AE_ERR) {
            log_error("Unrecoverable error creating master ipfd file event.");
            return VR_ERROR;
        }
    }
    
    return VR_OK;
}
Exemplo n.º 2
0
int main(int argc, char **argv)
{
	int ret;
#if _LINUX_
	aeEventLoop *loop;
#endif

	SSRC = getpid();
	IPCAM_DEV = create_empty_ipcam_link();

#if !_LINUX_
	pthread_t deal_msg_pid;
	pthread_t deal_console_input_pid;
	pthread_t maintain_ipcam_link_pid;

	ret = pthread_create(&deal_console_input_pid, 0, 
				deal_console_input, NULL);
	if (ret) {
		debug_print("pthread_create failed");
		exit(errno);
	}

	ret = pthread_create(&deal_msg_pid, 0, 
				recv_msg_from_ipcam, NULL);
	if (ret) {
		debug_print("pthread_create failed");
		exit(errno);
	}

	ret = pthread_create(&maintain_ipcam_link_pid, 0, 
				maintain_ipcam_link, NULL);
	if (ret) {
		debug_print("pthread_create failed");
		exit(errno);
	}

	pthread_join(maintain_ipcam_link_pid, NULL);
	pthread_join(deal_msg_pid, NULL);
	pthread_join(deal_console_input_pid, NULL);
#else
	int pc_server_fd;

	pc_server_fd = init_server_UDP_fd(PC_SERVER_PORT, "0.0.0.0");
	assert(pc_server_fd > 0);
	loop = aeCreateEventLoop();
	fprintf(stdout, "\033[01;32mipc_shell> \033[0m");
	fflush(stdout);
	ret = aeCreateFileEvent(loop, STDIN_FILENO, AE_READABLE, dealcmd, NULL);
	assert(ret != AE_ERR);
	ret = aeCreateFileEvent(loop, pc_server_fd, AE_READABLE, dealnet, NULL);
	assert(ret != AE_ERR);
	aeCreateTimeEvent(loop, CHECK_IPCAM_CYCLE * 1000, watch_ipcam_link_clear, NULL, NULL);
	aeMain(loop);
#endif
	return 0;
}
Exemplo n.º 3
0
void init_server_config()
{
	g_server.port = DEFAULT_PORT;
	g_server.bindaddr = NULL;
	g_server.commands = NULL;
	g_server.clients = listCreate();
	g_server.el = aeCreateEventLoop(100 + 1024);
	if (g_server.el == NULL) {
		printf ("el error\n");
	}

	// create tcp server
	g_server.socket_fd = anetTcpServer(g_server.neterr, g_server.port, g_server.bindaddr);
	if (g_server.socket_fd == ANET_ERR) {
		printf ("socket error\n");
		exit(1);
	}

	// binding acceptTcpHandler to client connected. 
	if (g_server.socket_fd > 0) {
		if (aeCreateFileEvent(g_server.el, g_server.socket_fd, AE_READABLE, acceptTcpHandler, NULL) == AE_ERR){
			printf ("Unrecoverable error creating server.ipfd file event");
			exit(1);
		}
	}
}
Exemplo n.º 4
0
void initServer(){

    server.mainthread = pthread_self();
    server.clients = listCreate();
    server.el = aeCreateEventLoop();

    if (server.port != 0) {
        server.ipfd = anetTcpServer(server.neterr,server.port,server.bindaddr);
        if (server.ipfd == ANET_ERR) {
            redisLog(REDIS_WARNING, "Opening port %d: %s",
                server.port, server.neterr);
            exit(1);
        }
    }
//    if (server.unixsocket != NULL) {
//        unlink(server.unixsocket); /* don't care if this fails */
//        server.sofd = anetUnixServer(server.neterr,server.unixsocket,server.unixsocketperm);
//        if (server.sofd == ANET_ERR) {
//            redisLog(REDIS_WARNING, "Opening socket: %s", server.neterr);
//            exit(1);
//        }
//    }
    if (server.ipfd < 0 && server.sofd < 0) {
        redisLog(REDIS_WARNING, "Configured to not listen anywhere, exiting.");
        exit(1);
    }

    aeCreateTimeEvent(server.el, 1, serverCron, NULL, NULL);
    if (server.ipfd > 0 && aeCreateFileEvent(server.el,server.ipfd,AE_READABLE,
        acceptTcpHandler,NULL) == AE_ERR) oom("creating file event");
//    if (server.sofd > 0 && aeCreateFileEvent(server.el,server.sofd,AE_READABLE,
//        acceptUnixHandler,NULL) == AE_ERR) oom("creating file event");
}
Exemplo n.º 5
0
client *createClient(int fd) {
    client *c = malloc(sizeof(client));

    anetNonBlock(NULL,fd);
    anetEnableTcpNoDelay(NULL,fd);
    if (server.tcpkeepalive)
        anetKeepAlive(NULL,fd,server.tcpkeepalive);
    if (aeCreateFileEvent(server.el,fd,AE_READABLE,
        readQueryFromClient, c) == AE_ERR)
    {
        close(fd);
        free(c);
        return NULL;
    }

    c->id = server.next_client_id++;
    c->fd = fd;
    c->name = NULL;
    c->bufpos = 0;
    c->querybuf = sdsempty();
    c->querybuf_peak = 0;
    c->reqtype = 0;
    c->argc = 0;
    c->argv = NULL;
    c->lastcmd = NULL;
    c->multibulklen = 0;
    c->bulklen = -1;
    c->sentlen = 0;
    c->flags = 0;
    c->ctime = c->lastinteraction = server.unixtime;
    if (fd != -1) listAddNodeTail(server.clients,c);
    return c;
}
Exemplo n.º 6
0
void one_work_start(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask)
{
	int incomesock;
		
	if(read(fd,&incomesock,sizeof(incomesock)) != sizeof(incomesock))
	{
		logError(	"file :"__FILE__",line :%d"\
			"one_work_start get incomesock failed.",\
			__LINE__);
		return ;
	}
	
	if(setnonblocking(incomesock) < 0)
		return ;
	
	storage_client_t *pClient;

	pClient = init_storage_client(clientData);

	pClient->sockfd = incomesock;
	
	pClient->data.buff = &pClient->cmd;
	pClient->data.need_size = sizeof(pClient->cmd);
	pClient->data.proc = accept_command;
	
	if(aeCreateFileEvent(eventLoop, incomesock, AE_READABLE,nb_sock_recv_data,pClient) != AE_OK)
	{
		logError(	"file :"__FILE__",line :%d"\
			"one_work_start CreateFileEvent failed.",\
			__LINE__);
		clean_storage_client(pClient);
		return ;
	}
	return ;
}
Exemplo n.º 7
0
static void
smrConnect ()
{
  redisLog (REDIS_NOTICE,
	    "initialize SMR Connection, Local Dumpfile Seq Num:%lld",
	    server.smr_seqnum);
  server.smr_conn =
    smr_connect_tcp (server.smr_lport, server.smr_seqnum, &smrCb, NULL);

  if (server.smr_conn == NULL)
    {
      redisLog (REDIS_WARNING, "Failed to connect to smr, errno(%d)", errno);
      exit (1);
    }

  server.smr_fd = smr_get_poll_fd (server.smr_conn);
  if (server.smr_fd == -1)
    {
      redisLog (REDIS_WARNING, "Failed to get poll fd from smr");
      exit (1);
    }

  if (server.smr_fd > 0
      && aeCreateFileEvent (server.el, server.smr_fd, AE_READABLE,
			    processSmrCallback, NULL) == AE_ERR)
    {
      redisLog (REDIS_WARNING,
		"Unrecoverable error creating smr.fd file event.");
      smr_disconnect (server.smr_conn);
      exit (1);
    }
}
Exemplo n.º 8
0
struct gwseriport *gwseriport_create(const char *ttypath,int uart_speed)
{
        struct gwseriport *s = malloc(sizeof(*s));
        if(s == NULL)
                return NULL;
        memset(s,0,sizeof(*s));

        int fd = open_seriport(ttypath,uart_speed);
        if(fd < 0){
                free(s);
                return NULL;
        }

        s->recvbuf = buffer_create(1024);
        s->fd = fd;
        s->ttypath = strdup(ttypath);

        if(aeCreateFileEvent(server.el,fd,AE_READABLE,seriportHandler,s) == AE_ERR){
                close(fd);
                buffer_release(s->recvbuf);
                free(s);
                return NULL;
        }

        listAddNodeTail(server.seriports,s);
        
        return s;
}
Exemplo n.º 9
0
static void resetClient(client c) {
    aeDeleteFileEvent(config.el,c->context->fd,AE_WRITABLE);
    aeDeleteFileEvent(config.el,c->context->fd,AE_READABLE);
    aeCreateFileEvent(config.el,c->context->fd,AE_WRITABLE,writeHandler,c);
    c->written = 0;
    c->pending = config.pipeline;
}
Exemplo n.º 10
0
void new_nb_sock_send_file(struct aeEventLoop *eventLoop, int sockfd, void *clientData, int mask)
{
	storage_client_t *pClient;

	pClient = clientData;
	logDebug("new_nb_sock_send_file %s,%d",pClient->file.file_name,pClient->file.start_offlen);

	if(pClient->file.fd == 0)
	{
		if((pClient->file.fd = open(pClient->file.file_name,O_RDONLY)) == -1)
		{
			logError(	"file: "__FILE__",line: %d,"\
				"new_nb_sock_send_file call open file failed,"\
				"errno: %d,error info: %s",\
				__LINE__,errno,strerror(errno));
			return ;
		}
	}
	if(aeCreateFileEvent(eventLoop,sockfd, AE_WRITABLE,do_new_nb_sock_send_file,pClient) != AE_OK)
	{
			logError(	"file :"__FILE__",line :%d\
				new_nb_sock_send_file CreateFileEvent failed.",\
				__LINE__);
			return ;
	}
	return ;
}
Exemplo n.º 11
0
void readBodyFromPipe(  aeEventLoop *el, int fd , aePipeData data )
{
	int pos = PIPE_DATA_HEADER_LENG;
	int nread = 0;
	int needlen = data.len;
	int bodylen = 0;

	if( data.len <= 0 )
	{
		return;
	}
	
	nread = read( fd , data.data , needlen );
	//if (nread == -1 && errno == EAGAIN) return;
	if( nread < 0 )
	{
	 	if (nread == -1 && errno == EAGAIN) return;
		printf( "readBodyFromPipe error\n");   
	}

	//set writable event to connfd
	if ( sdslen( servG->connlist[data.connfd].send_buffer ) == 0  )
	{
        	aeCreateFileEvent( el, 
			data.connfd,
			AE_WRITABLE,
			onClientWritable,
			NULL 
		);
	}			
	servG->connlist[data.connfd].send_buffer = sdscatlen( servG->connlist[data.connfd].send_buffer ,data.data, nread );
}
Exemplo n.º 12
0
int main()
{

	printf("Start\n");

	signal(SIGINT, StopServer);

	//初始化网络事件循环
	g_event_loop = aeCreateEventLoop(1024*10);

	//设置监听事件
	int fd = anetTcpServer(g_err_string, PORT, NULL);
	if( ANET_ERR == fd )
		fprintf(stderr, "Open port %d error: %s\n", PORT, g_err_string);
	if( aeCreateFileEvent(g_event_loop, fd, AE_READABLE, AcceptTcpHandler, NULL) == AE_ERR )
		fprintf(stderr, "Unrecoverable error creating server.ipfd file event.");

	//设置定时事件
	aeCreateTimeEvent(g_event_loop, 1, PrintTimer, NULL, NULL);

	//开启事件循环
	aeMain(g_event_loop);

	//删除事件循环
	aeDeleteEventLoop(g_event_loop);

	printf("End\n");
	return 0;
}
Exemplo n.º 13
0
void *reactorThreadRun(void *arg)
{
    reactorThreadParam* param = (reactorThreadParam*)arg;
    aeServer* serv = param->serv;
    int thid = param->thid;
    aeEventLoop* el = aeCreateEventLoop( 1024 );
    serv->reactorThreads[thid].reactor.eventLoop = el;
 
    int ret,i;
	//每个线程都有workerNum个worker pipe
    for(  i = 0; i < serv->workerNum; i++ )
    {
        if ( aeCreateFileEvent( el,serv->workers[i].pipefd[0],
                     AE_READABLE,onMasterPipeReadable, thid  ) == -1 )
        {
            printf( "CreateFileEvent error fd "  );
            close(serv->workers[i].pipefd[0]);
        }
    }
    
    aeSetBeforeSleepProc( el ,initThreadOnLoopStart );
    aeMain( el );
	
    aeDeleteEventLoop( el );
    el = NULL;
}
Exemplo n.º 14
0
int create_storage_service()
{
	if((g_storage_service.sockfd = sock_server(g_storage_service.heart_beat.port)) < 0)
		return -1;
	
	if (tcpsetserveropt(g_storage_service.sockfd, g_storage_service.network_timeout) != 0)
	{
		return -2;
	}
	
	if((g_storage_service.eventLoop = (aeEventLoop*)aeCreateEventLoop()) == NULL)
	{
		logError(	"file :"__FILE__",line :%d"\
			"create_storage_service CreateEventLoop failed.");
		exit(1);
	}

	aeCreateTimeEvent(g_storage_service.eventLoop,g_storage_service.heart_beat_millisec,heart_beat_init,g_storage_service.nio_pool.nio_node,NULL);

	if(aeCreateFileEvent(g_storage_service.eventLoop, g_storage_service.sockfd, AE_READABLE,accept_tcp,NULL) != AE_OK)
	{
		logError(	"file :"__FILE__",line :%d"\
			"create_storage_service CreateFileEvent failed.");
		exit(1);
	}
	return 0;
}
Exemplo n.º 15
0
int create_tracker_service()
{
	if((g_tracker_service.sockfd = sock_server(g_tracker_service.server_port)) < 0)
		return -1;
	
	if (tcpsetserveropt(g_tracker_service.sockfd, g_tracker_service.network_timeout) != 0)
	{
		return -2;
	}
	
	if((g_tracker_service.eventLoop = (aeEventLoop*)aeCreateEventLoop()) == NULL)
	{
		logError(	"file :"__FILE__",line :%d"\
			"create_tracker_service CreateEventLoop failed.");
			return -3;
	}

	aeCreateTimeEvent(g_tracker_service.eventLoop,g_tracker_service.check_storage_pool_millisec,check_storage_pool,NULL,NULL);
	
	if(aeCreateFileEvent(g_tracker_service.eventLoop, g_tracker_service.sockfd, AE_READABLE,accept_tcp,NULL) != AE_OK)
	{
		logError(	"file :"__FILE__",line :%d"\
			"create_tracker_service CreateFileEvent failed.");
			return -4;
	}
	return 0;
}
Exemplo n.º 16
0
static int connect_socket(thread *thread, connection *c) {
    struct addrinfo addr = cfg.addr;
    struct aeEventLoop *loop = thread->loop;
    int fd, flags;

    fd = socket(addr.ai_family, addr.ai_socktype, addr.ai_protocol);

    flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);

    if (connect(fd, addr.ai_addr, addr.ai_addrlen) == -1) {
        if (errno != EINPROGRESS) goto error;
    }

    flags = 1;
    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags));

    if (aeCreateFileEvent(loop, fd, AE_READABLE, socket_handshake, c) != AE_OK) {
        goto error;
    }

    c->fd = fd;

    return fd;

  error:
    thread->errors.connect++;
    close(fd);
    return -1;
}
Exemplo n.º 17
0
void *reactorThreadRun( void *arg )
{
	reactorThreadParam *param = (reactorThreadParam *) arg;
	appnetServer *serv = param->serv;
	int thid = param->thid;
	aeEventLoop *el = aeCreateEventLoop( MAX_EVENT );
	serv->reactor_threads[thid].reactor.event_loop = el;
	serv->reactor_threads[thid].hh = (httpHeader *) malloc( sizeof(httpHeader) );
	serv->reactor_threads[thid].hs = (handshake *) malloc( sizeof(handshake) );
	
	int ret,i,index;
	for (i = 0; i < serv->worker_num + serv->task_worker_num; i++)
	{
		index = i * serv->reactor_num + thid;
		
		if (aeCreateFileEvent( el , serv->worker_pipes[index].pipefd[0] , AE_READABLE ,
				onMasterPipeReadable , thid ) == -1)
		{
			
			printf( "CreateFileEvent error fd " );
			close( serv->worker_pipes[index].pipefd[0] );
		}
	}
	
	aeSetBeforeSleepProc( el , initThreadOnLoopStart );
	aeMain( el );
	aeDeleteEventLoop( el );
	
	free( serv->reactor_threads[thid].hh );
	free( serv->reactor_threads[thid].hs );
	el = NULL;
}
Exemplo n.º 18
0
int main(int argc, char** argv) {
    signal(SIGABRT, &sighandler);
    signal(SIGTERM, &sighandler);
    signal(SIGINT, &sighandler);

    initServer();

    aeEventLoop* eventLoop = aeCreateEventLoop(server.max_process_client + SHTTPSVR_EVENTLOOP_FDSET_INCR);
    server.el = eventLoop;

    int listen_socket = anetTcpServer(NULL, 80, NULL, server.tcp_backlog);
    anetNonBlock(NULL, listen_socket);

    if (listen_socket > 0
        && AE_ERR == aeCreateFileEvent(eventLoop, listen_socket, AE_READABLE, tAcceptProc, NULL)) {
        ERRLOG("aeCreateFileEvent error!");
        exit(1);
    }

    aeSetBeforeSleepProc(eventLoop, tBeforeSleepProc);
    initTimeEvent(eventLoop);
    aeMain(eventLoop);
    aeDeleteEventLoop(eventLoop);
    return 0;
}
Exemplo n.º 19
0
void aeFileReadWrite(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask)
{
    int ret;
    printf("aeFileReadWrite mask = %d, fd = %d\n", mask, fd);
    if(server_fd == fd){
        struct sockaddr_in client_addr;
        socklen_t sin_size;
        printf("A New client connect\n"); 
        int new_fd = accept(fd, (struct sockaddr *)&client_addr, &sin_size);
        printf("New connection client%s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
        ret = aeCreateFileEvent(eventLoop, new_fd, AE_READABLE, aeFileReadWrite, NULL);
        if(ret == AE_ERR)
            printf("aeCreateFileEvent failed\n");

    }else{
        char buf[1024];
        ret = recv(fd, buf, sizeof(buf), 0);
        if (ret <= 0) {
            printf("A Client disconnet\n");
            aeDeleteFileEvent(eventLoop, fd, AE_READABLE | AE_WRITABLE);
            aeClose(fd);
        }else{
            buf[ret] = '\0'; 
            printf("Recv data: %s\n", buf);
        }
    }
}
Exemplo n.º 20
0
int acceptor_start(acceptor_t *acceptor)
{
    if(0!=aeCreateFileEvent(g_libnet.evLoop,acceptor->fd,
        AE_READABLE,_accept_handler,(void*)acceptor)){
        return (-1);
    }
    return 0;
}
Exemplo n.º 21
0
void addReplay(vuiClient *c, const char *body)
{
    if (body) c->res.body = sdscpy(c->res.body, body);
    else
        sdsclear(c->res.body);
    c->procing = PROC_HALF;
    aeCreateFileEvent(server.el, c->fd, AE_WRITABLE, sendReplay, c);
}
Exemplo n.º 22
0
redisClient *createClient(int fd) {
    redisClient *c = zmalloc(sizeof(redisClient));

    /* passing -1 as fd it is possible to create a non connected client.
     * This is useful since all the Redis commands needs to be executed
     * in the context of a client. When commands are executed in other
     * contexts (for instance a Lua script) we need a non connected client. */
    if (fd != -1) {
        anetNonBlock(NULL,fd);
        anetEnableTcpNoDelay(NULL,fd);
        if (server.tcpkeepalive)
            anetKeepAlive(NULL,fd,server.tcpkeepalive);
        if (aeCreateFileEvent(server.el,fd,AE_READABLE,
            readQueryFromClient, c) == AE_ERR)
        {
            close(fd);
            zfree(c);
            return NULL;
        }
    }

    selectDb(c,0);
    c->fd = fd;
    c->name = NULL;
    c->bufpos = 0;
    c->querybuf = sdsempty();
    c->querybuf_peak = 0;
    c->reqtype = 0;
    c->argc = 0;
    c->argv = NULL;
    c->cmd = c->lastcmd = NULL;
    c->multibulklen = 0;
    c->bulklen = -1;
    c->sentlen = 0;
    c->flags = 0;
    c->ctime = c->lastinteraction = server.unixtime;
    c->authenticated = 0;
    c->replstate = REDIS_REPL_NONE;
    c->slave_listening_port = 0;
    c->reply = listCreate();
    c->reply_bytes = 0;
    c->obuf_soft_limit_reached_time = 0;
    listSetFreeMethod(c->reply,decrRefCount);
    listSetDupMethod(c->reply,dupClientReplyValue);
    c->bpop.keys = dictCreate(&setDictType,NULL);
    c->bpop.timeout = 0;
    c->bpop.target = NULL;
    c->io_keys = listCreate();
    c->watched_keys = listCreate();
    listSetFreeMethod(c->io_keys,decrRefCount);
    c->pubsub_channels = dictCreate(&setDictType,NULL);
    c->pubsub_patterns = listCreate();
    listSetFreeMethod(c->pubsub_patterns,decrRefCount);
    listSetMatchMethod(c->pubsub_patterns,listMatchObjects);
    if (fd != -1) listAddNodeTail(server.clients,c);
    initClientMultiState(c);
    return c;
}
Exemplo n.º 23
0
int SetWriteEvent(proxy_client*c)
{
    if(aeCreateFileEvent(el,c->fd,AE_WRITABLE,SendOutcome,c)==AE_ERR){
	LogError("Set write event failed");
	return -1;
    }
    return 0;

}
Exemplo n.º 24
0
/* Set the event loop to listen for write events on the client's socket.
 * Typically gets called every time a reply is built. */
int _installWriteEvent(redisClient *c) {
    if (c->fd <= 0) return REDIS_ERR;
    if (c->bufpos == 0 && listLength(c->reply) == 0 &&
        (c->replstate == REDIS_REPL_NONE ||
         c->replstate == REDIS_REPL_ONLINE) &&
        aeCreateFileEvent(server.el, c->fd, AE_WRITABLE,
        sendReplyToClient, c) == AE_ERR) return REDIS_ERR;
    return REDIS_OK;
}
Exemplo n.º 25
0
//此函数必须在写入send_buffer前执行
void setPipeWritable( aeEventLoop *el , void *privdata ,  int worker_id  )
{
	if (sdslen( servG->workers[worker_id].send_buffer ) == 0  )
	{
        	aeCreateFileEvent( el, 
			servG->workers[worker_id].pipefd[0],
			AE_WRITABLE,
			onMasterPipeWritable, worker_id );
	}			
}
Exemplo n.º 26
0
/* This function is called every time we are going to transmit new data
 * to the client. The behavior is the following:
 *
 * If the client should receive new data (normal clients will) the function
 * returns REDIS_OK, and make sure to install the write handler in our event
 * loop so that when the socket is writable new data gets written.
 *
 * If the client should not receive new data, because it is a fake client
 * or a slave, or because the setup of the write handler failed, the function
 * returns REDIS_ERR.
 *
 * Typically gets called every time a reply is built, before adding more
 * data to the clients output buffers. If the function returns REDIS_ERR no
 * data should be appended to the output buffers. */
int prepareClientToWrite(redisClient *c) {
    if (c->flags & REDIS_LUA_CLIENT) return REDIS_OK;
    if (c->fd <= 0) return REDIS_ERR; /* Fake client */
    if (c->bufpos == 0 && listLength(c->reply) == 0 &&
        (c->replstate == REDIS_REPL_NONE ||
         c->replstate == REDIS_REPL_ONLINE) &&
        aeCreateFileEvent(server.el, c->fd, AE_WRITABLE,
        sendReplyToClient, c) == AE_ERR) return REDIS_ERR;
    return REDIS_OK;
}
Exemplo n.º 27
0
/* This function is called at the end of every background saving.
 * The argument bgsaveerr is REDIS_OK if the background saving succeeded
 * otherwise REDIS_ERR is passed to the function.
 *
 * The goal of this function is to handle slaves waiting for a successful
 * background saving in order to perform non-blocking synchronization. */
void updateSlavesWaitingBgsave(int bgsaveerr) {
//backgroundSaveDoneHandler在BGSAVE操作完成后,调用这里来处理可能的从库事件。
    listNode *ln;
    int startbgsave = 0;
    listIter li;

    listRewind(server.slaves,&li);
    while((ln = listNext(&li))) {//循环遍历每一个从库,查看其状态进行相应的处理。
        redisClient *slave = ln->value;

        if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_START) {
            startbgsave = 1;//刚才在做bgsave的时候,有客户端来请求sync同步,但是我没有理他,现在得给他准备了。
            slave->replstate = REDIS_REPL_WAIT_BGSAVE_END;//修改这个状态后,新的写入操作会记录到这个连接的缓存里
        } else if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_END) {
        //后台保存完成,下面需要发送rdb文件了,丫的够大的
            struct redis_stat buf;

            if (bgsaveerr != REDIS_OK) {
                freeClient(slave);
                redisLog(REDIS_WARNING,"SYNC failed. BGSAVE child returned an error");
                continue;
            }
			//打开这个rdb_filename,要准备给这个slave发送数据了。
            if ((slave->repldbfd = open(server.rdb_filename,O_RDONLY)) == -1 ||
                redis_fstat(slave->repldbfd,&buf) == -1) {
                freeClient(slave);
                redisLog(REDIS_WARNING,"SYNC failed. Can't open/stat DB after BGSAVE: %s", strerror(errno));
                continue;
            }
            slave->repldboff = 0;
            slave->repldbsize = buf.st_size;
//记住此时slave->repldbfd没有关闭,可写事件的时候就不需要打开了。
            slave->replstate = REDIS_REPL_SEND_BULK;
            aeDeleteFileEvent(server.el,slave->fd,AE_WRITABLE);//删掉之前的可写回调,注册为sendBulkToSlave
            if (aeCreateFileEvent(server.el, slave->fd, AE_WRITABLE, sendBulkToSlave, slave) == AE_ERR) {
                freeClient(slave);
                continue;
            }
        }
    }
    if (startbgsave) {//悲剧,又有要sync的,还得保存一次。
        if (rdbSaveBackground(server.rdb_filename) != REDIS_OK) {
            listIter li;

            listRewind(server.slaves,&li);
            redisLog(REDIS_WARNING,"SYNC failed. BGSAVE failed");
            while((ln = listNext(&li))) {
                redisClient *slave = ln->value;
				//这下面似乎有问题,replstate已经在上面被设置为了_END。https://github.com/antirez/redis/issues/1308
                if (slave->replstate == REDIS_REPL_WAIT_BGSAVE_START)
                    freeClient(slave);
            }
        }
    }
}
Exemplo n.º 28
0
static void acceptCommonHandler(int fd, int flags, char *ip) {
    client *c = (client *)zmalloc(sizeof(client));
    c->fd = fd;
    if (aeCreateFileEvent(server.el, fd, AE_READABLE, readClient, (void *) c) == AE_ERR) {
        close(fd);
        zfree(c);
        return;
    }
    anetNonBlock(NULL, fd);
    return;
}
Exemplo n.º 29
0
void sendBulkToSlave(aeEventLoop *el, int fd, void *privdata, int mask) {
    redisClient *slave = privdata;
    REDIS_NOTUSED(el);
    REDIS_NOTUSED(mask);
    char buf[REDIS_IOBUF_LEN];
    ssize_t nwritten, buflen;

    if (slave->repldboff == 0) {
        /* Write the bulk write count before to transfer the DB. In theory here
         * we don't know how much room there is in the output buffer of the
         * socket, but in pratice SO_SNDLOWAT (the minimum count for output
         * operations) will never be smaller than the few bytes we need. */
        sds bulkcount;

        bulkcount = sdscatprintf(sdsempty(),"$%lld\r\n",(unsigned long long)
            slave->repldbsize);
        if (write(fd,bulkcount,sdslen(bulkcount)) != (signed)sdslen(bulkcount))
        {
            sdsfree(bulkcount);
            freeClient(slave);
            return;
        }
        sdsfree(bulkcount);
    }
    lseek(slave->repldbfd,slave->repldboff,SEEK_SET);
    buflen = read(slave->repldbfd,buf,REDIS_IOBUF_LEN);
    if (buflen <= 0) {
        redisLog(REDIS_WARNING,"Read error sending DB to slave: %s",
            (buflen == 0) ? "premature EOF" : strerror(errno));
        freeClient(slave);
        return;
    }
    if ((nwritten = write(fd,buf,buflen)) == -1) {
        redisLog(REDIS_VERBOSE,"Write error sending DB to slave: %s",
            strerror(errno));
        freeClient(slave);
        return;
    }
    slave->repldboff += nwritten;
    if (slave->repldboff == slave->repldbsize) {
        close(slave->repldbfd);
        slave->repldbfd = -1;
        aeDeleteFileEvent(server.el,slave->fd,AE_WRITABLE);
        slave->replstate = REDIS_REPL_ONLINE;
        if (aeCreateFileEvent(server.el, slave->fd, AE_WRITABLE,
            sendReplyToClient, slave) == AE_ERR) {
            freeClient(slave);
            return;
        }
        addReplySds(slave,sdsempty());
        redisLog(REDIS_NOTICE,"Synchronization with slave succeeded");
    }
}
Exemplo n.º 30
0
/* Set the event loop to listen for write events on the client's socket.
 * Typically gets called every time a reply is built. */
int _installWriteEvent(redisClient *c) {
    /* When CLOSE_AFTER_REPLY is set, no more replies may be added! */
    redisAssert(!(c->flags & REDIS_CLOSE_AFTER_REPLY));

    if (c->fd <= 0) return REDIS_ERR;
    if (c->bufpos == 0 && listLength(c->reply) == 0 &&
        (c->replstate == REDIS_REPL_NONE ||
         c->replstate == REDIS_REPL_ONLINE) &&
        aeCreateFileEvent(server.el, c->fd, AE_WRITABLE,
        sendReplyToClient, c) == AE_ERR) return REDIS_ERR;
    return REDIS_OK;
}