- hostlist_t *hl_this;
- hostlist_t *hl_prev;
-
- hl_this = hosts;
- hl_prev = NULL;
- while (hl_this != NULL)
- {
- DEBUG ("ping plugin: host = %s, wait_left = %i, "
- "wait_time = %i, next = %p",
- hl_this->host, hl_this->wait_left,
- hl_this->wait_time, (void *) hl_this->next);
-
- if (hl_this->wait_left <= 0)
- {
- if (ping_host_add (pingobj, hl_this->host) == 0)
- {
- DEBUG ("ping plugin: Successfully added host %s", hl_this->host);
- /* Remove the host from the linked list */
- if (hl_prev != NULL)
- hl_prev->next = hl_this->next;
- else
- hosts = hl_this->next;
- free (hl_this->host);
- free (hl_this);
- hl_this = (hl_prev != NULL) ? hl_prev : hosts;
- }
- else
- {
- WARNING ("ping plugin: Failed adding host "
- "`%s': %s", hl_this->host,
- ping_get_error (pingobj));
- hl_this->wait_left = hl_this->wait_time;
- hl_this->wait_time *= 2;
- if (hl_this->wait_time > 86400)
- hl_this->wait_time = 86400;
- }
- }
- else
- {
- hl_this->wait_left -= interval_g;
- }
-
- if (hl_this != NULL)
- {
- hl_prev = hl_this;
- hl_this = hl_this->next;
- }
- }
-} /* void add_hosts */
-
-static int ping_init (void)
+ 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) /* {{{ */