Esempio n. 1
0
/* 每个struct sock的时钟函数 */
void
net_timer (unsigned long data)
{
  struct sock *sk = (struct sock*)data;
  /* 相当于获取时钟的类型吧, */
  int why = sk->timeout;
  /* timeout is overwritten by 'delete_timer' and 'reset_timer' */

  /* 判断sock是否已被其他进程使用,或者当前是否正在执行网络的下半部分,
    * 如果当前正在执行网络的下半部分,则重新设置sock的timer,同时添加到
    * 内核时钟当中,等待下次执行 
    */
  if (sk->inuse || in_inet_bh()) {
    sk->timer.expires = 10;
    add_timer(&sk->timer);
    return;
  }

  /* 设置sock为用 */
  sk->inuse = 1;

  DPRINTF ((DBG_TMR, "net_timer: found sk=%X why = %d\n", sk, why));
  if (sk->wfront && 
      before(sk->window_seq, sk->wfront->h.seq) &&
      sk->send_head == NULL &&
      sk->ack_backlog == 0 &&
      sk->state != TCP_TIME_WAIT)
    reset_timer(sk, TIME_PROBE0, sk->rto);
  else if (sk->keepopen)
    reset_timer (sk, TIME_KEEPOPEN, TCP_TIMEOUT_LEN);

  /* Always see if we need to send an ack. */
  /* 看看还有没有收到的数据包没有应答 */
  if (sk->ack_backlog) {
    /* sock发送确认数据包*/
    sk->prot->read_wakeup (sk);
    if (! sk->dead)
      wake_up_interruptible (sk->sleep);
  }

  /* Now we need to figure out why the socket was on the timer. */
  switch (why) {
    case TIME_DONE:
	if (! sk->dead || sk->state != TCP_CLOSE) {
	  printk ("non dead socket in time_done\n");
	  release_sock (sk);
	  break;
	}
	destroy_sock (sk);
	break;
    case TIME_DESTROY:
	/* We've waited for a while for all the memory associated with
	 * the socket to be freed.  We need to print an error message.
	 */
	/* 如果sock的发送缓冲区和接收缓冲区都为空,则直接在后面的语句当中释放 */
	if(sk->wmem_alloc!=0 || sk->rmem_alloc!=0)
	{
		DPRINTF ((DBG_TMR, "possible memory leak.  sk = %X\n", sk));
		sk->wmem_alloc++;	/* So it DOESNT go away */
		destroy_sock (sk);
		sk->wmem_alloc--;	/* Might now have hit 0 - fall through and do it again if so */
		sk->inuse = 0;	/* This will be ok, the destroy won't totally work */
	}
	if(sk->wmem_alloc==0 && sk->rmem_alloc==0)
		destroy_sock(sk);	/* Socket gone, DONT update sk->inuse! */
	break;
    case TIME_CLOSE:
	/* We've waited long enough, close the socket. */
	sk->state = TCP_CLOSE;
	delete_timer (sk);
	/* Kill the ARP entry in case the hardware has changed. */
	arp_destroy_maybe (sk->daddr);
	if (!sk->dead)
	  wake_up_interruptible (sk->sleep);
	sk->shutdown = SHUTDOWN_MASK;
	reset_timer (sk, TIME_DESTROY, TCP_DONE_TIME);
	release_sock (sk);
	break;
    case TIME_PROBE0:   /* 窗口探测定时器,也被称为坚持定时器 */
	tcp_send_probe0(sk);
	release_sock (sk);
	break;
    case TIME_WRITE:	/* 超时重传定时器 */   /* try to retransmit. */
	/* It could be we got here because we needed to send an ack.
	 * So we need to check for that.
	 */
	if (sk->send_head) {
	  if (jiffies < (sk->send_head->when + sk->rto)) {
	    reset_timer (sk, TIME_WRITE, 
			 (sk->send_head->when + sk->rto - jiffies));
	    release_sock (sk);
	    break;
	  }
	  /* printk("timer: seq %d retrans %d out %d cong %d\n", sk->send_head->h.seq,
	     sk->retransmits, sk->packets_out, sk->cong_window); */
	  DPRINTF ((DBG_TMR, "retransmitting.\n"));
          /* 调用tcp协议的超时重传函数 */
	  sk->prot->retransmit (sk, 0);
	  if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
	    || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) {
	    DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 1\n"));
	    arp_destroy_maybe (sk->daddr);
	    ip_route_check (sk->daddr);
	  }
	  if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) {
	    DPRINTF ((DBG_TMR, "timer.c TIME_WRITE time-out 2\n"));
	    sk->err = ETIMEDOUT;
	    if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2
	      || sk->state == TCP_LAST_ACK) {
	      sk->state = TCP_TIME_WAIT;
	      reset_timer (sk, TIME_CLOSE, TCP_TIMEWAIT_LEN);
	    } else {
	      sk->prot->close (sk, 1);
	      break;
	    }
	  }
	}
	release_sock (sk);
	break;
    case TIME_KEEPOPEN:          /* 保活定时器 */
	/* Send something to keep the connection open. */
	if (sk->prot->write_wakeup)
	  sk->prot->write_wakeup (sk);
	sk->retransmits++;  /* 因为是重发定时,所以会增加超时重发次数 */
	if (sk->shutdown == SHUTDOWN_MASK) {
	  sk->prot->close (sk, 1);
	  sk->state = TCP_CLOSE;
	}

	if ((sk->state == TCP_ESTABLISHED && sk->retransmits && !(sk->retransmits & 7))
	  || (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR1)) {
	  DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 1\n"));
	  arp_destroy_maybe (sk->daddr);
	  ip_route_check (sk->daddr);
	  release_sock (sk);
	  break;
	}
	if (sk->state != TCP_ESTABLISHED && sk->retransmits > TCP_RETR2) {
	  DPRINTF ((DBG_TMR, "timer.c TIME_KEEPOPEN time-out 2\n"));
	  arp_destroy_maybe (sk->daddr);
	  sk->err = ETIMEDOUT;
	  if (sk->state == TCP_FIN_WAIT1 || sk->state == TCP_FIN_WAIT2) {
	    sk->state = TCP_TIME_WAIT;
	    if (!sk->dead)
	      wake_up_interruptible (sk->sleep);
	    release_sock (sk);
	  } else {
	    sk->prot->close (sk, 1);
	  }
	  break;
	}
	release_sock (sk);
	break;
    default:
	printk ("net timer expired - reason unknown, sk=%08X\n", (int)sk);
	release_sock (sk);
	break;
  }
}
Esempio n. 2
0
void recv_lprobe(task * tmp_packet) {
	aodv_neigh *tmp_neigh;
	l_probe *tmp_lprobe;
	u_int32_t res_sec, res_usec, sec, usec;

	tmp_lprobe = tmp_packet->data;

	tmp_neigh = find_aodv_neigh(tmp_packet->src_ip);
	if (tmp_neigh == NULL) {
#ifdef DEBUG
		printk ("Error: Source %s of an incoming large probe-packet belongs to any neighbour\n", inet_ntoa(tmp_packet->src_ip));
#endif
		return;
	}

	
	//Update neighbor timelife
	delete_timer(tmp_neigh->ip, tmp_neigh->ip, NO_TOS, TASK_NEIGHBOR);
	insert_timer_simple(TASK_NEIGHBOR, HELLO_INTERVAL
			* (1 + ALLOWED_HELLO_LOSS) + 100, tmp_neigh->ip);
	update_timer_queue();
	tmp_neigh->lifetime = HELLO_INTERVAL * (1 + ALLOWED_HELLO_LOSS) + 20
			+ getcurrtime();

	if (tmp_lprobe->n_probe != tmp_neigh->ett.last_count) //if not equal, the don't belong to the same pair.
	{
#ifdef DEBUG
		printk("Error: Invalid pair of probe-packets from %s\n",inet_ntoa(tmp_packet->src_ip) );
#endif
		return;
	}

	//NEW ETT-PAIR received - Timer is reloaded
	delete_timer(tmp_neigh->ip, tmp_neigh->ip, NO_TOS, TASK_ETT_CLEANUP);
	insert_timer_simple(TASK_ETT_CLEANUP, ETT_INTERVAL * (1 + ALLOWED_ETT_LOSS)
			+ 100, tmp_neigh->ip);
	update_timer_queue();

	sec = tmp_lprobe->sec;
	usec = tmp_lprobe->usec;
	res_sec = sec - tmp_neigh->ett.sec;
	if (res_sec == 0)
		//large packet still received  on same the second-value to the small one, only usec was incremented
		res_usec = usec - tmp_neigh->ett.usec;
	else if (res_sec == 1) //large packet received in a new second-value
		res_usec=1000000 + usec - tmp_neigh->ett.sec;
	else {
#ifdef DEBUG
		printk ("Too high delay between the probe-packets, difference in seconds of %d\n", res_sec);
#endif
		res_usec = DEFAULT_ETT_METRIC;
	}
	tmp_neigh->ett.meas_delay = res_usec;
	tmp_neigh->recv_rate = ntohs(tmp_lprobe->my_rate);

	if (g_fixed_rate == 0) {
		delay_vector_add(tmp_neigh, ntohl(tmp_lprobe->last_meas_delay));
#ifdef DEBUG
		printk("Received Delay to %s: %d Usecs\n",inet_ntoa(tmp_neigh->ip) ,ntohl(tmp_lprobe->last_meas_delay));
#endif
		compute_estimation(tmp_neigh);
	}

	if (tmp_neigh->recv_rate == 0 || tmp_neigh->send_rate == 0) //Estimation is still undone! Fast_interval!
		tmp_neigh->ett.interval = ETT_FAST_INTERVAL;
	else
		tmp_neigh->ett.interval = ETT_INTERVAL;

	return;

}
Esempio n. 3
0
void net_timer (unsigned long data)
{
	struct sock *sk = (struct sock*)data;
	int why = sk->timeout;

	/* 
	 * only process if socket is not in use
	 */

	if (sk->users)
	{
		sk->timer.expires = jiffies+HZ;
		add_timer(&sk->timer);
		sti();
		return;
	}

	/* Always see if we need to send an ack. */

	if (sk->ack_backlog && !sk->zapped) 
	{
		sk->prot->read_wakeup (sk);
		if (! sk->dead)
		sk->data_ready(sk,0);
	}

	/* Now we need to figure out why the socket was on the timer. */

	switch (why) 
	{
		case TIME_DONE:
			/* If the socket hasn't been closed off, re-try a bit later */
			if (!sk->dead) {
				reset_timer(sk, TIME_DONE, TCP_DONE_TIME);
				break;
			}

			if (sk->state != TCP_CLOSE) 
			{
				printk ("non CLOSE socket in time_done\n");
				break;
			}
			destroy_sock (sk);
			break;

		case TIME_DESTROY:
		/*
		 *	We've waited for a while for all the memory associated with
		 *	the socket to be freed.
		 */

			destroy_sock(sk);
			break;

		case TIME_CLOSE:
			/* We've waited long enough, close the socket. */
			sk->state = TCP_CLOSE;
			delete_timer (sk);
			if (!sk->dead)
				sk->state_change(sk);
			sk->shutdown = SHUTDOWN_MASK;
			reset_timer (sk, TIME_DONE, TCP_DONE_TIME);
			break;

		default:
			printk ("net_timer: timer expired - reason %d is unknown\n", why);
			break;
	}
}
Esempio n. 4
0
/*==========================================
 * Removes a instance, all its maps and npcs.
 *------------------------------------------*/
