+ static pingobj_t *pingobj = NULL;
+
+ struct timeval tv_begin;
+ struct timeval tv_end;
+ struct timespec ts_wait;
+ struct timespec ts_int;
+
+ hostlist_t *hl;
+ int status;
+
+ pthread_mutex_lock (&ping_lock);
+
+ pingobj = ping_construct ();
+ if (pingobj == NULL)
+ {
+ ERROR ("ping plugin: ping_construct failed.");
+ ping_thread_error = 1;
+ pthread_mutex_unlock (&ping_lock);
+ return ((void *) -1);
+ }
+
+ ping_setopt (pingobj, PING_OPT_TIMEOUT, (void *) &ping_timeout);
+ ping_setopt (pingobj, PING_OPT_TTL, (void *) &ping_ttl);
+
+ /* Add all the hosts to the ping object. */
+ status = 0;
+ for (hl = hostlist_head; hl != NULL; hl = hl->next)
+ {
+ int tmp_status;
+ tmp_status = ping_host_add (pingobj, hl->host);
+ if (tmp_status != 0)
+ WARNING ("ping plugin: ping_host_add (%s) failed.", hl->host);
+ else
+ status++;
+ }
+
+ if (status == 0)
+ {
+ ERROR ("ping plugin: No host could be added to ping object. Giving up.");
+ ping_thread_error = 1;
+ pthread_mutex_unlock (&ping_lock);
+ return ((void *) -1);
+ }
+
+ /* Set up `ts_int' */
+ {
+ double temp_sec;
+ double temp_nsec;
+
+ temp_nsec = modf (ping_interval, &temp_sec);
+ ts_int.tv_sec = (time_t) temp_sec;
+ ts_int.tv_nsec = (long) (temp_nsec * 1000000000L);
+ }
+
+ while (ping_thread_loop > 0)
+ {
+ pingobj_iter_t *iter;
+ int status;
+
+ if (gettimeofday (&tv_begin, NULL) < 0)
+ {
+ ERROR ("ping plugin: gettimeofday failed");
+ ping_thread_error = 1;
+ break;
+ }
+
+ pthread_mutex_unlock (&ping_lock);
+
+ status = ping_send (pingobj);
+ if (status < 0)
+ {
+ ERROR ("ping plugin: ping_send failed: %s", ping_get_error (pingobj));
+ pthread_mutex_lock (&ping_lock);
+ ping_thread_error = 1;
+ break;
+ }
+
+ pthread_mutex_lock (&ping_lock);
+
+ if (ping_thread_loop <= 0)
+ break;
+
+ for (iter = ping_iterator_get (pingobj);
+ iter != NULL;
+ iter = ping_iterator_next (iter))
+ { /* {{{ */
+ char userhost[NI_MAXHOST];
+ double latency;
+ size_t param_size;
+
+ param_size = sizeof (userhost);
+ status = ping_iterator_get_info (iter,
+#ifdef PING_INFO_USERNAME
+ PING_INFO_USERNAME,
+#else
+ PING_INFO_HOSTNAME,
+#endif
+ userhost, ¶m_size);
+ if (status != 0)
+ {
+ WARNING ("ping plugin: ping_iterator_get_info failed: %s",
+ ping_get_error (pingobj));
+ continue;
+ }
+
+ for (hl = hostlist_head; hl != NULL; hl = hl->next)
+ if (strcmp (userhost, hl->host) == 0)
+ break;
+
+ if (hl == NULL)
+ {
+ WARNING ("ping plugin: Cannot find host %s.", userhost);
+ continue;
+ }
+
+ param_size = sizeof (latency);
+ status = ping_iterator_get_info (iter, PING_INFO_LATENCY,
+ (void *) &latency, ¶m_size);
+ if (status != 0)
+ {
+ WARNING ("ping plugin: ping_iterator_get_info failed: %s",
+ ping_get_error (pingobj));
+ continue;
+ }
+
+ hl->pkg_sent++;
+ if (latency >= 0.0)
+ {
+ hl->pkg_recv++;
+ hl->latency_total += latency;
+ hl->latency_squared += (latency * latency);
+ }
+ } /* }}} for (iter) */
+
+ if (gettimeofday (&tv_end, NULL) < 0)
+ {
+ ERROR ("ping plugin: gettimeofday failed");
+ ping_thread_error = 1;
+ break;
+ }
+
+ /* Calculate the absolute time until which to wait and store it in
+ * `ts_wait'. */
+ time_calc (&ts_wait, &ts_int, &tv_begin, &tv_end);
+
+ status = pthread_cond_timedwait (&ping_cond, &ping_lock, &ts_wait);
+ if (ping_thread_loop <= 0)
+ break;
+ } /* while (ping_thread_loop > 0) */
+
+ pthread_mutex_unlock (&ping_lock);
+ ping_destroy (pingobj);
+
+ return ((void *) 0);
+} /* }}} void *ping_thread */
+
+static int start_thread (void) /* {{{ */
+{
+ int status;
+
+ pthread_mutex_lock (&ping_lock);
+
+ if (ping_thread_loop != 0)
+ {
+ pthread_mutex_unlock (&ping_lock);
+ return (-1);
+ }
+
+ ping_thread_loop = 1;
+ ping_thread_error = 0;
+ status = pthread_create (&ping_thread_id, /* attr = */ NULL,
+ ping_thread, /* arg = */ (void *) 0);
+ if (status != 0)
+ {
+ ping_thread_loop = 0;
+ ERROR ("ping plugin: Starting thread failed.");
+ pthread_mutex_unlock (&ping_lock);
+ return (-1);
+ }
+
+ pthread_mutex_unlock (&ping_lock);
+ return (0);
+} /* }}} int start_thread */
+
+static int stop_thread (void) /* {{{ */
+{
+ int status;
+
+ pthread_mutex_lock (&ping_lock);