static int vbus_notification_cb(struct msm_rpc_client *client,
				void *buffer, int in_size)
{
	struct vbus_sn_notification_args *args;
	struct rpc_request_hdr *req = buffer;
	int rc;
	uint32_t accept_status;
	void (*cb_func)(int);
	uint32_t cb_id;
	int vbus;

	args = (struct vbus_sn_notification_args *) (req + 1);
	cb_id = be32_to_cpu(args->cb_id);
	vbus = be32_to_cpu(args->vbus);

	cb_func = msm_rpc_get_cb_func(client, cb_id);
	if (cb_func) {
		cb_func(!vbus);
		accept_status = RPC_ACCEPTSTAT_SUCCESS;
	} else
		accept_status = RPC_ACCEPTSTAT_SYSTEM_ERR;

	msm_rpc_start_accepted_reply(client, be32_to_cpu(req->xid),
				     accept_status);
	rc = msm_rpc_send_accepted_reply(client, 0);
	if (rc)
		pr_err("%s: send accepted reply failed: %d\n", __func__, rc);

	return rc;
}
Beispiel #2
0
/**
 *  i40e_clean_asq - cleans Admin send queue
 *  @hw: pointer to the hardware structure
 *
 *  returns the number of free desc
 **/
u16 i40e_clean_asq(struct i40e_hw *hw)
{
	struct i40e_adminq_ring *asq = &(hw->aq.asq);
	struct i40e_asq_cmd_details *details;
	u16 ntc = asq->next_to_clean;
	struct i40e_aq_desc desc_cb;
	struct i40e_aq_desc *desc;

	desc = I40E_ADMINQ_DESC(*asq, ntc);
	details = I40E_ADMINQ_DETAILS(*asq, ntc);
	while (rd32(hw, hw->aq.asq.head) != ntc) {
		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
			   "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));

		if (details->callback) {
			I40E_ADMINQ_CALLBACK cb_func =
					(I40E_ADMINQ_CALLBACK)details->callback;
			i40e_memcpy(&desc_cb, desc, sizeof(struct i40e_aq_desc),
				    I40E_DMA_TO_DMA);
			cb_func(hw, &desc_cb);
		}
		i40e_memset(desc, 0, sizeof(*desc), I40E_DMA_MEM);
		i40e_memset(details, 0, sizeof(*details), I40E_NONDMA_MEM);
		ntc++;
		if (ntc == asq->count)
			ntc = 0;
		desc = I40E_ADMINQ_DESC(*asq, ntc);
		details = I40E_ADMINQ_DETAILS(*asq, ntc);
	}

	asq->next_to_clean = ntc;

	return I40E_DESC_UNUSED(asq);
}
Beispiel #3
0
/**
 *  i40e_clean_asq - cleans Admin send queue
 *  @hw: pointer to the hardware structure
 *
 *  returns the number of free desc
 **/
