Beispiel #1
0
/*  
    Process sock read. Two type of sock could be read, TCP or UDP
    TCP sock is local port. In this function, it only read the sock, and store 
    data into the buffer belonged to the socket.
    UDP is routing port. It process one LSA each time. Prepare the response
    and update routing info accordingly.
 */
void process_read(fd_set *rdset, fd_set *tmp_rdset, fd_set *wrset,
                  int lc_sock, int rd_sock)
{
    int sock;
    int new_sock;

    rd_sock = rd_sock;

    while(-1 != (sock = get_next_fd(tmp_rdset)))
    {
        dbg_print(0, "to read sock %d\n", sock);
        client_info_t *clnt_inf = get_clnt_info(sock);

        // local request
        if(clnt_inf->sock_type == SOCKET_TYPE_TCP)
        {
            if(sock == lc_sock)   // listen sock
            {
                new_sock = accept_new(lc_sock);
                if(-1 != new_sock)
                {
                    dbg_print(2, "new sock %d\n", new_sock);
                    FD_SET(new_sock, rdset);
                }
                continue;
            }
            else
            {
                int rev;
                
                rev = recv_clnt_data(sock);
                if(rev > 0)
                {
                    FD_SET(sock, wrset);
                }
                else if(0 == rev) //peer close socket
                {
                    close(sock);
                    FD_CLR(sock, wrset);
                    FD_CLR(sock, rdset);
                    remove_clnt_info(sock);
                    dbg_print(2, "peer close socket %d\n", sock);
                }
                else if(-1 ==rev && EWOULDBLOCK != errno)
                {
                    fprintf(stderr, "??? what happens when read?\n");
                    perror("?");
                    assert(0);
                }
            }
        }//end tcp
        else // routing port, process routing LSA
        {
            if(clnt_process_rt_inf(sock) > 0)
            {
                FD_SET(sock, wrset);
            }
        }
    }
}
Beispiel #2
0
void
cos_init(void *arg)
{
	int c, accept_fd, ret;
	long eid;
	char *init_str = cos_init_args(), *create_str;
	int lag, nthds, prio;
	
	cvect_init_static(&evts);
	cvect_init_static(&tor_from);
	cvect_init_static(&tor_to);
	lock_static_init(&sc_lock);
		
	sscanf(init_str, "%d:%d:%d", &lag, &nthds, &prio);
	printc("lag: %d, nthds:%d, prio:%d\n", lag, nthds, prio);
	create_str = strstr(init_str, "/");
	assert(create_str);

	eid = evt_get();
	ret = c = from_tsplit(cos_spd_id(), td_root, create_str, strlen(create_str), TOR_ALL, eid);
	if (ret <= td_root) BUG();
	accept_fd = c;
	evt_add(c, eid);

	/* event loop... */
	while (1) {
		struct tor_conn tc;
		int t;
		long evt;

		memset(&tc, 0, sizeof(struct tor_conn));
		evt = evt_wait_all();
		t   = evt_torrent(evt);

		if (t > 0) {
			tc.feid = evt;
			tc.from = t;
			if (t == accept_fd) {
				tc.to = 0;
				accept_new(accept_fd);
			} else {
				tc.to = tor_get_to(t, &tc.teid);
				assert(tc.to > 0);
				from_data_new(&tc);
			}
		} else {
			t *= -1;
			tc.teid = evt;
			tc.to   = t;
			tc.from = tor_get_from(t, &tc.feid);
			assert(tc.from > 0);
			to_data_new(&tc);
		}

		cos_mpd_update();
	}
}
Beispiel #3
0
void cos_init(void *arg)
{
	int c, accept_fd, ret;
	long eid;

	cvect_init_static(&evts);
	cvect_init_static(&tor_from);
	cvect_init_static(&tor_to);
	
	eid = evt_get();
	c = net_create_tcp_connection(cos_spd_id(), cos_get_thd_id(), eid);
	if (c < 0) BUG();
	ret = net_bind(cos_spd_id(), c, 0, 200);
	if (ret < 0) BUG();
	ret = net_listen(cos_spd_id(), c, 255);
	if (ret < 0) BUG();
	accept_fd = c;
	evt_add(c, eid);

	while (1) {
		struct tor_conn tc;
		int t;
		long evt;

		memset(&tc, 0, sizeof(struct tor_conn));
		printc("waiting...\n");
		evt = evt_grp_wait(cos_spd_id());
		t   = evt_torrent(evt);

		if (t > 0) {
			tc.feid = evt;
			tc.from = t;
			if (t == accept_fd) {
				tc.to = 0;
				printc("accepting event.\n");
				accept_new(accept_fd);
			} else {
				tc.to = tor_get_to(t);
				assert(tc.to > 0);
				printc("data from net.\n");
				from_data_new(&tc);
			}
		} else {
			t *= -1;
			tc.teid = evt;
			tc.to   = t;
			tc.from = tor_get_from(t);
			assert(tc.from > 0);
			printc("data from torrent.\n");
			to_data_new(&tc);
		}

		cos_mpd_update();
	}
}
Beispiel #4
0
void
cos_init(void *arg)
{
	int c, accept_fd, ret;
	long eid;
	char *init_str = cos_init_args();
	char __create_str[128];
	static volatile int first = 1, off = 0;
	int port;
	u64_t start, end;

	if (cos_get_thd_id() == pid_thd) {
		pid_process();
	}
	
	union sched_param sp;

	if (first) {
		first = 0;

		sp.c.type = SCHEDP_PRIO;
		sp.c.value = 10;
		pid_thd = sched_create_thd(cos_spd_id(), sp.v, 0, 0);

		init(init_str);
		return;
	}


	printc("Thread %d, port %d\n", cos_get_thd_id(), __port+off);	
	port = off++;
	port += __port;
	eid = evt_get();
	if (snprintf(__create_str, 128, create_str, port) < 0) BUG();
	ret = c = from_tsplit(cos_spd_id(), td_root, __create_str, strlen(__create_str), TOR_ALL, eid);
	if (ret <= td_root) BUG();
	accept_fd = c;
	printc("accept_fd %d (eid %d)\n", accept_fd, eid);
	evt_add(c, eid);

	/* event loop... */
	while (1) {
		int t;
		long evt;
		
		evt = evt_wait_all();
		t   = evt_torrent(evt);
		printc("an interrupt comes in (thd %d, evt %d t %d)\n",
		       cos_get_thd_id(), evt, t);
		accept_new(accept_fd);
		break;
	}
}
Beispiel #5
0
void poll_loop(void)
{
    ITF *itf,*next_itf;
    ENTRY *entry,*next_entry;
    VCC *vcc,*next_vcc;
    int fds,ret;

    gettimeofday(&now,NULL);
    while (1) {
	FD_ZERO(&rset);
	FD_ZERO(&cset);
	FD_SET(kernel,&rset);
	FD_SET(unix_sock,&rset);
	if (incoming >= 0) FD_SET(incoming,&rset);
	fds = incoming+1;
	if (kernel >= fds) fds = kernel+1;
	if (unix_sock >= fds) fds = unix_sock+1;
	for (itf = itfs; itf; itf = itf->next)
	    for (entry = itf->table; entry; entry = entry->next)
		for (vcc = entry->vccs; vcc; vcc = vcc->next) {
		    if (vcc->connecting) FD_SET(vcc->fd,&cset);
		    else FD_SET(vcc->fd,&rset);
		    if (vcc->fd >= fds) fds = vcc->fd+1;
		}
	for (entry = unknown_incoming; entry; entry = entry->next) {
	    if (!entry->vccs || entry->vccs->next) {
		diag(COMPONENT,DIAG_ERROR,"internal error: bad unknown entry");
		continue;
	    }
	    FD_SET(entry->vccs->fd,&rset);
	    if (entry->vccs->fd >= fds) fds = entry->vccs->fd+1;
	}
	for (vcc = unidirectional_vccs; vcc; vcc = vcc->next) {
	    FD_SET(vcc->fd,&rset);
	    if (vcc->fd >= fds) fds = vcc->fd+1;
	}
	ret = select(fds,&rset,&cset,NULL,next_timer());
/*
 * Now here's something strange: < 0.32 needed the exception mask to be NULL
 * in order to work, due to a bug in atm_select. In 0.32, this has been fixed.
 * Also, 2.1 kernels use the poll mechanism and not select, so select is
 * emulated on top of poll. Now the funny bit is that, as soon as the exception
 * set is non-NULL, when a non-blocking connect finishes, select returns one
 * but has none if the possible bits set in either rset or cset. To make things
 * even stranger, no exception is actually found in sys_select, so this must be
 * some very odd side-effect ... The work-around for now is to simply pass NULL
 * for the exception mask (which is the right thing to do anyway, but it'd be
 * nice if doing a perfectly valid variation wouldn't blow up the system ...)
 */
#if 0
{
  int i;
  for (i = 0; i < sizeof(rset); i++)
   fprintf(stderr,"%02x:%02x ",((unsigned char *) &rset)[i],
    ((unsigned char *) &cset)[i]);
  fprintf(stderr,"\n");
}
#endif
	if (ret < 0) {
	    if (errno != EINTR) perror("select");
	}
	else {
	    diag(COMPONENT,DIAG_DEBUG,"----------");
	    gettimeofday(&now,NULL);
	    if (FD_ISSET(kernel,&rset)) recv_kernel();
	    if (FD_ISSET(unix_sock,&rset)) recv_unix();
	    if (incoming >= 0 && FD_ISSET(incoming,&rset)) accept_new();
	    for (itf = itfs; itf; itf = next_itf) {
		next_itf = itf->next;
		for (entry = itf->table; entry; entry = next_entry) {
		    next_entry = entry->next;
		    for (vcc = entry->vccs; vcc; vcc = next_vcc) {
			next_vcc = vcc->next;
			if (FD_ISSET(vcc->fd,&rset)) recv_vcc(vcc);
			else if (FD_ISSET(vcc->fd,&cset))
				complete_connect(vcc);
		    }
		}
	    }
	    for (entry = unknown_incoming; entry; entry = next_entry) {
		next_entry = entry->next;
		if (FD_ISSET(entry->vccs->fd,&rset)) recv_vcc(entry->vccs);
	    }
	    for (vcc = unidirectional_vccs; vcc; vcc = next_vcc) {
		next_vcc = vcc->next;
		if (FD_ISSET(vcc->fd,&rset)) drain_vcc(vcc);
	    }
	    expire_timers();
	      /* expire timers after handling messages to make sure we don't
		 time out unnecessarily because of scheduling delays */
	}
	table_changed();
    }
}
Beispiel #6
0
int vfs_signalling_thread(void *arg)
{
	t_thread_arg *argp = (t_thread_arg *)arg;
	if (sub_init_signalling(argp->name))
	{
		LOG(glogfd, LOG_ERROR, "sub_init_signalling %s err %m\n", argp->name);
		stop = 1;
		return -1;
	}
	if (argp->port > 0)
	{
		lfd = get_listen_sock(argp->port);
		if (lfd < 0)
		{
			LOG(glogfd, LOG_ERROR, "get_listen_sock err %d\n", argp->port);
			stop = 1;
			return -1;
		}
		LOG(glogfd, LOG_DEBUG, "%s listen on %d\n", argp->name, argp->port);
	}
	maxevent = argp->maxevent;
    epfd = epoll_create(maxevent);
	if(epfd < 0) 
	{
		LOG(glogfd, LOG_ERROR, "epoll_create(%d): %m\n", maxevent);
		stop = 1;
		return -1;
	}
    pev = (struct epoll_event*)malloc(sizeof(struct epoll_event) * maxevent);
	if(pev == NULL) 
	{
		LOG(glogfd, LOG_ERROR, "allocate epoll_event(%d): %m\n", maxevent);
		stop = 1;
		return -1;
	}
	if (argp->port > 0)
	{
		if (argp->flag)
			set_socket_attr(lfd);
	}

	iobuf = malloc(init_buff_size);
	if (iobuf == NULL)
	{
		LOG(glogfd, LOG_ERROR, "allocate iobuf [%d] error %m\n", init_buff_size);
		stop = 1;
		return -1;
	}

	struct threadstat *thst = get_threadstat();
	int event = EPOLLIN;
	if (argp->port > 0)
		epoll_add(epfd, lfd, event);
	int n = 0, i = 0;
	time_t last = time(NULL);
	time_t now = last;
	LOG(glogfd, LOG_DEBUG, "%s:%s:%d\n", ID, FUNC, LN);
	while (!stop)
	{
	    n = epoll_wait(epfd, pev, maxevent, 1000);
	    for(i = 0; i < n; i++) 
		{
			if (argp->port > 0 && pev[i].data.fd == lfd)
				accept_new();
			else
				do_process(pev[i].data.fd, pev[i].events);
		}
		thread_reached(thst);
		now = time(NULL);
		if (now > last + g_config.cktimeout)
		{
			last = now;
			if (solib.svc_timeout)
				solib.svc_timeout();
		}

	}
	return 0;
}
Beispiel #7
0
void game_loop( void )
{
   struct timeval last_time;

   gettimeofday( &last_time, NULL );
   current_time = last_time.tv_sec;

   // Main loop 
   while( !mud_down )
   {
      accept_new( control );

      // Primative, yet effective infinite loop catcher. At least that's the idea.
      set_alarm( 30 );
      alarm_section = "game_loop";

      // If no descriptors are present, why bother processing input for them?
      if( dlist.size(  ) > 0 )
         process_input(  );

#if !defined(__CYGWIN__)
#ifdef MULTIPORT
      mud_recv_message(  );
#endif
#endif
#ifdef IMC
      imc_loop(  );
#endif

      // Autonomous game motion. Stops processing when there are no people at all online.
      if( dlist.size(  ) > 0 )
         update_handler(  );

      // Event handling. Will continue to process even with nobody around. Keeps areas fresh this way.
      run_events( current_time );

      // If no descriptors are present, why bother processing output for them?
      if( dlist.size(  ) > 0 )
         process_output(  );

      /*
       * Synchronize to a clock. ( Would have moved this to its own function, but the code REALLY hated that plan.... )
       * Sleep( last_time + 1/PULSE_PER_SECOND - now ).
       * Careful here of signed versus unsigned arithmetic.
       */
      {
         struct timeval now_time;
         long secDelta;
         long usecDelta;

         gettimeofday( &now_time, NULL );
         usecDelta = ( last_time.tv_usec ) - ( now_time.tv_usec ) + 1000000 / sysdata->pulsepersec;
         secDelta = ( last_time.tv_sec ) - ( now_time.tv_sec );
         while( usecDelta < 0 )
         {
            usecDelta += 1000000;
            secDelta -= 1;
         }

         while( usecDelta >= 1000000 )
         {
            usecDelta -= 1000000;
            secDelta += 1;
         }

         if( secDelta > 0 || ( secDelta == 0 && usecDelta > 0 ) )
         {
            struct timeval stall_time;

            stall_time.tv_usec = usecDelta;
            stall_time.tv_sec = secDelta;
            if( select( 0, NULL, NULL, NULL, &stall_time ) < 0 && errno != EINTR )
            {
               perror( "game_loop: select: stall" );
               exit( 1 );
            }
         }
      }
      gettimeofday( &last_time, NULL );
      current_time = last_time.tv_sec;

      // Dunno if it needs to be reset, but I'll do it anyway. End of the loop here. 
      set_alarm( 0 );

      /*
       * This will be the very last thing done here, because if you can't make it through
       * one lousy loop without crashing a second time.....
       */
      sigsegv = false;
   }
   // End of main game loop 
   // Returns back to 'main', and will result in mud shutdown
}