int instance_destroy(short instance_id)
{
	struct instance_data *im;
	struct party_data *p;
	int i, type = 0, count = 0;
	unsigned int now = (unsigned int)time(NULL);

	if(instance_id <= 0 || instance_id > MAX_INSTANCE_DATA)
		return 1;

	im = &instance_data[instance_id];

	if(im->state == INSTANCE_FREE)
		return 1;

	if(im->state == INSTANCE_IDLE) {
		for(i = 0; i < instance_wait.count; i++) {
			if(instance_wait.id[i] == instance_id) {
				instance_wait.count--;
				memmove(&instance_wait.id[i],&instance_wait.id[i+1],sizeof(instance_wait.id[0])*(instance_wait.count-i));
				memset(&instance_wait.id[instance_wait.count], 0, sizeof(instance_wait.id[0]));

				for(i = 0; i < instance_wait.count; i++)
					if(instance_data[instance_wait.id[i]].state == INSTANCE_IDLE)
						if((p = party_search(instance_data[instance_wait.id[i]].party_id)) != NULL)
							clif_instance_changewait( party_getavailablesd( p ), i+1, 1);

				if(instance_wait.count)
					instance_wait.timer = add_timer(gettick()+INSTANCE_INTERVAL, instance_subscription_timer, 0, 0);
				else
					instance_wait.timer = -1;
				type = 0;
				break;
			}
		}
	} else {
		if(im->keep_limit && im->keep_limit <= now)
			type = 1;
		else if(im->idle_limit && im->idle_limit <= now)
			type = 2;
		else
			type = 3;

		for(i = 0; i < MAX_MAP_PER_INSTANCE; i++)
			count += map_delinstancemap(im->map[i].m);
	}

	if(im->keep_timer != -1) {
		delete_timer(im->keep_timer, instance_delete_timer);
		im->keep_timer = -1;
	}
	if(im->idle_timer != -1) {
		delete_timer(im->idle_timer, instance_delete_timer);
		im->idle_timer = -1;
	}

	if((p = party_search(im->party_id))) {
		p->instance_id = 0;

		if(type)
			clif_instance_changestatus( party_getavailablesd( p ), type, 0, 1 );
		else
			clif_instance_changewait( party_getavailablesd( p ), 0xffff, 1 );
	}

	if( im->vars ) {
		db_destroy(im->vars);
		im->vars = NULL;
	}

	ShowInfo("[Instance] Destroyed %d.\n", instance_id);

	memset(&instance_data[instance_id], 0, sizeof(instance_data[instance_id]));

	return 0;
}
Esempio n. 5
0
static void post_event_once(struct timerobj *tmobj)
{
	struct psos_tm *tm = container_of(tmobj, struct psos_tm, tmobj);
	ev_send(tm->tid, tm->events);
	delete_timer(tm);
}
Esempio n. 6
0
long sys_timer_control(long id,long cmd,long arg1,long arg2,long arg3)
{
  long r=-EINVAL;
  task_t *caller=current_task();
  posix_stuff_t *stuff=caller->posix_stuff;
  posix_timer_t *ptimer;
  itimerspec_t tspec,kspec;
  ktimer_t *ktimer;

#ifdef CONFIG_DEBUG_TIMERS
  kprintf_fault("sys_timer_control(<BEGIN>) [%d:%d]: Tick=%d,(cmd=%d,id=%d)\n",
                current_task()->pid,current_task()->tid,
                system_ticks,cmd,id);
#endif

  switch( cmd ) {
    case __POSIX_TIMER_SETTIME:
      /* Arguments are the same as for POSIX 'timer_settime()':
       *    arg1: int flags, arg2: struct itimerspec *value
       *    arg3: struct itimerspec *ovalue
       */
      if( !arg2 || copy_from_user(&tspec,(void *)arg2,sizeof(tspec)) ) {
        r=-EFAULT;
      } else {
        bool valid_timeval=timeval_is_valid(&tspec.it_value) && timeval_is_valid(&tspec.it_interval);
        ulong_t tx=time_to_ticks(&tspec.it_value);
        ulong_t itx=time_to_ticks(&tspec.it_interval);

        /* We need to hold the lock during the whole process, so lookup
         * target timer explicitely.
         */
        LOCK_POSIX_STUFF_W(stuff);
        ptimer=(posix_timer_t*)__posix_locate_object(stuff,id,POSIX_OBJ_TIMER);
        if( !ptimer ) {
          break;
        }

        ktimer=&ptimer->ktimer;
        if( !(tspec.it_value.tv_sec | tspec.it_value.tv_nsec) ) {
          if( ktimer->time_x && posix_timer_active(ptimer) ) { /* Disarm active timer */
#ifdef CONFIG_DEBUG_TIMERS
            kprintf_fault("sys_timer_control() [%d:%d]: Tick=%d, deactivating timer %p:(P=%d) to %d\n",
                          current_task()->pid,current_task()->tid,
                          system_ticks,ktimer,ptimer->interval,tx);
#endif
            deactivate_posix_timer(ptimer);
            delete_timer(ktimer);
          }
          r=0;
        } else if( valid_timeval ) {
          if( !(arg1 & TIMER_ABSTIME) ) {
            tx+=system_ticks;
          }

          ptimer->interval=itx;
          activate_posix_timer(ptimer);
          if( ktimer->time_x ) { /* New time for active timer. */
#ifdef CONFIG_DEBUG_TIMERS
            kprintf_fault("sys_timer_control() [%d:%d] <RE-ARM> Tick=%d, timer=%p:(Tv=%d/%d,Pv=%d/%d,ABS=%d) to %d\n",
                          current_task()->pid,current_task()->tid,
                          system_ticks,ktimer,
                          tspec.it_value.tv_sec,tspec.it_value.tv_nsec,
                          tspec.it_interval.tv_sec,tspec.it_interval.tv_nsec,
                          (arg1 & TIMER_ABSTIME) != 0,
                          tx);
#endif

            r=modify_timer(ktimer,tx);
          } else {
            TIMER_RESET_TIME(ktimer,tx);

#ifdef CONFIG_DEBUG_TIMERS
            kprintf_fault("sys_timer_control() <ARM> [%d:%d] Tick=%d, timer=%p:(Tv=%d/%d,Pv=%d/%d,ABS=%d) to %d\n",
                          current_task()->pid,current_task()->tid,
                          system_ticks,ktimer,
                          tspec.it_value.tv_sec,tspec.it_value.tv_nsec,
                          tspec.it_interval.tv_sec,tspec.it_interval.tv_nsec,
                          (arg1 & TIMER_ABSTIME) != 0,
                          tx);
#endif

            r=add_timer(ktimer);
          }
        }
        UNLOCK_POSIX_STUFF_W(stuff);

        if( !r && arg3 ) {
          __get_timer_status(ptimer,&kspec);
          if( copy_to_user((itimerspec_t *)arg3,&kspec,sizeof(kspec)) )  {
            r=-EFAULT;
            /* TODO: [mt] Cleanup timer upon -EFAULT. */
          }
        }
      }
      break;
    case __POSIX_TIMER_GETTIME:
      ptimer=posix_lookup_timer(stuff,id);
      if( !ptimer ) {
        break;
      }
      __get_timer_status(ptimer,&kspec);
      r=copy_to_user((itimerspec_t *)arg1,&kspec,sizeof(kspec)) ? -EFAULT : 0;
      break;
    case __POSIX_TIMER_GETOVERRUN:
      ptimer=posix_lookup_timer(stuff,id);
      if( !ptimer ) {
        break;
      }
      r=ptimer->overrun;
      break;
    default:
      r=-EINVAL;
      break;
  }

  if( ptimer ) {
    release_posix_timer(ptimer);
  }

#ifdef CONFIG_DEBUG_TIMERS
  kprintf_fault("sys_timer_control(<END>) [%d:%d]: Tick=%d, (cmd=%d,id=%d), result=%d\n",
                current_task()->pid,current_task()->tid,
                system_ticks,cmd,id,r);
#endif
  return ERR(r);
}
Esempio n. 7
0
int main(int argc,char **argv)
{
LONG seconds;
struct timerequest *tr;      /* IO block for timer commands */
struct timeval oldtimeval;   /* timevals to store times     */
struct timeval mytimeval;
struct timeval currentval;

printf("\nTimer test\n");

/* sleep for two seconds */
currentval.tv_secs = 2;
currentval.tv_micro = 0;
time_delay( &currentval, UNIT_VBLANK );
printf( "After 2 seconds delay\n" );

/* sleep for four seconds */
currentval.tv_secs = 4;
currentval.tv_micro = 0;
time_delay( &currentval, UNIT_VBLANK );
printf( "After 4 seconds delay\n" );

/* sleep for 500,000 micro-seconds = 1/2 second */
currentval.tv_secs = 0;
currentval.tv_micro = 500000;
time_delay( &currentval, UNIT_MICROHZ );
printf( "After 1/2 second delay\n" );

printf( "DOS Date command shows: " );
(void) Execute( "date", 0, 0 );

/* save what system thinks is the time....we'll advance it temporarily */
get_sys_time( &oldtimeval );
printf("Original system time is:\n");
show_time(oldtimeval.tv_secs );

printf("Setting a new system time\n");

seconds = 1000 * SECSPERDAY + oldtimeval.tv_secs;

set_new_time( seconds );
/* (if user executes the AmigaDOS DATE command now, he will*/
/* see that the time has advanced something over 1000 days */

printf( "DOS Date command now shows: " );
(void) Execute( "date", 0, 0 );

get_sys_time( &mytimeval );
printf( "Current system time is:\n");
show_time(mytimeval.tv_secs);

/* Added the microseconds part to show that time keeps */
/* increasing even though you ask many times in a row  */

printf("Now do three TR_GETSYSTIMEs in a row (notice how the microseconds increase)\n\n");
get_sys_time( &mytimeval );
printf("First TR_GETSYSTIME \t%ld.%ld\n",mytimeval.tv_secs, mytimeval.tv_micro);
get_sys_time( &mytimeval );
printf("Second TR_GETSYSTIME \t%ld.%ld\n",mytimeval.tv_secs, mytimeval.tv_micro);
get_sys_time( &mytimeval );
printf("Third TR_GETSYSTIME \t%ld.%ld\n",mytimeval.tv_secs, mytimeval.tv_micro);

printf( "\nResetting to former time\n" );
set_new_time( oldtimeval.tv_secs );

get_sys_time( &mytimeval );
printf( "Current system time is:\n");
show_time(mytimeval.tv_secs);

/* just shows how to set up for using the timer functions, does not */
/* demonstrate the functions themselves.  (TimerBase must have a    */
/* legal value before AddTime, SubTime or CmpTime are performed.    */
tr = create_timer( UNIT_MICROHZ );
if (tr)
    TimerBase = (struct Library *)tr->tr_node.io_Device;
else
    printf("Could't create timer with UNIT_MICROHZ\n");

/* and how to clean up afterwards */
TimerBase = (struct Library *)(-1);
delete_timer( tr );

return 0;
}
Esempio n. 8
0
void harmony_action_request_global(int task, int id, intptr data) {
	switch (task) {
	case HARMTASK_LOGIN_ACTION:
		chrif_harmony_request((uint8*)data, id);
		break;
	case HARMTASK_GET_FD:
		{
		TBL_PC *sd = BL_CAST(BL_PC, map_id2bl(id));
		*(int32*)data = (sd ? sd->fd : 0);
		}
		break;
	case HARMTASK_SET_LOG_METHOD:
		log_method = id;
		break;
	case HARMTASK_INIT_GROUPS:
		if (chrif_isconnected())
			harmony_register_groups();
		else {
			// Register groups as soon as the char server is available again
			if (tid_group_register != INVALID_TIMER)
				delete_timer(tid_group_register, harmony_group_register_timer);
			tid_group_register = add_timer_interval(gettick()+1000, harmony_group_register_timer, 0, 0, 500);
		}
		break;
	case HARMTASK_RESOLVE_GROUP:
#if HARMSW == HARMSW_RATHENA_GROUP
		*(int32*)data = pc_group_id2level(id);
#else
		*(int32*)data = id;
#endif
		break;
	case HARMTASK_PACKET:
		clif_send((const uint8*)data, id, NULL, ALL_CLIENT);
		break;
	case HARMTASK_GET_ADMINS:
	{
#if HARMSW == HARMSW_RATHENA_GROUP
		// Iterate groups and register each group individually
		current_groupscan_minlevel = id;
		pc_group_iterate(harmony_iterate_groups_adminlevel);
#else
		//
		int account_id;
		int level = id;
		if (SQL_SUCCESS != SqlStmt_BindParam(admin_stmt, 0, SQLDT_INT, (void*)&level, sizeof(level)) ||
			SQL_SUCCESS != SqlStmt_Execute(admin_stmt))
		{
			ShowError("Fetching GM accounts failed.\n");
			Sql_ShowDebug(mmysql_handle);
			break;
		}

		SqlStmt_BindColumn(admin_stmt, 0, SQLDT_INT, &account_id, 0, NULL, NULL);
		while (SQL_SUCCESS == SqlStmt_NextRow(admin_stmt)) {
			harm_funcs->zone_register_admin(account_id, false);
		}
#endif
		break;
	}
	case HARMTASK_IS_CHAR_CONNECTED:
		*(int*)data = chrif_isconnected();
		break;
	default:
		ShowError("Harmony requested unknown action! (Global; ID=%d)\n", task);
		ShowError("This indicates that you are running an incompatible version.\n");
		break;
	}
}
Esempio n. 9
0
int bg_team_clean(int bg_id, bool remove)
{ // Deletes BG Team from db
	int i;
	struct map_session_data *sd;
	struct battleground_data *bg = bg_team_search(bg_id);
	struct guild *g;

	if( bg == NULL ) return 0;
	for( i = 0; i < MAX_BG_MEMBERS; i++ )
	{
		if( (sd = bg->members[i].sd) == NULL )
			continue;

		bg_send_dot_remove(sd);
		sd->bg_id = 0;
		sd->state.bg_afk = 0;
		sd->bmaster_flag = NULL;
		bg_member_removeskulls(sd);

		// Remove Guild Skill Buffs
		status_change_end(&sd->bl,SC_GUILDAURA,INVALID_TIMER);
		status_change_end(&sd->bl,SC_BATTLEORDERS,INVALID_TIMER);
		status_change_end(&sd->bl,SC_REGENERATION,INVALID_TIMER);

		if( !battle_config.bg_eAmod_mode )
			continue; // No need to touch Guild stuff

		if( sd->status.guild_id && (g = guild_search(sd->status.guild_id)) != NULL )
		{
			clif_guild_belonginfo(sd,g);
			clif_guild_basicinfo(sd);
			clif_guild_allianceinfo(sd);
			clif_guild_memberlist(sd);
			clif_guild_skillinfo(sd);
		}
		else
			clif_bg_leave_single(sd, sd->status.name, "Leaving Battleground...");

		clif_charnameupdate(sd);
		clif_guild_emblem_area(&sd->bl);
	}

	for( i = 0; i < MAX_GUILDSKILL; i++ )
	{
		if( bg->skill_block_timer[i] == INVALID_TIMER )
			continue;
		delete_timer(bg->skill_block_timer[i], bg_block_skill_end);
	}

	if( remove )
		idb_remove(bg_team_db, bg_id);
	else
	{
		bg->count = 0;
		bg->leader_char_id = 0;
		bg->team_score = 0;
		bg->creation_tick = 0;
		memset(&bg->members, 0, sizeof(bg->members));
	}

	return 1;
}
Esempio n. 10
0
void elemental_summon_stop(struct elemental_data *ed) {
	nullpo_retv(ed);
	if( ed->summon_timer != INVALID_TIMER )
		delete_timer(ed->summon_timer, elemental_summon_end);
	ed->summon_timer = INVALID_TIMER;
}
Esempio n. 11
0
/*
 * You call this to register a timer callback.
 *
 * The arguments:
 *  update:      This should be 1 if we're updating the specified refnum
 *  refnum_want: The refnum requested.  
 *		 (1) User-supplied for /TIMER timers
 *		 (2) the empty string for system timers ("dont care")
 *  interval:	 How long until the timer should fire; 
 *		 (1) for repeating timers (events != 1), the timer will 
 *		     fire with this interval.
 *		 (2) for "snap" timers, the first fire will be the next
 *		     time time() % interval == 0.
 *  events:	 The number of times this event should fire.  
 *		 (1) The value -1 means "repeat forever"
 *		 (2) Timers automatically delete after they fire the
 *		     requested number of times.
 *
 * Scenario 1: You want to run ircII commands (/TIMER timers)
 * | callback:	 NULL
 * | commands:	 some ircII commands to run when the timer goes off
 * | subargs:	 what to use to expand $0's, etc in the 'what' variable.
 *
 * Scenario 2: You want to call an internal function (system timers)
 * | callback:	 function to call when timer goes off
 * | commands:	 argument to pass to "callback" function.  Should be some
 * |		 non-auto storage, perhaps a struct or a malloced char *
 * |		 array.  The caller is responsible for disposing of this
 * |		 area when it is called, since the timer mechanism does not
 * |		 know anything of the nature of the argument.
 * | subargs:	 should be NULL, its ignored anyhow.
 *
 *  domain:	What the TIMER should bind to:
 *		(a) SERVER_TIMER  - 'domref' refers to a server refnum.
 *			Each time this timer runs, set from_server to 'domref'
 *			and set the current window to whatever 'domref's 
 *			current window is at that time.
 *		(b) WINDOW_TIME - 'domref' refers to a window refnum.
 *			Each time this timer runs, set current_window to
 *			'domref' and set the current server to whatever 
 *			'domref's server is at that time.
 *		(c) GENERAL_TIMER - 'domref' is ignored.  
 *			Do not save or restore from_server or current_window: 
 *			run in whatever the context is when it goes off.
 *  domref:	Either a server refnum, window refnum, or -1 (see 'domain')
 *  cancelable:	A "Cancelable" timer will not fire if its context cannot be
 *		restored (ie, the server it is bound to is disconnected or
 *		deleted; or the window it is bound to is deleted).  A normal
 *		(non-cancelable) timer will turn into a GENERAL_TIMER if its
 *		context cannot be restored.
 *  snap:	A "snap" timer runs every time (time() % interval == 0).
 *		This is useful for things that (eg) run at the top of every 
 *		minute (60), hour (3600), or day (86400)
 */
