Example #1
0
int rpc_start(rpc_t *rpc) {
	if (!rpc) {
		RPC_DEBUG("rpc is NULL");
		goto fail;
	}

	if (!rpc->handler) {
		RPC_DEBUG("rpc handler is NULL");
		goto fail;
	}
	
	if (pthread_create(&rpc->rpc_thread, NULL, do_rpc_thread, rpc)) {
		RPC_PERROR("pthread_create");
		goto fail;
	}

	while (!rpc->active) {
		rpc_cond_wait(rpc);
	}

	return 0;

fail:
	return -1;
}
Example #2
0
static int rpc_recv(struct rpc *rpc) {
	struct rpc_request_hdr_t hdr;
	struct rpc_reply_t reply;
	LOG_ENTRY;
		
	memset(&reply, 0, sizeof(reply));
	if (rpc_read(rpc->fd, &hdr, sizeof(hdr)) < 0) {
		RPC_PERROR("rpc_read");
		goto fail;
	}

	RPC_DEBUG("<<< header code %x", hdr.code);
	if (rpc->handler(&hdr, &reply)) {
		RPC_ERROR("failed to handle message");
		goto fail;
	}
	RPC_DEBUG("<<< handled message %x", hdr.code);

	if (rpc_write(rpc->fd, &reply, sizeof(reply)) < 0) {
		RPC_PERROR("rpc_write");
		goto fail;
	}
	RPC_DEBUG("<<< done with message %x", hdr.code);

	LOG_EXIT;
	return 0;
fail:
	return -1;
}
Example #3
0
/**
 * @brief wrapper for connect api
 *
 * @param ip
 * @param port
 * @param timeout_ms
 *
 * @return 
 */
