static void print_update (void) { int elapse; time_msec_t time_now; int reqs_sec = 0; int tx_sec = 0; time_now = get_time_msecs(); elapse = time_now - time_start; if ((elapse == 0) || ((request_done == 0) && (request_fails == 0))) { return; } reqs_sec = (int)(request_done / (elapse/1000.0f)); tx_sec = (int)(tx_total / (elapse/1000.0f)); printf ("threads %d, reqs %li (%d reqs/s avg), TX %llu (%d bytes/s avg), fails %li, %.2f secs\n", thread_num, request_done, reqs_sec, (long long unsigned) tx_total, tx_sec, request_fails, elapse/1000.0f); }
static void update_rate_limiter_timeout (GFileMonitor *monitor, guint new_time) { ForEachData data; GSource *source; if (monitor->priv->timeout_fires_at != 0 && new_time != 0 && time_difference (new_time, monitor->priv->timeout_fires_at) == 0) return; /* Nothing to do, we already fire earlier than that */ data.min_time = G_MAXUINT32; data.monitor = monitor; data.time_now = get_time_msecs (); g_hash_table_foreach_remove (monitor->priv->rate_limiter, foreach_rate_limiter_update, &data); /* Remove old timeout */ if (monitor->priv->timeout) { g_source_destroy (monitor->priv->timeout); g_source_unref (monitor->priv->timeout); monitor->priv->timeout_fires_at = 0; monitor->priv->timeout = NULL; } /* Set up new timeout */ if (data.min_time != G_MAXUINT32) { source = g_timeout_source_new (data.min_time + 1); /* + 1 to make sure we've really passed the time */ g_source_set_callback (source, rate_limiter_timeout, monitor, NULL); g_source_attach (source, monitor->priv->context); monitor->priv->timeout = source; monitor->priv->timeout_fires_at = data.time_now + data.min_time; } }
static gboolean rate_limiter_timeout (gpointer timeout_data) { GFileMonitor *monitor = timeout_data; ForEachData data; GSource *source; data.min_time = G_MAXUINT32; data.monitor = monitor; data.time_now = get_time_msecs (); g_hash_table_foreach_remove (monitor->priv->rate_limiter, foreach_rate_limiter_fire, &data); /* Remove old timeout */ if (monitor->priv->timeout) { g_source_destroy (monitor->priv->timeout); g_source_unref (monitor->priv->timeout); monitor->priv->timeout = NULL; monitor->priv->timeout_fires_at = 0; } /* Set up new timeout */ if (data.min_time != G_MAXUINT32) { source = g_timeout_source_new (data.min_time + 1); /* + 1 to make sure we've really passed the time */ g_source_set_callback (source, rate_limiter_timeout, monitor, NULL); g_source_attach (source, monitor->priv->context); monitor->priv->timeout = source; monitor->priv->timeout_fires_at = data.time_now + data.min_time; } return FALSE; }
static void * thread_routine (void *me) { int re; long http_code; double downloaded; CURLcode error; int is_error = 0; cb_thread_t *thread = (cb_thread_t *)me; cb_url_t *url = (cb_url_t *)urls.next; /* Wait until activated. Then, wait a sec until the rest of * the its peers are ready as well. */ pthread_mutex_lock (&thread->start_mutex); sleep(1); /* The first thread reads the time */ if (time_start == 0) { time_start = get_time_msecs(); } while (! finished) { time_msec_t requested_time; /* Configure curl, if needed */ if (thread->curl == NULL) { thread->curl = curl_easy_init(); curl_easy_setopt (thread->curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt (thread->curl, CURLOPT_WRITEFUNCTION, cb_write_data); curl_easy_setopt (thread->curl, CURLOPT_HEADERFUNCTION, cb_got_header); curl_easy_setopt (thread->curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); # if 0 curl_easy_setopt (thread->curl, CURLOPT_VERBOSE, 1); #endif } curl_easy_setopt (thread->curl, CURLOPT_URL, url->url.buf); /* Request it */ requested_time = get_time_msecs(); error = curl_easy_perform (thread->curl); switch (error) { case CURLE_OK: http_code = 0; downloaded = 0; curl_easy_getinfo (thread->curl, CURLINFO_RESPONSE_CODE, &http_code); curl_easy_getinfo (thread->curl, CURLINFO_SIZE_DOWNLOAD, &downloaded); re = count_response (http_code, downloaded); if (re != 0) { is_error = 1; request_fails++; } break; case CURLE_COULDNT_RESOLVE_HOST: finished = 1; is_error = 1; request_fails++; fprintf (stderr, "FATAL ERROR: %s\n", curl_easy_strerror(re)); break; default: is_error = 1; request_fails++; if (verbose) { fprintf (stderr, "ERROR: %s (elapsed %.2fs)\n", curl_easy_strerror(re), ((get_time_msecs() - requested_time)/1000.0f)); } } /* Prepare for the next request */ if ((! keepalive) || (is_error)) { curl_easy_cleanup (thread->curl); thread->curl = NULL; } url = (cb_url_t *)((url->entry.next == &urls) ? urls.next : url->entry.next); } return NULL; }
/** * g_file_monitor_emit_event: * @monitor: a #GFileMonitor. * @child: a #GFile. * @other_file: a #GFile. * @event_type: a set of #GFileMonitorEvent flags. * * Emits the #GFileMonitor::changed signal if a change * has taken place. Should be called from file monitor * implementations only. * * The signal will be emitted from an idle handler (in the <link * linkend="g-main-context-push-thread-default">thread-default main * context</link>). **/ void g_file_monitor_emit_event (GFileMonitor *monitor, GFile *child, GFile *other_file, GFileMonitorEvent event_type) { guint32 time_now, since_last; gboolean emit_now; RateLimiter *limiter; g_return_if_fail (G_IS_FILE_MONITOR (monitor)); g_return_if_fail (G_IS_FILE (child)); limiter = g_hash_table_lookup (monitor->priv->rate_limiter, child); if (event_type != G_FILE_MONITOR_EVENT_CHANGED) { if (limiter) { rate_limiter_send_delayed_change_now (monitor, limiter, get_time_msecs ()); if (event_type == G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT) limiter->send_virtual_changes_done_at = 0; else rate_limiter_send_virtual_changes_done_now (monitor, limiter); update_rate_limiter_timeout (monitor, 0); } emit_in_idle (monitor, child, other_file, event_type); } else { /* Changed event, rate limit */ time_now = get_time_msecs (); emit_now = TRUE; if (limiter) { since_last = time_difference (limiter->last_sent_change_time, time_now); if (since_last < monitor->priv->rate_limit_msec) { /* We ignore this change, but arm a timer so that we can fire it later if we don't get any other events (that kill this timeout) */ emit_now = FALSE; if (limiter->send_delayed_change_at == 0) { limiter->send_delayed_change_at = time_now + monitor->priv->rate_limit_msec; update_rate_limiter_timeout (monitor, limiter->send_delayed_change_at); } } } if (limiter == NULL) limiter = new_limiter (monitor, child); if (emit_now) { emit_in_idle (monitor, child, other_file, event_type); limiter->last_sent_change_time = time_now; limiter->send_delayed_change_at = 0; /* Set a timeout of 2*rate limit so that we can clear out the change from the hash eventualy */ update_rate_limiter_timeout (monitor, time_now + 2 * monitor->priv->rate_limit_msec); } /* Schedule a virtual change done. This is removed if we get a real one, and postponed if we get more change events. */ limiter->send_virtual_changes_done_at = time_now + DEFAULT_VIRTUAL_CHANGES_DONE_DELAY_SECS * 1000; update_rate_limiter_timeout (monitor, limiter->send_virtual_changes_done_at); } }