char *add_timer (int update, const char *refnum_want, double interval, long events, int (callback) (void *), void *commands, const char *subargs, TimerDomain domain, int domref, int cancelable, int snap)
{
	Timer	*ntimer, *otimer = NULL;
	char *	refnum_got = NULL;
	Timeval right_now;
	char *	retval;

	right_now = get_time(NULL);

	/*
	 * We do this first, because if 'interval' is invalid, we don't
	 * want to do the expensive clone/create/delete operation.
 	 * It is ineligant to check for this error here.
	 */
	if (update == 1 && interval == -1)	/* Not changing the interval */
		(void) 0;	/* XXX sigh */
	else if (interval < 0.01 && events == -1)
	{
		say("You can't infinitely repeat a timer that runs more "
			"than 100 times a second.");
		return NULL;
	}

	/* 
	 * If we say we're updating; but the timer does not exist, 
	 * then we're not updating. ;-)
	 */
	if (update)
	{
	    if (!(otimer = get_timer(refnum_want)))
		update = 0;		/* Ok so we're not updating! */
	}

	/*
	 * Arrange for an appropriate Timer to be in 'ntimer'.
	 */
	if (update)
	{
		unlink_timer(otimer);
		ntimer = clone_timer(otimer);
		delete_timer(otimer);
	}
	else
	{
		if (create_timer_ref(refnum_want, &refnum_got) == -1)
		{
			say("TIMER: Refnum '%s' already exists", refnum_want);
			return NULL;
		}

		ntimer = new_timer();
		ntimer->ref = refnum_got;
	}

	/* Update the interval */
	if (update == 1 && interval == -1)
		(void) 0;	/* XXX sigh - not updating interval */
	else
	{
		ntimer->interval = double_to_timeval(interval);
		if (snap)
		{
			double x = time_to_next_interval(interval);
			ntimer->time = time_add(right_now, double_to_timeval(x));
		}
		else
			ntimer->time = time_add(right_now, ntimer->interval);
	}

	/* Update the repeat events */
	if (update == 1 && events == -2)
		(void) 0;	/* XXX sigh - not updating events */
	else
		ntimer->events = events;


	/* Update the callback */
	if (callback)
	{
		/* Delete the previous timer, if necessary */
		if (ntimer->command)
			new_free(&ntimer->command);
		if (ntimer->subargs)
			new_free(&ntimer->subargs);
		ntimer->callback = callback;

		/* Unfortunately, command is "sometimes const". */
		ntimer->callback_data = commands;
		ntimer->subargs = NULL;
	}
	else
	{
		ntimer->callback = NULL;
		malloc_strcpy(&ntimer->command, (const char *)commands);
		malloc_strcpy(&ntimer->subargs, subargs);
	}

	/* Update the domain refnum */
	ntimer->domain = domain;
	if (update == 1 && domref == -1)
		(void) 0;	/* XXX sigh - not updating domref */
	else
		ntimer->domref = domref;

	/* Update the cancelable */
	if (update == 1 && cancelable == -1)
		(void) 0;	/* XXX sigh - not updating cancelable */
	else
		ntimer->cancelable = cancelable;


	/* Schedule up the new/updated timer! */
	schedule_timer(ntimer);
	retval = ntimer->ref;
	return retval;		/* Eliminates a specious warning from gcc */
}
Esempio n. 12
0
/*
 * ExecuteTimers:  checks to see if any currently pending timers have
 * gone off, and if so, execute them, delete them, etc, setting the
 * current_exec_timer, so that we can't remove the timer while its
 * still executing.
 *
 * changed the behavior: timers will not hook while we are waiting.
 */