int connect_ex(char *ip, unsigned short port, 
        int timeout_ms) {

    /* create socket */
    int fd = socket(PF_INET, SOCK_STREAM, 0);
    if (-1 == fd) {
        RPC_WARNING("socket() error, errno=%d", errno);
        return -1;
    }
    RPC_DEBUG("socket created, fd=%d", fd);

    /* set to nonblock socket */
    if (-1 == set_nonblock(fd)) {
        RPC_WARNING("set_nonblock() error, errno=%d", errno);
        close(fd);
        return -1;
    }

    /* connect to remote server */
    struct sockaddr_in remote_addr;
    memset(&remote_addr, 0, sizeof(remote_addr));
    remote_addr.sin_family = AF_INET;
    remote_addr.sin_port = htons(port);
    remote_addr.sin_addr.s_addr = inet_addr(ip);

    int ret = connect(fd, (struct sockaddr*)&remote_addr, sizeof(remote_addr));
    if (0 == ret) {
        RPC_DEBUG("connect_ex() succ, fd=%d, ip=%s, port=%u", fd, ip, port);
        return fd;
    }
    if (-1 != ret || EINPROGRESS != errno) {
        RPC_WARNING("connect() error, ret=%d, errno=%d", ret, errno);
        close(fd);
        return -1;
    }

    /* wait until fd is writable */
    ret = wait_for_io(fd, 'o', timeout_ms);
    if (ret < 0) {
        RPC_WARNING("wait_for_io() timeout, fd=%d", fd);
        close(fd);
        return -1;
    }

    /* check socket status */
    int socket_res;
    socklen_t res_len = sizeof(socket_res);
    if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &socket_res, &res_len) < 0) {
        RPC_WARNING("getsockopt() error, fd=%d, errno=%d", fd, errno);
        close(fd);
    }
    if (0 != socket_res) {
        RPC_WARNING("connect() error, remote not available, fd=%d", fd);
        close(fd);
        return -1;
    }
    RPC_DEBUG("connect_ex() succ, fd=%d, ip=%s, port=%u", fd, ip, port);
    return fd;
}
Example #4
0
static void* do_rpc_thread(void *data) {
	LOG_ENTRY;

	struct rpc *rpc = data;
	if (!rpc || !rpc->handler) {
		RPC_PUTS("bad rpc");
		LOG_EXIT;
		return NULL;
	}
	
	rpc->active = 1;
	rpc_cond_signal(rpc);

	fd_set fds;

	while (rpc->active) {
		RPC_DEBUG("+loop");
		
		FD_ZERO(&fds);
		FD_SET(rpc->fd, &fds);
		FD_SET(rpc->pipefd[READ_END], &fds);

		select(max(rpc->fd, rpc->pipefd[READ_END]) + 1, &fds, NULL, NULL, NULL);
		pthread_mutex_lock(&rpc->fd_mutex);
		if (FD_ISSET(rpc->fd, &fds)) {
			RPC_DEBUG("receiving RPC message");
			if (rpc_recv(rpc) < 0) {
				RPC_ERROR("receive error");
				rpc->active = 0;
				goto handled;
			}
		}
		if (FD_ISSET(rpc->pipefd[READ_END], &fds)) {
			RPC_DEBUG("calling remote party");
			if (rpc_send(rpc) < 0) {
				RPC_ERROR("call error");
				rpc->active = 0;
				goto handled;
			}
		}
handled:
		pthread_mutex_unlock(&rpc->fd_mutex);
		RPC_DEBUG("-loop");
	}
	rpc_cond_signal(rpc);

	LOG_EXIT;
	return NULL;
}
Example #5
0
static void xtra_cb_thread_func(void* unused) {
	LOG_ENTRY;
	while (pipe_xtra[0] >= 0) {
		struct rpc_request_hdr_t hdr;
		memset(&hdr, 0, sizeof(hdr));
		if (read(pipe_xtra[READ_END], &hdr, sizeof(hdr)) != sizeof(hdr)) {
			RPC_ERROR("failed to read request header");
			break;
		}
		
		char *buf = hdr.buffer;
		size_t idx = 0;
		
		RPC_DEBUG("%s: request code %d", __func__, hdr.code);

		switch (hdr.code) {
		case XTRA_REQUEST_CB:
			if (xtraCallbacks && xtraCallbacks->download_request_cb) {
				xtraCallbacks->download_request_cb();
			}
			else {
				RPC_ERROR("xtraCallbacks == NULL");
			}
			break;
		}
fail:
		continue;
	}
	LOG_EXIT;
}
Example #6
0
static void ni_cb_thread_func(void* unused) {
	LOG_ENTRY;
	while (pipe_ni[0] >= 0) {
		struct rpc_request_hdr_t hdr;
		memset(&hdr, 0, sizeof(hdr));
		if (read(pipe_ni[READ_END], &hdr, sizeof(hdr)) != sizeof(hdr)) {
			RPC_ERROR("failed to read request header");
			break;
		}
		
		char *buf = hdr.buffer;
		size_t idx = 0;
		
		RPC_DEBUG("%s: request code %d", __func__, hdr.code);

		switch (hdr.code) {
		case NI_NOTIFY_CB:
			if (niCallbacks && niCallbacks->notify_cb) {
				GpsNiNotification nfy;
				memset(&nfy, 0, sizeof(nfy));
				RPC_UNPACK(buf, idx, nfy);
				niCallbacks->notify_cb(&nfy);
			}
			else {
				RPC_ERROR("niCallbacks == NULL");
			}
			break;
		}
fail:
		continue;
	}
	LOG_EXIT;
}
Example #7
0
static void agps_cb_thread_func(void* unused) {
	LOG_ENTRY;
	while (pipe_agps[0] >= 0) {
		struct rpc_request_hdr_t hdr;
		memset(&hdr, 0, sizeof(hdr));
		if (read(pipe_agps[READ_END], &hdr, sizeof(hdr)) != sizeof(hdr)) {
			RPC_ERROR("failed to read request header");
			break;
		}
		
		char *buf = hdr.buffer;
		size_t idx = 0;
		
		RPC_DEBUG("%s: request code %d", __func__, hdr.code);

		switch (hdr.code) {
		case AGPS_STATUS_CB:
			if (aGpsCallbacks && aGpsCallbacks->status_cb) {
				AGpsStatus status;
				memset(&status, 0, sizeof(status));
				RPC_UNPACK(buf, idx, status);
				aGpsCallbacks->status_cb(&status);
			}
			else {
				RPC_ERROR("aGpsCallbacks == NULL");
			}
			break;
		}
fail:
		continue;
	}
	LOG_EXIT;
}
Example #8
0
static int rpc_call_result(rpc_t *rpc, rpc_request_t *req)
{
	LOG_ENTRY;
	int rc = -1;

	if (!rpc) {
		RPC_ERROR("rpc is NULL");
		goto fail;
	}

	if (!req) {
		RPC_ERROR("request is NULL");
		goto fail;
	}

	rc = rpc_call(rpc, req);
	if (rc < 0) {
		RPC_ERROR("rpc_call failed %d", rc);
		goto fail;
	}
	RPC_DEBUG("%s: rpc_call done", __func__);

	size_t idx = 0;
	RPC_UNPACK(req->reply.buffer, idx, rc);
fail:
	LOG_EXIT;
	return rc;
}
Example #9
0
static int agps_data_conn_open(const char *apn) {
	LOG_ENTRY;
	struct rpc_request_t req = {
		.header = {
			.code = GPS_PROXY_AGPS_DATA_CONN_OPEN,
		},
	};

	int rc = -1;
	char *buf = req.header.buffer;
	size_t idx = 0;

	if (!apn) {
		RPC_DEBUG("%s: apn is NULL", __func__);
		goto fail;
	}

	memset(req.header.buffer, 0, RPC_PAYLOAD_MAX);
	RPC_PACK_S(buf, idx, apn);
	req.header.buffer[RPC_PAYLOAD_MAX - 1] = '\0';

	rc = rpc_call_result(gps_rpc, &req);
fail:
	LOG_EXIT;
	return rc;
}
Example #10
0
/**
 * @brief wrapper for recv api
 *
 * @param fd
 * @param buf
 * @param expect_len
 * @param flags
 * @param timeout_ms
 *
 * @return 
 */
