/*! * Main loop of the internet protocol service */ void serve_clients_internet_protocol (global_status_type * global_status, global_option_type * global_option) { int player_index; for (player_index = 0; player_index < MAX_NUMBER_PLAYER; player_index++) { global_status->next_frame_to_send[player_index] = 1; global_status->input_value[player_index] = 0; } /* Allocate memory for the history */ init_internet_history (); /* Prepare memory releasing at the end of the program */ atexit (release_internet_history); init_frame_status (global_status, global_option); global_status->start_time = (double) SDL_GetTicks () / (double) SDL_TICKS_PER_SECOND; for (;;) { #if defined(DEBUG) fprintf (stderr, "Waiting for status packets while preparing frame %u\ntime = %u\n", global_status->frame_number, SDL_GetTicks ()); #endif /* Let packets accumulate for a short amount of time */ SDL_Delay (get_remaining_time (global_status)); #if defined(DEBUG) fprintf (stderr, "Finished sleeping, time = %u\n", SDL_GetTicks ()); #endif while (read_incoming_server_packet (global_status) != 0) { #if defined(DEBUG) fprintf (stderr, "Got a packet\n"); #endif /* Stores the incoming status */ store_remote_status_internet (global_status, global_option); } send_internet_digest (global_status, global_option); } /* While the above loop is infinite, this won't be called */ release_internet_history (); }
void nbr_cache_auto_rem(void) { int i; for (i = 0; i < NBR_CACHE_SIZE; i++) { if (get_remaining_time(&(nbr_cache[i].ltime)) == 0 && nbr_cache[i].type == NBR_CACHE_TYPE_TEN) { memmove(&(nbr_cache[i]), &(nbr_cache[nbr_count]), sizeof(nbr_cache_t)); memset(&(nbr_cache[nbr_count]), 0, sizeof(nbr_cache_t)); nbr_count--; } } }
std::string timer_details::str() const { std::ostringstream oss; oss<<"[name:"<<_name<<"] "; oss<<"[state:"<<timer_details::str(_state)<<"] "; oss<<"[now:"<<boost::posix_time::to_simple_string(boost::posix_time::microsec_clock::local_time())<<"] "; oss<<"[starting_time:"<<boost::posix_time::to_simple_string(_starting_time)<<"] "; oss<<"[time_duration:"<<boost::posix_time::to_simple_string(_time_duration)<<"] "; oss<<"[remaining_time:"; if(_starting_time.is_not_a_date_time() || _time_duration.is_not_a_date_time()) oss<<"n/a"; else oss<<boost::posix_time::to_simple_string(get_remaining_time()); oss<<"] "; oss<<"[auto_reset:"<<base::formatting::to_string(_auto_reset)<<"] "; return oss.str(); }
static void* polling_thread(void*) { ENTER("polling_thread"); while(1) { int a_stop_is_required=0; SHOW_TIME("polling_thread > locking\n"); int a_status = pthread_mutex_lock(&my_mutex); SHOW_TIME("polling_thread > locked (my_event_is_running = 0)\n"); my_event_is_running = 0; pthread_mutex_unlock(&my_mutex); SHOW_TIME("polling_thread > unlocked\n"); SHOW_TIME("polling_thread > wait for my_sem_start_is_required\n"); while ((sem_wait(&my_sem_start_is_required) == -1) && errno == EINTR) { continue; // Restart when interrupted by handler } SHOW_TIME("polling_thread > get my_sem_start_is_required\n"); a_status = pthread_mutex_lock(&my_mutex); SHOW_TIME("polling_thread > locked (my_event_is_running = 1)\n"); my_event_is_running = 1; pthread_mutex_unlock(&my_mutex); SHOW_TIME("polling_thread > unlocked\n"); a_stop_is_required=0; a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required); // NOTE: may set a_stop_is_required to -1 if ((a_status==0) && (a_stop_is_required > 0)) { SHOW("polling_thread > stop required (%d)\n", __LINE__); while(0 == sem_trywait(&my_sem_stop_is_required)) { }; } else { a_stop_is_required=0; } // In this loop, my_event_is_running = 1 while (head && (a_stop_is_required <= 0)) { SHOW_TIME("polling_thread > check head\n"); while(0 == sem_trywait(&my_sem_start_is_required)) { }; espeak_EVENT* event = (espeak_EVENT*)(head->data); assert(event); uint32_t time_in_ms = 0; int err = get_remaining_time((uint32_t)event->sample, &time_in_ms, &a_stop_is_required); if (a_stop_is_required > 0) { break; } else if (err != 0) { // No available time: the event is deleted. SHOW("polling_thread > %s\n","audio device down"); a_status = pthread_mutex_lock(&my_mutex); SHOW_TIME("polling_thread > locked\n"); event_delete( (espeak_EVENT*)pop()); a_status = pthread_mutex_unlock(&my_mutex); SHOW_TIME("polling_thread > unlocked\n"); } else if (time_in_ms==0) { // the event is already reached. if (my_callback) { event_notify(event); // the user_data (and the type) are cleaned to be sure // that MSG_TERMINATED is called twice (at delete time too). event->type=espeakEVENT_LIST_TERMINATED; event->user_data=NULL; } a_status = pthread_mutex_lock(&my_mutex); SHOW_TIME("polling_thread > locked\n"); event_delete( (espeak_EVENT*)pop()); a_status = pthread_mutex_unlock(&my_mutex); SHOW_TIME("polling_thread > unlocked\n"); a_stop_is_required=0; a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required); if ((a_status==0) && (a_stop_is_required > 0)) { SHOW("polling_thread > stop required (%d)\n", __LINE__); while(0 == sem_trywait(&my_sem_stop_is_required)) { }; } else { a_stop_is_required=0; } } else { // The event will be notified soon: sleep until timeout or stop request a_stop_is_required = sleep_until_timeout_or_stop_request(time_in_ms); } } a_status = pthread_mutex_lock(&my_mutex); SHOW_TIME("polling_thread > locked\n"); SHOW_TIME("polling_thread > my_event_is_running = 0\n"); my_event_is_running = 0; if(a_stop_is_required <= 0) { a_status = sem_getvalue(&my_sem_stop_is_required, &a_stop_is_required); if ((a_status==0) && (a_stop_is_required > 0)) { SHOW("polling_thread > stop required (%d)\n", __LINE__); while(0 == sem_trywait(&my_sem_stop_is_required)) { }; } else { a_stop_is_required=0; } } a_status = pthread_mutex_unlock(&my_mutex); SHOW_TIME("polling_thread > unlocked\n"); if (a_stop_is_required > 0) { SHOW("polling_thread > %s\n","stop required!"); // no mutex required since the stop command is synchronous // and waiting for my_sem_stop_is_acknowledged init(); // acknowledge the stop request SHOW_TIME("polling_thread > post my_sem_stop_is_acknowledged\n"); a_status = sem_post(&my_sem_stop_is_acknowledged); } } return NULL; }
void recv_rtr_adv(void) { int8_t trigger_ns = -1; int8_t abro_found = 0; int16_t abro_version = 0; /* later replaced, just to supress warnings */ ipv6_addr_t abro_addr; ipv6_buf = get_ipv6_buf(); opt_hdr_len = RTR_ADV_LEN; rtr_adv_buf = get_rtr_adv_buf(ipv6_ext_hdr_len); ipv6_addr_t newaddr; recvd_cids_len = 0; /* update interface reachable time and retrans timer */ if (rtr_adv_buf->reachable_time != 0) { iface.adv_reachable_time = HTONL(rtr_adv_buf->reachable_time); } if (rtr_adv_buf->retrans_timer != 0) { iface.adv_retrans_timer = HTONL(rtr_adv_buf->retrans_timer); } def_rtr_entry = def_rtr_lst_search(&ipv6_buf->srcaddr); if (rtr_adv_buf->router_lifetime != 0) { if (def_rtr_entry != NULL) { set_remaining_time(&(def_rtr_entry->inval_time), HTONL(rtr_adv_buf->router_lifetime)); } else { def_rtr_lst_add(&(ipv6_buf->srcaddr), HTONL(rtr_adv_buf->router_lifetime)); trigger_ns = 1; } } else { /* remove router from default router list */ if (def_rtr_entry != NULL) { def_rtr_lst_rem(def_rtr_entry); } } mutex_lock(&lowpan_context_mutex); /* read options */ while (packet_length > IPV6HDR_ICMPV6HDR_LEN + opt_hdr_len) { opt_buf = get_opt_buf(ipv6_ext_hdr_len, opt_hdr_len); switch(opt_buf->type) { case (OPT_SLLAO_TYPE): { break; } case (OPT_MTU_TYPE): { break; } /* rfc 4862 section 5.5.3 */ case (OPT_PI_TYPE): { opt_pi_buf = get_opt_pi_buf(ipv6_ext_hdr_len, opt_hdr_len); /* crazy condition, read 5.5.3a-b-c for further information */ if (ipv6_prefix_ll_match(&opt_pi_buf->addr) || (HTONL(opt_pi_buf->pref_ltime) > HTONL(opt_pi_buf->val_ltime))) { break; } else { /* check if on-link flag is set */ if (opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_L) { /* TODO: do on-link pi handling */ } if (opt_pi_buf->l_a_reserved1 & OPT_PI_FLAG_A) { addr_list_ptr = ipv6_iface_addr_prefix_eq(&opt_pi_buf->addr); if (addr_list_ptr == NULL) { /* 5.5.3d */ if (opt_pi_buf->val_ltime != 0) { /* iid will also be added here */ ipv6_init_addr_prefix(&newaddr, &opt_pi_buf->addr); /* add into address list * TODO: duplicate address detection is not * implementet yet, so all new addresse will * be added with state PREFFERED */ ipv6_iface_add_addr(&newaddr, ADDR_STATE_PREFERRED, opt_pi_buf->val_ltime, opt_pi_buf->pref_ltime, ADDR_CONFIGURED_AUTO); printf("INFO: added address to interface\n"); trigger_ns = 1; } } else { /* 5.5.3e */ set_remaining_time(&(addr_list_ptr->pref_ltime), opt_pi_buf->pref_ltime); /* 7200 = 2hours in seconds */ if (HTONL(opt_pi_buf->val_ltime) > 7200 || HTONL(opt_pi_buf->val_ltime) > get_remaining_time(&(addr_list_ptr->val_ltime))) { set_remaining_time(&(addr_list_ptr->val_ltime), HTONL(opt_pi_buf->val_ltime)); } else { /* reset valid lifetime to 2 hours */ set_remaining_time(&(addr_list_ptr->val_ltime), 7200); } } } } /* TODO: save found prefixes */ break; } case (OPT_6CO_TYPE): { uint8_t comp; uint8_t num; opt_6co_hdr_buf = get_opt_6co_hdr_buf(ipv6_ext_hdr_len, opt_hdr_len); get_opt_6co_flags(&comp, &num, opt_6co_hdr_buf->c_flags); ipv6_addr_t prefix; memset(&prefix, 0, 16); opt_6co_prefix_buf = get_opt_6co_prefix_buf(ipv6_ext_hdr_len, opt_hdr_len + OPT_6CO_HDR_LEN); memcpy(&prefix, opt_6co_prefix_buf, opt_6co_hdr_buf->c_length); lowpan_context_update( num, &prefix, opt_6co_hdr_buf->c_length, comp, HTONS(opt_6co_hdr_buf->val_ltime) ); recvd_cids[recvd_cids_len] = num; recvd_cids_len = (recvd_cids_len + 1) % LOWPAN_CONTEXT_MAX; break; } case (OPT_ABRO_TYPE): { opt_abro_buf = get_opt_abro_buf(ipv6_ext_hdr_len, opt_hdr_len); abro_found = 1; abro_version = HTONS(opt_abro_buf->version); memcpy(&(abro_addr), &(opt_abro_buf->addr), sizeof(ipv6_addr_t)); break; } default: break; } /* multiplied with 8 because options length is in units of 8 bytes */ opt_hdr_len += (opt_buf->length * 8); } if (abro_found) { int i; for (i = 0; i < recvd_cids_len; i++) { abr_add_context(abro_version, &abro_addr, recvd_cids[i]); } } mutex_unlock(&lowpan_context_mutex, 0); if (trigger_ns >= 0) { /* send ns - draft-ietf-6lowpan-nd-15#section-5.5.1 * * section-10.2.4 * "Next the 6LN registers that address with one or more of its * default routers by sending a unicast NS message with an ARO * containing its tentative global IPv6 address to register * * if new address was configured, set src to newaddr(gp16) */ init_nbr_sol(&newaddr, &(ipv6_buf->srcaddr), &(ipv6_buf->srcaddr), OPT_SLLAO, OPT_ARO); #if ENABLE_DEBUG printf("INFO: send neighbor solicitation to: "); ipv6_print_addr(&(ipv6_buf->destaddr)); #endif lowpan_init((ieee_802154_long_t *) & (ipv6_buf->destaddr.uint16[4]), (uint8_t *)ipv6_buf); } }