Exemple #1
0
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);
}
Exemple #2
0
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; 
    }
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #5
0
/**
 * 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);
    }
}