int recv_ex(int fd, char *buf, int expect_len, 
        int flags, int timeout_ms) {

    int prev_ms = timeout_ms;

    int recv_len = 0;
    while (recv_len < expect_len) {
        unsigned long long prev_msec = get_cur_msec();

        int ret = wait_for_io(fd, 'i', timeout_ms);
        timeout_ms = MAX(0, timeout_ms - (get_cur_msec() - prev_msec));

        if (-1 == ret) {
            /* time expired or error */
            RPC_WARNING("wait_for_io() timeout, fd=%d", fd);
            return -1;
        } else {
            /* handle I/O event */
            int len = recv(fd, buf + recv_len, expect_len - recv_len, flags);
            if (len == 0) { 
                RPC_WARNING("client closed socket, fd=%d", fd);
                return -1;
            } else if (len < 0) { 
                RPC_WARNING("recv() error, fd=%d, errno=%d", fd, errno);
                return -1;
            } else {
                recv_len += len;
            }
        }
    }
    RPC_DEBUG("recv_ex() succ, fd=%d, recv_len=%d, cost_ms=%d", 
            fd, recv_len, prev_ms - timeout_ms);
    return recv_len;
}
Example #11
0
/**
 * @brief wrapper for send api
 *
 * @param fd
 * @param buf
 * @param expect_len
 * @param flags
 * @param timeout_ms
 *
 * @return 
 */
int send_ex(int fd, char *buf, int expect_len,
        int flags, int timeout_ms) {

    int prev_ms = timeout_ms;

    int send_len = 0;
    while (send_len < expect_len) {
        unsigned long long prev_msec = get_cur_msec();

        int ret = wait_for_io(fd, 'o', timeout_ms);
        timeout_ms = MAX(0, timeout_ms - (get_cur_msec() - prev_msec));

        if (-1 == ret) {
            /* time expired or error */
            RPC_WARNING("wait_for_io() timeout, fd=%d", fd);
            return -1;
        } else {
            /* handle I/O event */
            int len = send(fd, buf + send_len, expect_len - send_len, flags);
            if (len > 0) { 
                send_len += len;
            } else {
                RPC_WARNING("send() error, fd=%d, errno=%d", fd, errno);
                return -1;
            }
        }
    }
    RPC_DEBUG("send_ex() succ, fd=%d, send_len=%d, cost_ms=%d", 
            fd, send_len, prev_ms - timeout_ms);
    return send_len;
}
Example #12
0
/**
 * @brief notify process event(multi-threads call)
 */