void 	ExecuteTimers (void)
{
	Timeval	right_now;
	Timer *	current, *next;
	int	old_from_server = from_server;

	get_time(&right_now);
	while (PendingTimers && time_diff(right_now, PendingTimers->time) < 0)
	{
		int	old_refnum;

		old_refnum = current_window->refnum;
		current = PendingTimers;
		unlink_timer(current);

		/* Reschedule the timer if necessary */
		if (current->events < 0 || (current->events != 1))
		{
			next = clone_timer(current);
			if (next->events != -1)
				next->events--;

			next->time = time_add(next->time, next->interval);
			schedule_timer(next);
		}

		if (current->domain == SERVER_TIMER)
		{
		    if (!is_server_valid(current->domref))
		    {
			if (current->cancelable)
			    goto advance;
			/* Otherwise, pretend you were a  "GENERAL" type */
		    }
		    else
		    {
			from_server = current->domref;
			make_window_current_by_refnum(
					get_winref_by_servref(from_server));
		    }
		}
		else if (current->domain == WINDOW_TIMER)
		{
		    if (!get_window_by_refnum(current->domref))
		    {
			if (current->cancelable)
			    goto advance;
			/* Otherwise, pretend you were a "GENERAL" type */
		    }
		    else
		    {
			make_window_current_by_refnum(current->domref);
			from_server = current_window->server;
		    }
		}
		else
		{
		    /* General timers focus on the current window. */
		    if (current_window)
		    {
			if (current_window->server != from_server)
			    from_server = current_window->server;
		    }
		    else
		    {
			if (from_server != NOSERV)
			    make_window_current_by_refnum(
				get_winref_by_servref(from_server));
		    }
		}

		/* 
		 * If a callback function was registered, then
		 * we use it.  If no callback function was registered,
		 * then we call the lambda function.
		 */
		get_time(&right_now);
		now = right_now;
		if (current->callback)
			(*current->callback)(current->callback_data);
		else
			call_lambda_command("TIMER", current->command,
							current->subargs);

		from_server = old_from_server;
		make_window_current_by_refnum(old_refnum);
advance:
		delete_timer(current);
	}
}
Esempio n. 13
0
/*
 * You call this to register a timer callback.
 *
 * The arguments:
 *  update:      This should be 1 if we're updating the specified refnum
 *  refnum_want: The refnum requested.  This should only be sepcified
 *		 by the user, functions wanting callbacks should specify
 *		 the empty string, which means "dont care".
 * The rest of the arguments are dependant upon the value of "callback"
 *	-- if "callback" is NULL then:
 *  callback:	 NULL
 *  what:	 some ircII commands to run when the timer goes off
 *  subargs:	 what to use to expand $0's, etc in the 'what' variable.
 *
 *	-- if "callback" is non-NULL then:
 *  callback:	 function to call when timer goes off
 *  what:	 argument to pass to "callback" function.  Should be some
 *		 non-auto storage, perhaps a struct or a malloced char *
 *		 array.  The caller is responsible for disposing of this
 *		 area when it is called, since the timer mechanism does not
 *		 know anything of the nature of the argument.
 * subargs:	 should be NULL, its ignored anyhow.
 */