static u16 i40e_clean_asq(struct iavf_hw *hw)
{
	struct iavf_adminq_ring *asq = &hw->aq.asq;
	struct i40e_asq_cmd_details *details;
	u16 ntc = asq->next_to_clean;
	struct i40e_aq_desc desc_cb;
	struct i40e_aq_desc *desc;

	desc = IAVF_ADMINQ_DESC(*asq, ntc);
	details = I40E_ADMINQ_DETAILS(*asq, ntc);
	while (rd32(hw, hw->aq.asq.head) != ntc) {
		iavf_debug(hw, IAVF_DEBUG_AQ_MESSAGE,
			   "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head));

		if (details->callback) {
			I40E_ADMINQ_CALLBACK cb_func =
					(I40E_ADMINQ_CALLBACK)details->callback;
			desc_cb = *desc;
			cb_func(hw, &desc_cb);
		}
		memset((void *)desc, 0, sizeof(struct i40e_aq_desc));
		memset((void *)details, 0,
		       sizeof(struct i40e_asq_cmd_details));
		ntc++;
		if (ntc == asq->count)
			ntc = 0;
		desc = IAVF_ADMINQ_DESC(*asq, ntc);
		details = I40E_ADMINQ_DETAILS(*asq, ntc);
	}

	asq->next_to_clean = ntc;

	return IAVF_DESC_UNUSED(asq);
}
Beispiel #4
0
int
udp_listen(const char *host, int port, udp_callback_fn_t *cb_func,
    void *cb_data)
{
  char buf[8192];
  int lastsiz = 0;
  int sock;
  struct sockaddr_in cli;
  socklen_t addrsiz = (socklen_t)sizeof(cli);

  sock = udp_bind(host, port);
  if (sock < 0)
    return -1;
  memset(&cli, 0, sizeof(cli));
  memset(buf, 0, sizeof(buf));

  for (;;)
    {
      lastsiz = recvfrom(sock, buf, sizeof(buf), 0, (struct sockaddr *) &cli,
          &addrsiz);
      if (lastsiz > 0)
        {
          if (cb_func)
            cb_func(buf, lastsiz, cb_data);
        }
    }
  return 0;
}
Beispiel #5
0
/**
 *  i40e_clean_asq - cleans Admin send queue
 *  @hw: pointer to the hardware structure
 *
 *  returns the number of free desc
 **/
u16 i40e_clean_asq(struct i40e_hw *hw)
{
#ifdef I40E_QV
	struct i40e_aq_desc qv_desc = {0};
	struct i40e_aq_desc *qv_desc_on_ring;
#endif /* I40E_QV */
	struct i40e_adminq_ring *asq = &(hw->aq.asq);
	struct i40e_asq_cmd_details *details;
	u16 ntc = asq->next_to_clean;
	struct i40e_aq_desc desc_cb;
	struct i40e_aq_desc *desc;

	desc = I40E_ADMINQ_DESC(*asq, ntc);
	details = I40E_ADMINQ_DETAILS(*asq, ntc);
#ifdef I40E_QV
	/* copy the descriptor from ring to userspace buffer */
	i40e_memcpy(&qv_desc, desc, sizeof(struct i40e_aq_desc),
		     I40E_DMA_TO_NONDMA);
	qv_desc_on_ring = desc;
	desc = &qv_desc;
#endif /* I40E_QV */
	while (rd32(hw, hw->aq.asq.head) != ntc) {
		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
			   "%s: ntc %d head %d.\n", __FUNCTION__, ntc,
			   rd32(hw, hw->aq.asq.head));

		if (details->callback) {
			I40E_ADMINQ_CALLBACK cb_func =
					(I40E_ADMINQ_CALLBACK)details->callback;
			i40e_memcpy(&desc_cb, desc,
			            sizeof(struct i40e_aq_desc), I40E_DMA_TO_DMA);
			cb_func(hw, &desc_cb);
		}
		i40e_memset(desc, 0, sizeof(*desc), I40E_DMA_MEM);
		i40e_memset(details, 0, sizeof(*details), I40E_NONDMA_MEM);
#ifdef I40E_QV
		/* copy the descriptor from userspace buffer to ring */
		i40e_memcpy(qv_desc_on_ring, desc,
			    sizeof(struct i40e_aq_desc), I40E_NONDMA_TO_DMA);
#endif /* I40E_QV */
		ntc++;
		if (ntc == asq->count)
			ntc = 0;
		desc = I40E_ADMINQ_DESC(*asq, ntc);
		details = I40E_ADMINQ_DETAILS(*asq, ntc);
#ifdef I40E_QV
		/* copy the descriptor from ring to userspace buffer */
		i40e_memcpy(&qv_desc, desc, sizeof(struct i40e_aq_desc),
			     I40E_DMA_TO_NONDMA);
		qv_desc_on_ring = desc;
		desc = &qv_desc;
#endif /* I40E_QV */
	}

	asq->next_to_clean = ntc;

	return I40E_DESC_UNUSED(asq);
}
Beispiel #6
0
svn_error_t *
svn_sqlite__with_lock(svn_sqlite__db_t *db,
                      svn_sqlite__transaction_callback_t cb_func,
                      void *cb_baton,
                      apr_pool_t *scratch_pool /* NULL allowed */)
{
  SVN_SQLITE__WITH_LOCK(cb_func(cb_baton, db, scratch_pool), db);
  return SVN_NO_ERROR;
}
void AdStreamSubscriber::consume(const std::string& topic)
{
    // each topic using the separated consume thread.
    std::string cur_topic = topic;
    LOG(INFO) << "consume thread started for topic: " << cur_topic;

    boost::shared_ptr<izenelib::util::concurrent_queue<AdMessage> > tasks;
    MessageCBFuncT cb_func;
    {
        boost::unique_lock<boost::mutex> lock(mutex_);
        if (subscriber_list_.find(cur_topic) == subscriber_list_.end())
        {
            LOG(INFO) << "no subscriber for cur topic. exit";
            return;
        }
        tasks = consume_task_list_[cur_topic];
        cb_func = subscriber_list_[cur_topic];
    }

    while(true)
    {
        try
        {
            std::vector<AdMessage> msg_list;
            AdMessage msg;
            while(!tasks->empty())
            {
                tasks->pop(msg);
                msg_list.push_back(msg);
            }
            if (msg_list.empty())
            {
                tasks->pop(msg);
                msg_list.push_back(msg);
            }
            boost::this_thread::interruption_point();

            cb_func(msg_list);
        }
        catch(const boost::thread_interrupted& e)
        {
            break;
        }
        catch(const std::exception& e)
        {
            LOG(WARNING) << "consuming exception : " << e.what();
        }
    }
    LOG(INFO) << "consume thread exited for topic: " << cur_topic;
}
Beispiel #8
0
/* The body of svn_sqlite__with_transaction() and
   svn_sqlite__with_immediate_transaction(), which see. */