void http_event::on_process() {
    RPC_DEBUG("compute %s", m_head.c_str());
    this->set_response(m_head + "\r\n\r\n" + m_body);

    this->set_io_type('o');
    this->set_state("write");
    this->set_timeout(RPC_SEND_TIMEOUT);
    m_svr->add_io_event(this);
}
Example #13
0
int __rpc_call(struct rpc *rpc, struct rpc_request_t *req, int wait) {
	int ret = 0;
	LOG_ENTRY;

	int done = 0;
	req->reply_marker = &done;

	RPC_DEBUG("%s: writing to pipe code=%d", __func__, req->header.code);

	pthread_mutex_lock(&rpc->pipe_mtx);
	ret = write(rpc->pipefd[WRITE_END], req, sizeof(rpc_request_t));
	pthread_mutex_unlock(&rpc->pipe_mtx);

	if (ret < 0) {
		RPC_PERROR("write");
		goto fail;
	}

	if (!wait) {
		goto done;
	}

	while (!done && rpc->active) {
		RPC_DEBUG("%s: waiting for reply", __func__);
		rpc_cond_wait(rpc);
	}
	RPC_DEBUG("got reply");

done:
	ret = 0;

	if (!done || !rpc->active) {
		RPC_DEBUG("error");
		ret = -1;
	}

fail:
	LOG_EXIT;
	return ret;
}
Example #14
0
static int rpc_send(struct rpc *rpc) {
	LOG_ENTRY;

	struct rpc_request_t req;

	pthread_mutex_lock(&rpc->pipe_mtx);
	int rc = read(rpc->pipefd[READ_END], &req, sizeof(req));
	pthread_mutex_unlock(&rpc->pipe_mtx);

	if (rc < 0) {
		RPC_PERROR("read");
		goto fail;
	}

	RPC_DEBUG(">>> code %x", req.header.code);
	
	if (rpc_write(rpc->fd, &req.header, sizeof(rpc_request_hdr_t)) < 0) {
		RPC_PERROR("rpc_write");
		goto fail;
	}
	RPC_DEBUG(">>> sent header");

	if (rpc_read(rpc->fd, &req.reply, sizeof(rpc_reply_t)) < 0) {
		RPC_PERROR("rpc_read");
		goto fail;
	}
	RPC_DEBUG(">>> reply code %x", req.reply.code);

	if (req.reply_marker) {
		req.reply_marker[0] = 1;
	}
	rpc_cond_signal(rpc);

	LOG_EXIT;
	return 0;
fail:
	return -1;
}
Example #15
0
rpc_t *rpc_alloc(void) {
	rpc_t *ret = NULL;

	ret = (rpc_t*)malloc(sizeof(rpc_t));
	if (!ret) {
		RPC_DEBUG("out of memory");
		goto fail;
	}
	memset(ret, 0, sizeof(rpc_t));

	return ret;
fail:
	if (ret) {
		free(ret);
	}
	return NULL;
}
Example #16
0
static void ril_cb_thread_func(void* unused) {
	LOG_ENTRY;
	while (pipe_ril[0] >= 0) {
		struct rpc_request_hdr_t hdr;
		memset(&hdr, 0, sizeof(hdr));
		if (read(pipe_ril[READ_END], &hdr, sizeof(hdr)) != sizeof(hdr)) {
			RPC_ERROR("failed to read request header");
			break;
		}
		
		char *buf = hdr.buffer;
		size_t idx = 0;
		
		RPC_DEBUG("%s: request code %d", __func__, hdr.code);

		switch (hdr.code) {
		case RIL_SET_ID_CB:
			if (rilCallbacks && rilCallbacks->request_setid) {
				uint32_t flags;
				RPC_UNPACK(buf, idx, flags);
				rilCallbacks->request_setid(flags);
			}
			else {
				RPC_ERROR("rilCallbacks == NULL");
			}
			break;

		case RIL_REF_LOC_CB:
			if (rilCallbacks && rilCallbacks->request_refloc) {
				uint32_t flags;
				RPC_UNPACK(buf, idx, flags);
				rilCallbacks->request_refloc(flags);
			}
			else {
				RPC_ERROR("rilCallbacks == NULL");
			}
			break;
		}
fail:
		continue;
	}
	LOG_EXIT;
}
Example #17
0
/**
 * @brief notify incoming read head event
 */
