示例#1
0
void run_thread(struct message *info)
{
    struct sockaddr_in client_address ;
    socklen_t client_length ;
    client_length = sizeof(client_address);
    void error(const char *msg) ;
    int new_socket_fd = accept(info->socket_fd, (struct sockaddr *) &client_address, &client_length);
    if (new_socket_fd < 0)
    {
        error("error on accept new socket!");
    }
    int pid = fork();
    if (pid < 0) 
    {
        error("error on on fork");
    }
    if (pid == 0) {
        close(info->socket_fd);
        handler_request(new_socket_fd);
        exit(0);
    }
    else
    {
        close(new_socket_fd) ;
    }
    pthread_exit(NULL);
}
示例#2
0
void
loop(void)
{
	int listenfd, clifd;
	int rval, i, nr;
	int maxi, maxfd;
	uid_t uid;
	fd_set rset, allset;
	char buf[MAXLINE];

	/* obtain fd to listen for client request on */
	if ((listenfd = serv_listen(CS_OPEN)) < 0) 
		log_sys("serv_listen error");

	FD_ZERO(&allset);
	FD_SET(listenfd, &allset);
	maxfd = listenfd;
	maxi = -1;
	
	for (;;) {
		rset = allset;              /* rset get modified each time around */
		rval = select(maxfd + 1, &rset, NULL, NULL, NULL);
		if (rval < 0) 
			log_sys("select error");

		if (FD_ISSET(listenfd, &rset)) {
			/* accept new client request */
			if ((clifd = serv_accept(listenfd, &uid)) < 0)
				log_sys("serv_accept error");
			i = client_add(clifd, uid);
			FD_SET(clifd, &allset);
			if (i > maxi)
				maxi = i;
			if (clifd > maxfd)
				maxfd = clifd;
			log_msg("new connection: uid %d, fd %d", uid, clifd);
			continue;
		}
		for (i = 0; i <= maxi; i++) {
			if (client[i].fd == -1)
				continue;
		
			if (FD_ISSET(client[i].fd, &rset)) {
				/* read argument buffer from client */
				if ((nr = read(client[i].fd, buf, MAXLINE)) < 0) {
					log_sys("read error on fd %d", clifd);
				} else if (nr == 0) {
					log_msg("closed: uid %d, fd %d",
						client[i].uid, clifd);
					client_del(client[i].fd);  /* client has closed cxn */
					FD_CLR(clifd, &allset);
					close(clifd);
				} else {  /* process client's request */
					handler_request(buf, nr, clifd, client[i].uid);
				}
			}	
		}
	}
}
示例#3
0
void msg_process(char * (*handler_request)(char *req_buf, int fd))
{
	LOCALTSS(tss);
	int resp_size;
	RPCREQ* req;
	char* resp;

	int fd;
	MSG_DATA *req_msg;
	MSG_DATA *resp_msg;


	req_msg = NULL;
	resp_msg = NULL;
	
	while(TRUE)
	{
		
		pthread_mutex_lock(&mutex);

		while (msg_list_head == NULL)
			pthread_cond_wait(&cond, &mutex);

	
		req_msg = msg_list_head;
		msg_list_head = msg_list_head->next;
		msg_list_len--;
		pthread_mutex_unlock(&mutex);

		if(!strncasecmp(RPC_RBD_MAGIC, req_msg->data, STRLEN(RPC_RBD_MAGIC)))
		{
			req = conn_build_req(req_msg->block_buffer, req_msg->n_size);
		}
		else
		{
			req = conn_build_req(req_msg->data, req_msg->n_size);
		}
		
		fd = req_msg->fd;

		if(req_msg->n_size)
		{
			resp = handler_request(req->data, fd);

			if (resp == NULL)
			{
				if (tss->tstat & TSS_PARSER_ERR)
				{
					resp = conn_build_resp_byte(RPC_PARSER_ERR, 0, NULL);
				}
				else
				{
					resp = conn_build_resp_byte(RPC_FAIL, 0, NULL);					
				}
			}
		}
		else
		{	resp = conn_build_resp_byte(RPC_FAIL, 0, NULL);
		}

		/* If it's the select where/range session, skip the success operation. */
		if((fd < 0) || (((RPCRESP *)resp)->status_code & RPC_SKIP_SEND))
		{
			//local msg, such as recovery task msg, so no need to response
			goto finish;
		}

		resp_size = conn_get_resp_size((RPCRESP *)resp);

		resp_msg = NULL;
		resp_msg = (MSG_DATA *)msg_mem_alloc();
		resp_msg->n_size = resp_size;
		resp_msg->block_buffer = NULL;
		Assert(resp_size < MSG_SIZE);
		MEMCPY(resp_msg->data, resp, resp_size);
		resp_msg->fd = fd;	
		
		struct epoll_event ev;
		ev.data.ptr = resp_msg;
	
		ev.events = EPOLLOUT | EPOLLET;

		epoll_ctl(epfd, EPOLL_CTL_MOD, fd, &ev);

finish:

		if (req_msg->block_buffer != NULL)
		{
			free(req_msg->block_buffer);
		}
		
		msg_mem_free(req_msg);
  
		conn_destroy_req(req);
		conn_destroy_resp_byte(resp);		
		
		tss_init(tss);
	}
}