static svn_error_t *
with_transaction(svn_sqlite__db_t *db,
                 svn_sqlite__transaction_callback_t cb_func,
                 void *cb_baton,
                 apr_pool_t *scratch_pool /* NULL allowed */)
{
  svn_error_t *err;

  err = cb_func(cb_baton, db, scratch_pool);

  /* Commit or rollback the sqlite transaction. */
  if (err)
    {
      svn_error_t *err2 = exec_sql(db, "ROLLBACK TRANSACTION;");

      if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
        {
          /* ### Houston, we have a problem!

             We are trying to rollback but we can't because some
             statements are still busy. This leaves the database
             unusable for future transactions as the current transaction
             is still open.

             As we are returning the actual error as the most relevant
             error in the chain, our caller might assume that it can
             retry/compensate on this error (e.g. SVN_WC_LOCKED), while
             in fact the SQLite database is unusable until the statements
             started within this transaction are reset and the transaction
             aborted.

             We try to compensate by resetting all prepared but unreset
             statements; but we leave the busy error in the chain anyway to
             help diagnosing the original error and help in finding where
             a reset statement is missing. */

          err2 = reset_all_statements(db, err2);
          err2 = svn_error_compose_create(
                      exec_sql(db, "ROLLBACK TRANSACTION;"),
                      err2);
        }

      return svn_error_compose_create(err,
                                      err2);
    }

  return svn_error_trace(exec_sql(db, "COMMIT TRANSACTION;"));
}
Beispiel #9
0
svn_error_t *
svn_sqlite__with_lock(svn_sqlite__db_t *db,
                      svn_sqlite__transaction_callback_t cb_func,
                      void *cb_baton,
                      apr_pool_t *scratch_pool)
{
  svn_error_t *err;
  int savepoint = db->savepoint_nr++;
  /* This buffer is plenty big to hold the SAVEPOINT and RELEASE commands. */
  char buf[32];

  snprintf(buf, sizeof(buf), "SAVEPOINT s%u", savepoint);
  SVN_ERR(exec_sql(db, buf));
  err = cb_func(cb_baton, db, scratch_pool);

  if (err)
    {
      svn_error_t *err2;

      snprintf(buf, sizeof(buf), "ROLLBACK TO s%u", savepoint);
      err2 = exec_sql(db, buf);

      if (err2 && err2->apr_err == SVN_ERR_SQLITE_BUSY)
        {
          /* Ok, we have a major problem. Some statement is still open, which
             makes it impossible to release this savepoint.

             ### See huge comment in svn_sqlite__with_transaction for
                 further details */

          err2 = reset_all_statements(db, err2);
          err2 = svn_error_compose_create(exec_sql(db, buf), err2);
        }

      snprintf(buf, sizeof(buf), "RELEASE   s%u", savepoint);
      err2 = svn_error_compose_create(exec_sql(db, buf), err2);

      return svn_error_trace(svn_error_compose_create(err, err2));
    }

  snprintf(buf, sizeof(buf), "RELEASE   s%u", savepoint);
  return svn_error_trace(exec_sql(db, buf));
}
Beispiel #10
0
svn_error_t *
svn_sqlite__with_transaction(svn_sqlite__db_t *db,
                             svn_sqlite__transaction_callback_t cb_func,
                             void *cb_baton)
{
  svn_error_t *err;

  SVN_ERR(svn_sqlite__transaction_begin(db));
  err = cb_func(cb_baton, db);

  /* Commit or rollback the sqlite transaction. */
  if (err)
    {
      svn_error_clear(svn_sqlite__transaction_rollback(db));
      return err;
    }
  else
    return svn_sqlite__transaction_commit(db);
}
Beispiel #11
0
void cb_recv(void *conn_private, void *msg_private, mrpc_status_t status,
			KBuffer *out)
{
	cb_func(msg_private, status);
}
Beispiel #12
0
void cb_ping(void *conn_private, void *msg_private, mrpc_status_t status)
{
	cb_func(msg_private, status);
}
Beispiel #13
0
gint
gv_view_area_render_postscript(GvViewArea *view, int width, int height, 
                               float ulx, float uly, float lrx, float lry,
                               int is_rgb,
                               gint (*cb_func)(void *, const char *), 
                               void * cb_data )