void http_event::on_read_head() {
    char buf[128] = { 0 };
    int len = recv(m_fd, buf, sizeof(buf), 0);
    if (len == 0) { 
        RPC_WARNING("client closed socket, fd=%d, ip=%s, port=%u", 
                m_fd, m_ip.c_str(), m_port);
        return;
    } 
    if (len < 0) { 
        RPC_WARNING("recv() error, fd=%d, errno=%d, ip=%s, port=%u", 
                m_fd, errno, m_ip.c_str(), m_port);
        return;
    } 

    //RPC_DEBUG("recv head, fd=%d, read_len=%d", m_fd, len);
    m_head.append(buf, len);

    std::size_t pos = m_head.find("\r\n\r\n");

    if (pos == std::string::npos) {
        /* read head not done */
        this->set_state("read_head");
        m_svr->add_io_event(this);
    } else {
        /* read head done */
        RPC_DEBUG("read head done, fd=%d", m_fd);

        m_body = m_head.substr(pos + strlen("\r\n\r\n"));
        m_head = m_head.substr(0, pos);

        this->parse_http_head();
        if (m_body.size() < m_content_len) {
            this->set_state("read_body");
            m_svr->add_io_event(this);
        } else {
            m_body.resize(m_content_len);
            this->set_state("compute");
            this->on_cmplt_pkg();
        }
    }
}
Example #18
0
static const void *gps_get_extension(const char *name) {
	if (!name) {
		RPC_ERROR("%s: name is NULL", __func__);
		return NULL;
	}

	RPC_DEBUG("%s:%s", __func__, name);
	if (!strcmp(name, GPS_XTRA_INTERFACE)) {
		return &sGpsXtraInterface;
	}
	else if (!strcmp(name, AGPS_INTERFACE)) {
		return &sAGpsInterface;
	}
	else if (!strcmp(name, GPS_NI_INTERFACE)) {
		return &sGpsNiInterface;
	}
	else if (!strcmp(name, AGPS_RIL_INTERFACE)) {
		return &sRilInterface;
	}
	return NULL;
}
Example #19
0
/**
 * @brief notify incoming write event
 */
void http_event::on_write() {
    int len = send(m_fd, (char*)m_resp_data.data(), m_resp_data.size(), 0);
    if (len == 0) { 
        RPC_WARNING("send() error, fd=%d, errno=%d, ip=%s, port=%u, forget resp_data?", 
                m_fd, errno, m_ip.c_str(), m_port);
        return;
    }
    if (len < 0) { 
        RPC_WARNING("send() error, fd=%d, errno=%d, ip=%s, port=%u", 
                m_fd, errno, m_ip.c_str(), m_port);
        return;
    }
    //RPC_DEBUG("send, fd=%d, send_len=%d", m_fd, len);
    m_resp_data = m_resp_data.substr(len);
    if (m_resp_data.size() > 0) {
        this->set_state("write");
        m_svr->add_io_event(this);
    } else {
        RPC_DEBUG("session over, fd=%d", m_fd);
    }
}
Example #20
0
/**
 * @brief parse http head
 */
void http_event::parse_http_head() {
    /* parse content length */
    m_content_len = 0;
    char *pos_contlen = strcasestr((char*)m_head.c_str(), "content-length");
    if (NULL != pos_contlen) {
        char *pos_colon = strcasestr(pos_contlen, ":");
        if (NULL != pos_colon) {
            m_content_len = atoi(pos_colon + 1);
        }
    }
    RPC_DEBUG("extracted content_len, fd=%d, content_len=%d",
            m_fd, m_content_len);

    /* parse method and uri */
    std::string line, method, uri;
    std::size_t pos_line = m_head.find("\r\n");
    if (std::string::npos == pos_line) {
        line = m_head;
    } else {
        line = m_head.substr(0, pos_line);
    }
    const char *ch = line.c_str();
    for (; *ch != '\0' && *ch != ' '; ++ch) {
        m_method += *ch;
    }
    for (; *ch != '\0' && *ch == ' '; ++ch) {
    }
    for (; *ch != '\0' && *ch != ' '; ++ch) {
        m_uri += *ch;
    }
    for (; *ch != '\0' && *ch == ' '; ++ch) {
    }
    for (; *ch != '\0' && *ch != ' '; ++ch) {
        m_version += *ch;
    }
}
Example #21
0
/**
 * @brief dispatch task into thread
 *
 * @param evt
 */
