void game_mode_handler::tick(game_state* state) { current_session_state.time_elapsed += clk.getElapsedTime().asMicroseconds() / 1000.f; clk.restart(); if(game_over()) { ///just changed if(!in_game_over_state) { game_over_timer.restart(); printf("Round end\n"); } in_game_over_state = true; } ///we'd need to update all the client positions here if(in_game_over_state && game_over_timer.getElapsedTime().asSeconds() > game_data::game_over_time) { ///reset the session state current_session_state = session_state(); in_game_over_state = false; state->respawn_requests.clear(); printf("Round begin\n"); } }
/** * List all sessions in tabular form to a DCB * * Designed to be called within a debugger session in order * to display all active sessions within the gateway * * @param dcb The DCB to print to */ void dListSessions(DCB *dcb) { SESSION *list_session; spinlock_acquire(&session_spin); list_session = allSessions; if (list_session) { dcb_printf(dcb, "Sessions.\n"); dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); dcb_printf(dcb, "Session | Client | Service | State\n"); dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); } while (list_session) { dcb_printf(dcb, "%-16p | %-15s | %-14s | %s\n", list_session, ((list_session->client_dcb && list_session->client_dcb->remote) ? list_session->client_dcb->remote : ""), (list_session->service && list_session->service->name ? list_session->service->name : ""), session_state(list_session->state)); list_session = list_session->next; } if (allSessions) { dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n\n"); } spinlock_release(&session_spin); }
/** * List all sessions in tabular form to a DCB * * Designed to be called within a debugger session in order * to display all active sessions within the gateway * * @param dcb The DCB to print to */ void dListSessions(DCB *dcb) { SESSION *ptr; spinlock_acquire(&session_spin); ptr = allSessions; if (ptr) { dcb_printf(dcb, "Sessions.\n"); dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); dcb_printf(dcb, "Session | Client | Service | State\n"); dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n"); } while (ptr) { dcb_printf(dcb, "%-16p | %-15s | %-14s | %s\n", ptr, ((ptr->client && ptr->client->remote) ? ptr->client->remote : ""), (ptr->service && ptr->service->name ? ptr->service->name : ""), session_state(ptr->state)); ptr = ptr->next; } if (allSessions) dcb_printf(dcb, "-----------------+-----------------+----------------+--------------------------\n\n"); spinlock_release(&session_spin); }
/** * Print a particular session to a DCB * * Designed to be called within a debugger session in order * to display all active sessions within the gateway * * @param dcb The DCB to print to * @param ptr The session to print */ void dprintSession(DCB *dcb, SESSION *ptr) { int i; dcb_printf(dcb, "Session %p\n", ptr); dcb_printf(dcb, "\tState: %s\n", session_state(ptr->state)); dcb_printf(dcb, "\tService: %s (%p)\n", ptr->service->name, ptr->service); dcb_printf(dcb, "\tClient DCB: %p\n", ptr->client); if (ptr->client && ptr->client->remote) dcb_printf(dcb, "\tClient Address: %s\n", ptr->client->remote); dcb_printf(dcb, "\tConnected: %s", asctime(localtime(&ptr->stats.connect))); if (ptr->n_filters) { for (i = 0; i < ptr->n_filters; i++) { dcb_printf(dcb, "\tFilter: %s\n", ptr->filters[i].filter->name); ptr->filters[i].filter->obj->diagnostics( ptr->filters[i].instance, ptr->filters[i].session, dcb); } } }
/** * Print details of an individual session * * @param session Session to print */ void printSession(SESSION *session) { printf("Session %p\n", session); printf("\tState: %s\n", session_state(session->state)); printf("\tService: %s (%p)\n", session->service->name, session->service); printf("\tClient DCB: %p\n", session->client); printf("\tConnected: %s", asctime(localtime(&session->stats.connect))); }
/** * Write a session row for a session. this is called using the session * iterator function * * @param session The session to display * @param dcb The DCB to send the HTML to */ static void session_row(SESSION *session, DCB *dcb) { dcb_printf(dcb, "<TR><TD>%-16p</TD><TD>%s</TD><TD>%s</TD><TD>%s</TD></TR>\n", session, ((session->client && session->client->remote) ? session->client->remote : ""), (session->service && session->service->name ? session->service->name : ""), session_state(session->state)); }
/** * Provide a row to the result set that defines the set of sessions * * @param set The result set * @param data The index of the row to send * @return The next row or NULL */ static RESULT_ROW * sessionRowCallback(RESULTSET *set, void *data) { SESSIONFILTER *cbdata = (SESSIONFILTER *)data; int i = 0; char buf[20]; RESULT_ROW *row; SESSION *list_session; spinlock_acquire(&session_spin); list_session = allSessions; /* Skip to the first non-listener if not showing listeners */ while (list_session && cbdata->filter == SESSION_LIST_CONNECTION && list_session->state == SESSION_STATE_LISTENER) { list_session = list_session->next; } while (i < cbdata->index && list_session) { if (cbdata->filter == SESSION_LIST_CONNECTION && list_session->state != SESSION_STATE_LISTENER) { i++; } else if (cbdata->filter == SESSION_LIST_ALL) { i++; } list_session = list_session->next; } /* Skip to the next non-listener if not showing listeners */ while (list_session && cbdata->filter == SESSION_LIST_CONNECTION && list_session->state == SESSION_STATE_LISTENER) { list_session = list_session->next; } if (list_session == NULL) { spinlock_release(&session_spin); free(data); return NULL; } cbdata->index++; row = resultset_make_row(set); snprintf(buf,19, "%p", list_session); buf[19] = '\0'; resultset_row_set(row, 0, buf); resultset_row_set(row, 1, ((list_session->client_dcb && list_session->client_dcb->remote) ? list_session->client_dcb->remote : "")); resultset_row_set(row, 2, (list_session->service && list_session->service->name ? list_session->service->name : "")); resultset_row_set(row, 3, session_state(list_session->state)); spinlock_release(&session_spin); return row; }
/** * Print details of an individual session * * @param session Session to print */ void printSession(SESSION *session) { struct tm result; char timebuf[40]; printf("Session %p\n", session); printf("\tState: %s\n", session_state(session->state)); printf("\tService: %s (%p)\n", session->service->name, session->service); printf("\tClient DCB: %p\n", session->client_dcb); printf("\tConnected: %s", asctime_r(localtime_r(&session->stats.connect, &result), timebuf)); }
/** * Print all sessions to a DCB * * Designed to be called within a debugger session in order * to display all active sessions within the gateway * * @param dcb The DCB to print to */ void dprintAllSessions(DCB *dcb) { SESSION *ptr; spinlock_acquire(&session_spin); ptr = allSessions; while (ptr) { dcb_printf(dcb, "Session %p\n", ptr); dcb_printf(dcb, "\tState: %s\n", session_state(ptr->state)); dcb_printf(dcb, "\tService: %s (%p)\n", ptr->service->name, ptr->service); dcb_printf(dcb, "\tClient DCB: %p\n", ptr->client); if (ptr->client && ptr->client->remote) dcb_printf(dcb, "\tClient Address: %s\n", ptr->client->remote); dcb_printf(dcb, "\tConnected: %s", asctime(localtime(&ptr->stats.connect))); ptr = ptr->next; } spinlock_release(&session_spin); }
/** * Print a particular session to a DCB * * Designed to be called within a debugger session in order * to display all active sessions within the gateway * * @param dcb The DCB to print to * @param print_session The session to print */ void dprintSession(DCB *dcb, SESSION *print_session) { struct tm result; char buf[30]; int i; dcb_printf(dcb, "Session %d (%p)\n",print_session->ses_id, print_session); dcb_printf(dcb, "\tState: %s\n", session_state(print_session->state)); dcb_printf(dcb, "\tService: %s (%p)\n", print_session->service->name, print_session->service); dcb_printf(dcb, "\tClient DCB: %p\n", print_session->client_dcb); if (print_session->client_dcb && print_session->client_dcb->remote) { double idle = (hkheartbeat - print_session->client_dcb->last_read); idle = idle > 0 ? idle/10.f : 0; dcb_printf(dcb, "\tClient Address: %s%s%s\n", print_session->client_dcb->user?print_session->client_dcb->user:"", print_session->client_dcb->user?"@":"", print_session->client_dcb->remote); dcb_printf(dcb, "\tConnected: %s\n", asctime_r(localtime_r(&print_session->stats.connect, &result), buf)); if (print_session->client_dcb->state == DCB_STATE_POLLING) { dcb_printf(dcb, "\tIdle: %.0f seconds\n",idle); } } if (print_session->n_filters) { for (i = 0; i < print_session->n_filters; i++) { dcb_printf(dcb, "\tFilter: %s\n", print_session->filters[i].filter->name); print_session->filters[i].filter->obj->diagnostics(print_session->filters[i].instance, print_session->filters[i].session, dcb); } } }
/** * Print all sessions to a DCB * * Designed to be called within a debugger session in order * to display all active sessions within the gateway * * @param dcb The DCB to print to */ void dprintAllSessions(DCB *dcb) { struct tm result; char timebuf[40]; SESSION *list_session; spinlock_acquire(&session_spin); list_session = allSessions; while (list_session) { dcb_printf(dcb, "Session %d (%p)\n",list_session->ses_id, list_session); dcb_printf(dcb, "\tState: %s\n", session_state(list_session->state)); dcb_printf(dcb, "\tService: %s (%p)\n", list_session->service->name, list_session->service); dcb_printf(dcb, "\tClient DCB: %p\n", list_session->client_dcb); if (list_session->client_dcb && list_session->client_dcb->remote) { dcb_printf(dcb, "\tClient Address: %s%s%s\n", list_session->client_dcb->user?list_session->client_dcb->user:"", list_session->client_dcb->user?"@":"", list_session->client_dcb->remote); } dcb_printf(dcb, "\tConnected: %s", asctime_r(localtime_r(&list_session->stats.connect, &result), timebuf)); if (list_session->client_dcb && list_session->client_dcb->state == DCB_STATE_POLLING) { double idle = (hkheartbeat - list_session->client_dcb->last_read); idle = idle > 0 ? idle/10.0:0; dcb_printf(dcb, "\tIdle: %.0f seconds\n",idle); } list_session = list_session->next; } spinlock_release(&session_spin); }
static int stap_uprobe_change_plus (struct task_struct *tsk, unsigned long relocation, unsigned long length, const struct stap_uprobe_tf *stf, unsigned long offset, unsigned long vm_flags) { int tfi = (stf - stap_uprobe_finders); int spec_index; /* iterate over stap_uprobe_spec[] that use this same stap_uprobe_tf */ for (spec_index=0; spec_index<sizeof(stap_uprobe_specs)/sizeof(stap_uprobe_specs[0]); spec_index++) { int handled_p = 0; int slotted_p = 0; const struct stap_uprobe_spec *sups = &stap_uprobe_specs [spec_index]; struct stap_uprobe *sup; pid_t sdt_sem_pid; int rc = 0; int i; int pci; if (likely(sups->tfi != tfi)) continue; /* skip probes with an address beyond this map event; should not happen unless a shlib/exec got mmapped in weirdly piecemeal */ if (likely((vm_flags & VM_EXEC) && sups->address >= length)) continue; /* Found a uprobe_spec for this stap_uprobe_tf. Need to lock the stap_uprobes[] array to allocate a free spot, but then we can unlock and do the register_*probe subsequently. */ mutex_lock (& stap_uprobes_lock); for (i=0; i<MAXUPROBES; i++) { /* XXX: slow linear search */ sup = & stap_uprobes[i]; /* register new uprobe We make two passes for semaphores; see stap_uprobe_change_semaphore_plus */ if (sup->spec_index < 0 || (sups->sdt_sem_offset && vm_flags & VM_WRITE && sup->spec_index == spec_index)) { #if (UPROBES_API_VERSION < 2) /* See PR6829 comment. */ if (sup->spec_index == -1 && sup->up.kdata != NULL) continue; else if (sup->spec_index == -2 && sup->urp.u.kdata != NULL) continue; #endif sup->spec_index = spec_index; slotted_p = 1; break; } } mutex_unlock (& stap_uprobes_lock); #ifdef DEBUG_UPROBES _stp_dbug(__FUNCTION__,__LINE__, "+uprobe spec %d idx %d process %s[%d] addr %p pp %s\n", spec_index, (slotted_p ? i : -1), tsk->comm, tsk->tgid, (void*)(relocation+sups->address), sups->probe->pp); #endif /* NB: check for user-module build-id only if we have a pathname at all; for a process(PID#).* probe, we may not. If at some point we map process(PID#) to process("/proc/PID#/exe"), we'll get a pathname. */ if (stf->pathname) if ((rc = _stp_usermodule_check(tsk, stf->pathname, relocation))) return rc; /* Here, slotted_p implies that `i' points to the single stap_uprobes[] element that has been slotted in for registration or unregistration processing. !slotted_p implies that the table was full (registration; MAXUPROBES) or that no matching entry was found (unregistration; should not happen). */ sdt_sem_pid = (sups->return_p ? sup->urp.u.pid : sup->up.pid); if (sups->sdt_sem_offset && (sdt_sem_pid != tsk->tgid || sup->sdt_sem_address == 0)) { /* If the probe is in an ET_EXEC binary, then the sdt_sem_offset already * is a real address. But stap_uprobe_process_found calls us in this * case with relocation=offset=0, so we don't have to worry about it. */ sup->sdt_sem_address = (relocation - offset) + sups->sdt_sem_offset; } /* sdt_sem_offset */ for (pci=0; pci < sups->perf_counters_dim; pci++) { if ((sups->perf_counters)[pci] > -1) _stp_perf_read_init ((sups->perf_counters)[pci], tsk); } if (slotted_p) { struct stap_uprobe *sup = & stap_uprobes[i]; if (sups->return_p) { sup->urp.u.pid = tsk->tgid; sup->urp.u.vaddr = relocation + sups->address; sup->urp.handler = &enter_uretprobe_probe; rc = register_uretprobe (& sup->urp); } else { sup->up.pid = tsk->tgid; sup->up.vaddr = relocation + sups->address; sup->up.handler = &enter_uprobe_probe; rc = register_uprobe (& sup->up); } /* The u*probe failed to register. However, if we got EEXIST, * that means that the u*probe is already there, so just ignore * the error. This could happen if CLONE_THREAD or CLONE_VM was * used. */ if (rc != 0 && rc != -EEXIST) { _stp_warn ("u*probe failed %s[%d] '%s' addr %p rc %d\n", tsk->comm, tsk->tgid, sups->probe->pp, (void*)(relocation + sups->address), rc); /* NB: we need to release this slot, so we need to borrow the mutex temporarily. */ mutex_lock (& stap_uprobes_lock); sup->spec_index = -1; sup->sdt_sem_address = 0; mutex_unlock (& stap_uprobes_lock); } else { handled_p = 1; } } /* NB: handled_p implies slotted_p */ if (unlikely (! handled_p)) { #ifdef STP_TIMING atomic_inc (skipped_count_uprobe_reg()); #endif /* NB: duplicates common_entryfn_epilogue, but then this is not a probe entry fn epilogue. */ #ifndef STAP_SUPPRESS_HANDLER_ERRORS if (unlikely (atomic_inc_return (skipped_count()) > MAXSKIPPED)) { if (unlikely (pseudo_atomic_cmpxchg(session_state(), STAP_SESSION_RUNNING, STAP_SESSION_ERROR) == STAP_SESSION_RUNNING)) _stp_error ("Skipped too many probes, check MAXSKIPPED or try again with stap -t for more details."); } #endif } } /* close iteration over stap_uprobe_spec[] */ return 0; /* XXX: or rc? */ }