char *add_timer (int update, const char *refnum_want, double interval, long events, int (callback) (void *), void *commands, const char *subargs, int winref)
{
	Timer	*ntimer, *otimer = NULL;
	char	refnum_got[REFNUM_MAX + 1];
	Timeval right_now;
	char *	retval;

	/* XXX Eh, maybe it's a hack to check this here. */
	if (interval < 0.01 && events == -1)
	{
		say("You can't infinitely repeat a timer that runs more "
			"than 100 times a second.");
		return NULL;
	}

	right_now = get_time(NULL);

	if (update)
	{
	    if (!(otimer = get_timer(refnum_want)))
		update = 0;		/* Ok so we're not updating! */
	}

	if (update)
	{
		unlink_timer(otimer);
		ntimer = clone_timer(otimer);
		delete_timer(otimer);

		if (interval != -1)
		{
			ntimer->interval = double_to_timeval(interval);
			ntimer->time = time_add(right_now, ntimer->interval);
		}
		if (events != -2)
			ntimer->events = events;

		if (callback)
		{
			/* Delete the previous timer, if necessary */
			if (ntimer->command)
				new_free(&ntimer->command);
			if (ntimer->subargs)
				new_free(&ntimer->subargs);
			ntimer->callback = callback;
			/* Unfortunately, command is "sometimes const". */
			ntimer->callback_data = commands;
			ntimer->subargs = NULL;
		}
		else
		{
			if (ntimer->callback)
				ntimer->callback = NULL;
			malloc_strcpy(&ntimer->command, (const char *)commands);
			malloc_strcpy(&ntimer->subargs, subargs);
		}

		if (winref != -1)
			ntimer->window = winref;

	}
	else
	{
		if (create_timer_ref(refnum_want, refnum_got) == -1)
		{
			say("TIMER: Refnum '%s' already exists", refnum_want);
			return NULL;
		}

		ntimer = new_timer();
		strlcpy(ntimer->ref, refnum_got, sizeof ntimer->ref);
		ntimer->interval = double_to_timeval(interval);
		ntimer->time = time_add(right_now, ntimer->interval);
		ntimer->events = events;
		ntimer->callback = callback;
		/* Unfortunately, command is "sometimes const". */
		if (callback)
			ntimer->callback_data = commands;
		else
			malloc_strcpy(&ntimer->command, (const char *)commands);
		malloc_strcpy(&ntimer->subargs, subargs);
		ntimer->window = winref;
		ntimer->server = from_server;
	}

	schedule_timer(ntimer);
	retval = ntimer->ref;
	return retval;		/* Eliminates a specious warning from gcc */
}
Esempio n. 14
0
// Give a timer to the data store.  At this point the data store takes ownership
// of the timer and the caller should not reference it again (as the timer store
// may delete it at any time).
void TimerStore::add_timer(Timer* t)
{
  // First check if this timer already exists.
  auto map_it = _timer_lookup_table.find(t->id);
  if (map_it != _timer_lookup_table.end())
  {
    Timer* existing = map_it->second;

    // Compare timers for precedence, start-time then sequence-number.
    if ((t->start_time < existing->start_time) ||
        ((t->start_time == existing->start_time) &&
         (t->sequence_number < existing->sequence_number)))
    {
      // Existing timer is more recent
      delete t;
      return;
    }
    else
    {
      // Existing timer is older
      if (t->is_tombstone())
      {
        // Learn the interval so that this tombstone lasts long enough to catch
        // errors.
        t->interval = existing->interval;
        t->repeat_for = existing->interval;
      }
      delete_timer(t->id);
    }
  }

  // Work out where to store the timer (overdue bucket, short wheel, long wheel,
  // or heap).
  //
  // Note that these if tests MUST use less than. For example if _tick_time is
  // 20,330 a 1s timer will pop at 21,330. When in the short wheel the timer
  // will live in bucket 33. But this is the bucket that is about to pop, so the
  // timer must actually go in to the long wheel.  The same logic applies for
  // the 1s buckets (where timers due to pop in >=1hr need to go into the heap).
  uint64_t next_pop_time = t->next_pop_time();
  Bucket* bucket;

  if (next_pop_time < _tick_timestamp)
  {
    // The timer should have already popped so put it in the overdue timers,
    // and warn the user.
    //
    // We can't just put the timer in the next bucket to pop.  We need to know
    // what bucket to look in when deleting timers, and this is derived from
    // the pop time. So if we put the timer in the wrong bucket we can't find
    // it to delete it.
    LOG_WARNING("Modifying timer after pop time (current time is %lu). "
                "Window condition detected.\n" TIMER_LOG_FMT,
                _tick_timestamp,
                TIMER_LOG_PARAMS(t));
    _overdue_timers.insert(t);
  }
  else if (to_short_wheel_resolution(next_pop_time) <
           to_short_wheel_resolution(_tick_timestamp + SHORT_WHEEL_PERIOD_MS))
  {

    bucket = short_wheel_bucket(next_pop_time);
    bucket->insert(t);
  }
  else if (to_long_wheel_resolution(next_pop_time) <
           to_long_wheel_resolution(_tick_timestamp + LONG_WHEEL_PERIOD_MS))
  {
    bucket = long_wheel_bucket(next_pop_time);
    bucket->insert(t);
  }
  else
  {
    // Timer is too far in the future to be handled by the wheels, put it in
    // the extra heap.
    LOG_WARNING("Adding timer to extra heap, consider re-building with a larger "
                "LONG_WHEEL_NUM_BUCKETS constant");
    _extra_heap.push_back(t);
    std::push_heap(_extra_heap.begin(), _extra_heap.end());
  }

  // Finally, add the timer to the lookup table.
  _timer_lookup_table.insert(std::pair<TimerID, Timer*>(t->id, t));
}
Esempio n. 15
0
void destroy_sock(struct sock *sk)
{
	struct sk_buff *skb;

  	sk->inuse = 1;			/* just to be safe. */

  	/* In case it's sleeping somewhere. */
  	if (!sk->dead) 
  		sk->write_space(sk);

  	remove_sock(sk);
  
  	/* Now we can no longer get new packets. */
  	delete_timer(sk);
  	/* Nor send them */
	del_timer(&sk->retransmit_timer);
	
	while ((skb = tcp_dequeue_partial(sk)) != NULL) {
		IS_SKB(skb);
		kfree_skb(skb, FREE_WRITE);
	}

	/* Cleanup up the write buffer. */
  	while((skb = skb_dequeue(&sk->write_queue)) != NULL) {
		IS_SKB(skb);
		kfree_skb(skb, FREE_WRITE);
  	}
  	
  	/*
  	 *	Don't discard received data until the user side kills its
  	 *	half of the socket.
  	 */

	if (sk->dead) 
	{
  		while((skb=skb_dequeue(&sk->receive_queue))!=NULL) 
  		{
		/*
		 * This will take care of closing sockets that were
		 * listening and didn't accept everything.
		 */
			if (skb->sk != NULL && skb->sk != sk) 
			{
				IS_SKB(skb);
				skb->sk->dead = 1;
				skb->sk->prot->close(skb->sk, 0);
			}
			IS_SKB(skb);
			kfree_skb(skb, FREE_READ);
		}
	}	

	/* Now we need to clean up the send head. */
	cli();
	for(skb = sk->send_head; skb != NULL; )
	{
		struct sk_buff *skb2;

		/*
		 * We need to remove skb from the transmit queue,
		 * or maybe the arp queue.
		 */
		if (skb->next  && skb->prev) {
/*			printk("destroy_sock: unlinked skb\n");*/
			IS_SKB(skb);
			skb_unlink(skb);
		}
		skb->dev = NULL;
		skb2 = skb->link3;
		kfree_skb(skb, FREE_WRITE);
		skb = skb2;
	}
	sk->send_head = NULL;
	sti();

  	/* And now the backlog. */
  	while((skb=skb_dequeue(&sk->back_log))!=NULL) 
  	{
		/* this should never happen. */
/*		printk("cleaning back_log\n");*/
		kfree_skb(skb, FREE_READ);
	}

	/* Now if it has a half accepted/ closed socket. */
	if (sk->pair) 
	{
		sk->pair->dead = 1;
		sk->pair->prot->close(sk->pair, 0);
		sk->pair = NULL;
  	}

	/*
	 * Now if everything is gone we can free the socket
	 * structure, otherwise we need to keep it around until
	 * everything is gone.
	 */

	  if (sk->dead && sk->rmem_alloc == 0 && sk->wmem_alloc == 0) 
	  {
		kfree_s((void *)sk,sizeof(*sk));
	  } 
	  else 
	  {
		/* this should never happen. */
		/* actually it can if an ack has just been sent. */
		sk->destroy = 1;
		sk->ack_backlog = 0;
		sk->inuse = 0;
		reset_timer(sk, TIME_DESTROY, SOCK_DESTROY_TIME);
  	}
}