void svr_base::on_dispatch_task(io_event *evt) {

    int i = rand() % m_thrds_pool.size();
    RPC_DEBUG("dispatch task to [%d]", i);
    m_thrds_pool[i]->add_task(evt);
}
Example #22
0
/******************************************************************************
 * RPC Socket Interface
 *****************************************************************************/
static void gps_cb_thread_func(void* unused) {
	while (pipe_gps[0] >= 0) {
		struct rpc_request_hdr_t hdr;
		memset(&hdr, 0, sizeof(hdr));
		if (read(pipe_gps[READ_END], &hdr, sizeof(hdr)) != sizeof(hdr)) {
			RPC_ERROR("failed to read request header");
			break;
		}
		
		char *buf = hdr.buffer;
		size_t idx = 0;

		RPC_DEBUG("%s: request code %d", __func__, hdr.code);

		switch (hdr.code) {
		case GPS_LOC_CB:
			if (gpsCallbacks && gpsCallbacks->location_cb) {
				GpsLocation location;
				memset(&location, 0, sizeof(location));
				RPC_UNPACK(buf, idx, location);
				gpsCallbacks->location_cb(&location);
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case GPS_STATUS_CB:
			if (gpsCallbacks && gpsCallbacks->status_cb) {
				GpsStatus status;
				memset(&status, 0, sizeof(status));
				RPC_UNPACK(buf, idx, status);
				gpsCallbacks->status_cb(&status);
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case GPS_SV_STATUS_CB:
			if (gpsCallbacks && gpsCallbacks->sv_status_cb) {
				GpsSvStatus status;
				memset(&status, 0, sizeof(status));
				RPC_UNPACK(buf, idx, status);
				gpsCallbacks->sv_status_cb(&status);
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case GPS_NMEA_CB:
			if (gpsCallbacks && gpsCallbacks->nmea_cb) {
				char nmea[RPC_PAYLOAD_MAX] = {};
				GpsUtcTime timestamp;
				int length;

				RPC_UNPACK(buf, idx, timestamp);
				RPC_UNPACK(buf, idx, length);
				RPC_UNPACK_RAW(buf, idx, nmea, length);
			
				gpsCallbacks->nmea_cb(timestamp,
					nmea, length);
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case GPS_SET_CAPABILITIES_CB:
			if (gpsCallbacks && gpsCallbacks->set_capabilities_cb) {
				uint32_t caps = 0;
				RPC_UNPACK(buf, idx, caps);
				RPC_DEBUG("SET_CAPABILITIEST %x", caps);
				gpsCallbacks->set_capabilities_cb(caps);
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case GPS_ACQUIRE_LOCK_CB:
			if (gpsCallbacks && gpsCallbacks->acquire_wakelock_cb) {
				gpsCallbacks->acquire_wakelock_cb();
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case GPS_RELEASE_LOCK_CB:
			if (gpsCallbacks && gpsCallbacks->release_wakelock_cb) {
				gpsCallbacks->release_wakelock_cb();
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;

		case GPS_REQUEST_UTC_TIME_CB:
			if (gpsCallbacks && gpsCallbacks->request_utc_time_cb) {
				gpsCallbacks->request_utc_time_cb();
			}
			else {
				RPC_ERROR("gpsCallbacks == NULL");
			}
			break;
		}
fail:
		continue;
	}
}
Example #23
0
int rpc_init(int fd, rpc_handler_t handler, rpc_t *rpc) {
	if (fd < 0) {
		RPC_DEBUG("bad fd %d", fd);
		goto fail;
	}

	if (!handler) {
		RPC_DEBUG("handler is NULL");
		goto fail;
	}
	
	if (!rpc) {
		RPC_DEBUG("rpc is NULL");
		goto fail;
	}

	if (pthread_mutex_init(&rpc->fd_mutex, NULL)) {
		RPC_PERROR("init fd mutex");
		goto fail;
	}

	if (pthread_mutex_init(&rpc->cond_mtx, NULL)) {
		RPC_PERROR("init condition mutex");
		goto fail_cond_mutex;
	}

	if (pthread_cond_init(&rpc->cond, NULL)) {
		RPC_PERROR("init condition");
		goto fail_cond;
	}

	if (pthread_mutex_init(&rpc->pipe_mtx, NULL)) {
		RPC_ERROR("init pipe mutex");
		goto fail_pipe_mutex;
	}

	if (pipe(rpc->pipefd) < 0) {
		RPC_PERROR("pipe");
		goto fail_pipe;
	}

	set_nonblocking(rpc->pipefd[WRITE_END]);
	set_nonblocking(rpc->pipefd[READ_END]);
	set_nonblocking(fd);
	
	rpc->fd = fd;
	rpc->handler = handler;

	return 0;

fail_pipe:
	pthread_mutex_destroy(&rpc->pipe_mtx);
fail_pipe_mutex:
	pthread_cond_destroy(&rpc->cond);
fail_cond:
	pthread_mutex_destroy(&rpc->cond_mtx);
fail_cond_mutex:
	pthread_mutex_destroy(&rpc->fd_mutex);
fail:
	return -1;
}
Example #24
0
int main(int argc, char *argv[]) {
    const char *ip = NULL;
    int port = 0;
    int threads_num = 4;

    /* command line options */
    while (true) {
        static struct option long_options[] = {
            { "help", no_argument, 0, 'h'},
            { "ip", required_argument, 0, 'i'},
            { "port", required_argument, 0, 'p'},
            { "threads", required_argument, 0, 't'},
            { 0, 0, 0, 0 }
        };
        int option_index = 0;
        int c = getopt_long(argc, argv, "ht:i:p:", long_options, &option_index);
        if (-1 == c) {
            break;
        }
        switch (c) {
            case 'h':
                usage(argc, argv);
                exit(0);
            case 't':
                threads_num = atoi(optarg);
                break;
            case 'i':
                ip = optarg;
                break;
            case 'p':
                port = atoi(optarg);
                break;
            default:
                usage(argc, argv);
                exit(0);
        }
    }
    if (0 == port || ip == NULL) {
        usage(argc, argv);
        exit(0);
    }

    /* start service */
    RPC_DEBUG("threads num=%d", threads_num);
    RPC_INFO("register ip=%s", ip);
    RPC_INFO("register port=%d", port);

    signal(SIGINT, signal_proc);
    signal(SIGTERM, signal_proc);

    /* initialize server */
    $name$_svr *svr = new $name$_svr;

    if (0 != svr->run(threads_num)) {
        RPC_WARNING("create threads error");
        exit(-1);
    }
    if (0 != svr->bind(port)) {
        RPC_WARNING("bind error");
        exit(-1);
    }

    /* register information */
    if (0 != register_information(DS_IP, DS_PORT,
                RPC_ID, RPC_NAME, RPC_VERSION, ip, port)) {
        RPC_WARNING("register error");
    }

    unsigned long long prev_msec = get_cur_msec();
    while (running) {
        svr->run_routine(10);

        unsigned long long curr_msec = get_cur_msec();
        if (curr_msec - prev_msec >= 10 * 1000) {
            /* update register information every 10 secs */
            if (0 != register_information(DS_IP, DS_PORT,
                        RPC_ID, RPC_NAME, RPC_VERSION, ip, port)) {
                RPC_WARNING("update register information error");
            }
            prev_msec = curr_msec;
        }
    }

    svr->stop();
    svr->join();

    /* delete */
    if (0 != unregister_information(DS_IP, DS_PORT,
                RPC_ID, RPC_NAME, RPC_VERSION, ip, port)) {
        RPC_WARNING("unregister error");
    }
    delete svr;

    RPC_WARNING("server exit");
    return 0;
}