{
    gvPostScriptOptions   options;
    int errcode;
    char line[128];

    /* write prolog */

    cb_func( cb_data, "%!PS-Adobe-3.0 EPSF-3.0\n" );
    cb_func( cb_data, "%%Creator: gview\n" );
    cb_func( cb_data, "%%Title: gview_print\n" );
    cb_func( cb_data, "%%CreationDate: Thu Apr  6 20:11:10 2000\n" );
    cb_func( cb_data, "%%DocumentData: Clean7Bit\n" );
    cb_func( cb_data, "%%Origin: 0 0\n" );
#ifdef notdef
    sprintf( line, "%%%%BoundingBox: 0 0 %d %d\n", width, height );
    cb_func( cb_data, line );
#endif
    cb_func( cb_data, "%%LanguageLevel: 1\n" );
    cb_func( cb_data, "%%Pages: 1\n" );
    cb_func( cb_data, "%%EndComments\n" );
    cb_func( cb_data, "%%BeginSetup\n" );
    cb_func( cb_data, "%%EndSetup\n" );
    cb_func( cb_data, "%%Page: 1 1\n" );
    cb_func( cb_data, "gsave\n" );
    cb_func( cb_data, "100 dict begin\n" );

    sprintf( line, "%f %f translate\n", ulx*72.0, uly*72.0 );
    cb_func( cb_data, line );

    sprintf( line, "%f %f scale\n", (lrx - ulx)*72.0, (lry - uly)*72.0 );
    cb_func( cb_data, line );

    if( is_rgb )
    {
        sprintf( line, 
                 "%%ImageData: %d %d 8 3 0 %d 2 \"true 3 colorimage\"\n", 
                 width, height, width );
        cb_func( cb_data, line );

        sprintf( line, "/line0 %d string def\n", width );
        cb_func( cb_data, line );
        
        sprintf( line, "/line1 %d string def\n", width );
        cb_func( cb_data, line );
        
        sprintf( line, "/line2 %d string def\n", width );
        cb_func( cb_data, line );
    }
    else
    {
        sprintf( line, 
                 "%%ImageData: %d %d 8 1 0 %d 2 \"image\"\n", 
                 width, height, width );
        cb_func( cb_data, line );

        sprintf( line, "/scanLine %d string def\n", width );
        cb_func( cb_data, line );
    }


    sprintf( line, "%d %d 8\n", width, height );
    cb_func( cb_data, line );

    sprintf( line, "[%d 0 0 %d 0 %d]\n", width, -height, height );
    cb_func( cb_data, line );

    if( is_rgb )
    {
        cb_func( cb_data, "{currentfile line0 readhexstring pop}bind\n" );
        cb_func( cb_data, "{currentfile line1 readhexstring pop}bind\n" );
        cb_func( cb_data, "{currentfile line2 readhexstring pop}bind\n" );
        cb_func( cb_data, "true 3 colorimage\n" );
    }
    else
    {
        cb_func( cb_data, "{currentfile scanLine readhexstring pop}bind\n" );
        cb_func( cb_data, "image\n" );
    }

    /* now prepare and write image data */
    options.cb_func = cb_func;
    options.cb_data = cb_data;
    options.width = width;
    options.is_rgb = is_rgb;
    options.text_buf = g_malloc(width * 6 + 3);
    if( options.text_buf == NULL )
        return -1;

    errcode = gv_view_area_render_to_func( view, width, height, 
                                           postscript_handler, &options );
    
    g_free( options.text_buf );

    /* write postlog */

    if( errcode == 0 )
    {
        cb_func( cb_data, "end\n" );
        cb_func( cb_data, "grestore\n" );
        cb_func( cb_data, "showpage\n" );
        cb_func( cb_data, "%%Trailer\n" );
        cb_func( cb_data, "%%Pages: 1\n" );
        cb_func( cb_data, "%%EOF\n" );
    }

    return errcode;
}
int main(int argc, char *argv[]){
	if(argc <= 2){
		printf("usage: %s ip_address port_number\n", basename(argv[0]));
		return 1;
	}
	const char* ip = argv[1];
	int port = atoi(argv[2]);
	
	struct sockaddr_in address;
	bzero(&address, sizeof(address));
	address.sin_family = AF_INET;
	inet_pton(AF_INET, ip, &address.sin_addr);
	address.sin_port = htons(port);
	
	int listenfd = socket(PF_INET, SOCK_STREAM, 0);
	assert(listenfd >= 0);
	
	int ret = bind(listenfd, (struct sockaddr*)&address, sizeof(address));
	assert(ret != -1);
	
	ret = listen(listenfd, 5);
	assert(ret != -1);
	
	epoll_event events[MAX_EVENT_NUMBER];
	int epollfd = epoll_create(5);
	assert(epollfd != 0);
	addfd(epollfd, listenfd);
	
	ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd);
	assert(ret != -1);
	setnonblocking(pipefd[1]);
	addfd(epollfd, pipefd[0]);
	
	/*设置信号处理函数*/
	addsig(SIGALARM);
	addsig(SIGTERM);
	bool stop_server = false;
	
	client_data* users = new client_data[FD_LIMIT];
	bool timeout = false;
	alarm(TIMESLOT); /*定时*/
	
	while(!stop_server){
		int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
		if(number < 0 && errno != EINTR){
			printf("epoll failed\n");
			break;
		}
		for(int i = 0; i < number; i++){
			int sockfd = events[i].data.fd;
			if(sockfd == listenfd){
				struct sockaddr_in client_address;
				socklen_t client_addrlength = sizeof(client_address);
				int connfd = accept(sockfd, (struct sockaddr*)&client_address, &client_addrlength);
				addfd(epollfd, connfd);
				
				users[connfd].address = client_address;
				users[connfd].sockfd = connfd;
				util_timer* timer = new util_timer;
				timer->client_data = users[connfd];
				timer->cb_func = cb_func;
				time_t cur = time(NULL);
				timer->expire = cur + 3*TIMESLOT;
				users[connfd].timer = timer;
				timer_lst.add_timer(timer);
			} else if((sockfd == pipefd[0]) && (events[i].events & EPOLLIN)){
				char signals[1024];
				memset(signals, '\0', sizeof(signals));
				ret = recv(pipefd[0], signals, sizeof(signals), 0);
				if(ret < 0){
					//handle the error
					continue;
				} else if(ret == 0){
					continue;
				} else {
					for(int i = 0; i < ret; i++){
					switch (signals[i])
						case SIGALARM:
							/*关闭长时间不响应的连接*/
							timeout = true;//不立即处理定时任务
							break;
						case SIGTERM:
							stop_server = true;
					}
				}
			} else if(events[i].events & EPOLLIN){
				memset(users[sockfd].buf, '\0', BUFFER_SIZE);
				ret = recv(sockfd, users[sockfd].buf, BUFFER_SIZE - 1, 0);
				
				util_timer* timer = users[sockfd].timer;
				if(ret < 0){
					if(errno != EAGAIN){
						/*发生错误,则关闭连接,并移除定时器*/
						cb_func(&users[sockfd]);
						if(timer){
							timer_lst.del_timer(timer);
						}
					}
				} else if(ret == 0){
					/*对方已关闭连接,则关闭连接,并移除定时器*/
					cb_func(&users[sockfd]);
					if(timer){
						timer_lst.del_timer(timer);
					}
				} else {
					printf("get %d bytes of client data %s from %d\n", ret, users[sockfd].buf, sockfd);
					/*有数据,则需要调整定时器,以延迟该连接被关闭的时间*/
					if(timer){
						time_t cur = time(NULL);
						timer->expire = cur + 3*TIMESLOT;
						printf("adjust timer once\n");
						timer_lst.adjust_timer(timer);
					}
				}
			} else {
				//others
			}
		}
		/*最后处理定时事件*/
		if(timeout){
			timer_handler();
			timeout = false;
		}
	}
	close(listenfd);
	close(pipefd[0]);
	close(pipefd[1]);
	delete[] users;
	return 0;
}
Beispiel #15
0
int main(int argc, char *argv[])
{
	bool stop_server = false;

	client_data *users;
	bool timeout = false;
	int epollfd;
	epoll_event events[MAX_EVENT_NUMBER];
	int listenfd;
	int ret = 0;
	struct sockaddr_in address;
	const char *ip;
	int port;

	if (argc < 2) {
		printf("usage: ./main ip_address port_number");
		return 1;
	}

	ip = argv[1];
	port = atoi(argv[2]);

	bzero(&address, sizeof(address));
	address.sin_family = AF_INET;
	inet_pton(AF_INET, ip, &address.sin_addr);
	address.sin_port = htons(port);

	listenfd = socket(PF_INET, SOCK_STREAM, 0);
	assert(listenfd >= 0);

	ret = bind(listenfd, (struct sockaddr *)&address, sizeof(address));
	assert(ret != -1);

	ret = listen(listenfd, 5);
	assert(ret != -1);

	epollfd = epoll_create(5);
	assert(epollfd != -1);
	addfd(epollfd, listenfd);

	ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd);
	assert(ret != -1);
	setnonblocking(pipefd[1]);
	addfd(epollfd, pipefd[0]);

	addsig(SIGALRM);
	addsig(SIGTERM);

	users = new client_data[FD_LIMIT];
	alarm(TIMESLOT);

	while (!stop_server) {
		int number = epoll_wait(epollfd, events, MAX_EVENT_NUMBER, -1);
		if ((number < 0) && (errno != EINTR)) {
			printf("epoll failure\n");
			break;
		}

		for (int i=0; i<number; ++i) {
			int sockfd = events[i].data.fd;
			if (sockfd == listenfd) {
				struct sockaddr_in client_address;
				socklen_t client_addlength = sizeof(client_address);
				int connfd = accept(listenfd, (struct sockaddr *)&client_address, &client_addlength);
				addfd(epollfd, connfd);
				users[connfd].address = client_address;
				users[connfd].sockfd = connfd;
				
				util_timer *timer = new util_timer;
				timer->user_data = &users[connfd];
				timer->cb_func = cb_func;
				time_t cur = time(NULL);
				timer->expire = cur + TIME_INACTIVE;
				users[connfd].timer = timer;
				timer_lst.add_timer(timer);
			} else if ((sockfd == pipefd[0]) && (events[i]).events & EPOLLIN) {
				char signals[1024];
				ret = recv(pipefd[0], signals, sizeof(signals), 0);
				if (ret == -1)
					continue;
				else if (ret == 0)
					continue;
				else {
					for (int i=0; i<ret; ++i) {
						switch (signals[i]) {
						case SIGALRM:
							timeout = true;
							break;
						case SIGTERM:
							stop_server = true;	
						}
					}
				}
			} else if (events[i].events & EPOLLIN) {
				util_timer *timer = users[sockfd].timer;
				memset(users[sockfd].buf, '\0', BUFFER_SIZE);
				ret = recv(sockfd, users[sockfd].buf, BUFFER_SIZE, 0);

				if (ret < 0) {
					if (errno != EAGAIN) {
						cb_func(&users[sockfd]);
						if (timer)
							timer_lst.del_timer(timer);
					}
				} else {
					users[sockfd].buf[ret-1] = '\0';
					printf("get %d bytes of client data %s from %d\n",
							ret, users[sockfd].buf, sockfd);
					if (timer) {
						time_t cur = time(NULL);
						timer->expire = cur + TIME_INACTIVE;
						timer_lst.adjust_timer(timer);
					}
				}
			}
		}

		if (timeout) {
			timer_handler();
			timeout = false;
		}
	}

	close(listenfd);
	close(pipefd[0]);
	close(pipefd[1]);
	delete []users;
	return 0;
}
Beispiel #16
0
int main()
{
	int port = atoi("2500");

	int ret = 0;
	struct sockaddr_in address;
	//bzero(&address, sizeof(address));
	memset(&address, 0, sizeof(address));
	address.sin_family = AF_INET;
	address.sin_port = htons(port);
	address.sin_addr.s_addr = htonl(INADDR_ANY);

	int listenfd = socket(AF_INET, SOCK_STREAM, 0);
	assert(listenfd>=0);

	ret = bind( listenfd, (struct sockaddr*)&address, sizeof(address));
	assert( ret != -1 );

	ret = listen( listenfd, 5 );
	assert( ret != -1 );

	epoll_events events[MAX_EVENT_NUMER];
	int epollfd = epoll_create(5);
	assert(epollfd != -1);
	addfd( epollfd, listenfd);

	/**/
	ret = socketpair(AF_UNIX, SOCK_STREAM, 0, pipefd);
	assert( ret != -1 );
	setnonblocking( pipefd[1]);
	addfd( epollfd, pipefd[0]);

	addsig( SIGALRM );
	addsig( SIGTERM );
	bool stop_server = false;

	client_data* users = new client_data[FD_LIMIT];
	bool timeout = false;
	alarm(TIMESLOT);
	
	while( !stop_server )
	{
		int number = epoll_wait( epollfd, events, MAX_EVENT_NUMER, -1 );
		if( (number<0) && (errno != EINTR)) 
		{
			printf("epoll failure\n");
			break;
		}

		for( int i=0; i<number; i++)
		{
			int sockfd = events[i].data.fd;
			if( sockfd == listenfd )
			{
				struct sockaddr_in client_address;
				socklen_t client_addrlen = sizeof( client_addrlen);
				int connfd = accept( listenfd, (struct sockaddr*)
						&client_address, &client_addrlen);
				addfd( epollfd, connfd );

				users[connfd].address = client_address;
				users[connfd].sockfd = connfd;

				util_timer* timer = new util_timer;
				timer->user_data = &users[connfd];
				timer->cb_func = cb_func;
				time_t cur = time(NULL);
				timer->expire = cur + 3*TIMESLOT;
				users[connfd].timer = timer;
				timer_list.add_timer(timer);
			}
			else if( (sockfd == pipefd[0]) && (events[i].events & EPOLLIN))
			{
				int sig;
				char signals[1024];
				ret = recv( pipefd[0], signals, sizeof(signals), 0);
				if( ret == -1 || ret == 0 )
				{
					continue;
				}
				else
				{
					for(int i=0; i<ret; i++)
					{
						switch( signals[i])
						{
							case SIGALRM:
								{
									timeout = true;
									break;
								}
							case SIGHUP:
								{
									continue;
								}
							case SIGTERM:
								{
									stop_server = true;
								}
							case SIGINT:
								{
									printf("recv SIGINT\n");
									stop_server = true;
								}
						}
					}
				}
			}
			else if( events[i].events & EPOLLIN )
			{
				memset( users[sockfd].buf, '\0', BUFFER_SIZE );
				ret = recv( sockfd, users[sockfd].buf, BUFFER_SIZE-1, 0);
				printf("get %d bytes of client data %s from %d\n", ret, 
						users[sockfd].buf, sockfd);

				util_timer* timer = users[sockfd].timer;
				if( ret<0 )
				{
					if( errno != EAGAIN )
					{
						cb_func( &users[sockfd]);
						if( timer )
						{
							timer_list.del_timer( timer );
						}
					}
				}
				else if( ret == 0 )
				{
					cb_func( &users[sockfd]);
					if(timer)
					{
						timer_list.del_timer( timer );
					}
				}
				else
				{
					if( timer )
					{
						time_t cur = time(NULL);
						timer->expire = cur + 3*TIMESLOT;
						printf("adjust timer once\n");
						timer_list.adjust_timer( timer );
					}
				}

				if( timeout )
				{
					timer_handler();
					timeout = false;
				}

			}
		}

	}

	close(listenfd);
	close(epollfd);
	close(pipefd[0]);
	close(pipefd[1]);
	delete [] users;
	return 0;
}