bool network_process_recvq(network_t * network) { probe_t * probe, * reply; packet_t * packet; probe_reply_t * probe_reply; // Pop the packet from the queue if (!(packet = queue_pop_element(network->recvq, NULL))) { goto ERR_PACKET_POP; } // Transform the reply into a probe_t instance if(!(reply = probe_wrap_packet(packet))) { goto ERR_PROBE_WRAP_PACKET; } probe_set_recv_time(reply, get_timestamp()); if (network->is_verbose) { printf("Got reply:\n"); probe_dump(reply); } // Find the probe corresponding to this reply // The corresponding pointer (if any) is removed from network->probes if (!(probe = network_get_matching_probe(network, reply))) { goto ERR_PROBE_DISCARDED; } // Build a pair made of the probe and its corresponding reply if (!(probe_reply = probe_reply_create())) { goto ERR_PROBE_REPLY_CREATE; } // We're pass to the upper layer the probe and the reply to the upper layer. probe_reply_set_probe(probe_reply, probe); probe_reply_set_reply(probe_reply, reply); // Notify the instance which has build the probe that we've got the corresponding reply // TODO this provokes a double free: //pt_throw(NULL, probe->caller, event_create(PROBE_REPLY, probe_reply, NULL, (ELEMENT_FREE) probe_reply_free)); pt_throw(NULL, probe->caller, event_create(PROBE_REPLY, probe_reply, NULL, NULL)); // TODO probe_reply_free frees only the reply but probe_reply_deep_free cannot be used as other things may have references to its contents. return true; ERR_PROBE_REPLY_CREATE: ERR_PROBE_DISCARDED: probe_free(reply); ERR_PROBE_WRAP_PACKET: //packet_free(packet); TODO provoke segfault in case of stars ERR_PACKET_POP: return false; }
void pt_stop_instance( struct pt_loop_s * loop, algorithm_instance_t * instance ) { // Notify the caller that this instance will be freed pt_throw(NULL, instance, event_create(ALGORITHM_TERM, NULL, NULL, NULL)); // Unregister this instance from the loop pt_algorithm_instance_del(loop, instance); // Free this instance algorithm_instance_free(instance); }
algorithm_instance_t * pt_add_instance( struct pt_loop_s * loop, const char * name, void * options, probe_t * probe_skel ) { bool probe_allocated = false; algorithm_t * algorithm; algorithm_instance_t * instance = NULL; if (!(algorithm = algorithm_search(name))) { goto ERR_ALGORITHM_NOT_FOUND; } // If the probe skeleton does not exist, create it. if (!probe_skel) { probe_skel = probe_create(); probe_allocated = (probe_skel != NULL); if (!probe_allocated) goto ERR_PROBE_SKEL; } // Create a new instance of a running algorithm if (!(instance = algorithm_instance_create(loop, algorithm, options, probe_skel))) { goto ERR_INSTANCE; } // We need to queue a new event for the algorithm: it has been started pt_throw(NULL, instance, event_create(ALGORITHM_INIT, NULL, NULL, NULL)); // Add this algorithms to the list of handled algorithms pt_algorithm_instance_add(loop, instance); return instance; ERR_INSTANCE: ERR_PROBE_SKEL: if (probe_allocated) probe_free(probe_skel); ERR_ALGORITHM_NOT_FOUND: return NULL; }
bool network_drop_expired_flying_probe(network_t * network) { // Drop every expired probes size_t i, num_flying_probes = dynarray_get_size(network->probes); bool ret = false; probe_t * probe; // Is there flying probe(s) ? if (num_flying_probes > 0) { // Iterate on each expired probes (at least the oldest one has expired) for (i = 0 ;i < num_flying_probes; i++) { probe = dynarray_get_ith_element(network->probes, i); // Some probe may expires very soon and may expire before the next probe timeout // update. If so, the timer will be disarmed and libparistraceroute may freeze. // To avoid this kind of deadlock, we provoke a probe timeout for each probe // expiring in less that EXTRA_DELAY seconds. if (network_get_probe_timeout(network, probe) - EXTRA_DELAY > 0) break; // This probe has expired, raise a PROBE_TIMEOUT event. pt_throw(NULL, probe->caller, event_create(PROBE_TIMEOUT, probe, NULL, NULL)); //(ELEMENT_FREE) probe_free)); } // Delete the i oldest probes, which have expired. if (i != 0) { dynarray_del_n_elements(network->probes, 0, i, NULL); } ret = network_update_next_timeout(network); } else { fprintf(stderr, "network_drop_expired_flying_probe: a probe has expired, but there are no more flying probes!\n"); } return ret; }