{
llentry_t *le;
- stop_read_threads ();
-
destroy_all_callbacks (&list_init);
+ stop_read_threads ();
+
pthread_mutex_lock (&read_lock);
llist_destroy (read_list);
read_list = NULL;
destroy_read_heap ();
+ /* blocks until all write threads have shut down. */
+ stop_write_threads ();
+
+ /* ask all plugins to write out the state they kept. */
plugin_flush (/* plugin = */ NULL,
/* timeout = */ 0,
/* identifier = */ NULL);
plugin_set_ctx (old_ctx);
}
- stop_write_threads ();
-
/* Write plugins which use the `user_data' pointer usually need the
* same data available to the flush callback. If this is the case, set
* the free_function to NULL when registering the flush callback and to
} /* }}} int network_dispatch_notification */
#if HAVE_LIBGCRYPT
-static void network_init_gcrypt (void) /* {{{ */
+static int network_init_gcrypt (void) /* {{{ */
{
gcry_error_t err;
* Because you can't know in a library whether another library has
* already initialized the library */
if (gcry_control (GCRYCTL_ANY_INITIALIZATION_P))
- return;
+ return (0);
/* http://www.gnupg.org/documentation/manuals/gcrypt/Multi_002dThreading.html
* To ensure thread-safety, it's important to set GCRYCTL_SET_THREAD_CBS
if (err)
{
ERROR ("network plugin: gcry_control (GCRYCTL_SET_THREAD_CBS) failed: %s", gcry_strerror (err));
- abort ();
+ return (-1);
}
# endif
if (err)
{
ERROR ("network plugin: gcry_control (GCRYCTL_INIT_SECMEM) failed: %s", gcry_strerror (err));
- abort ();
+ return (-1);
}
gcry_control (GCRYCTL_INITIALIZATION_FINISHED);
-} /* }}} void network_init_gcrypt */
+ return (0);
+} /* }}} int network_init_gcrypt */
static gcry_cipher_hd_t network_get_aes256_cypher (sockent_t *se, /* {{{ */
const void *iv, size_t iv_size, const char *username)
{
if (se->data.client.security_level > SECURITY_LEVEL_NONE)
{
- network_init_gcrypt ();
+ if (network_init_gcrypt () < 0)
+ {
+ ERROR ("network plugin: Cannot configure client socket with "
+ "security: Failed to initialize crypto library.");
+ return (-1);
+ }
if ((se->data.client.username == NULL)
|| (se->data.client.password == NULL))
{
if (se->data.server.security_level > SECURITY_LEVEL_NONE)
{
- network_init_gcrypt ();
+ if (network_init_gcrypt () < 0)
+ {
+ ERROR ("network plugin: Cannot configure server socket with "
+ "security: Failed to initialize crypto library.");
+ return (-1);
+ }
if (se->data.server.auth_file == NULL)
{
{
int status;
+ /* listen_loop is set to non-zero in the shutdown callback, which is
+ * guaranteed to be called *after* all the write threads have been shut
+ * down. */
+ assert (listen_loop == 0);
+
if (!check_send_okay (vl))
{
#if COLLECT_DEBUG
have_init = 1;
#if HAVE_LIBGCRYPT
- network_init_gcrypt ();
+ if (network_init_gcrypt () < 0)
+ {
+ ERROR ("network plugin: Failed to initialize crypto library.");
+ return (-1);
+ }
#endif
if (network_config_stats != 0)
for (i = 0; i < size; ++i) {
PyObject *item, *num;
item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
- if (ds->ds->type == DS_TYPE_COUNTER) {
+ switch (ds->ds[i].type) {
+ case DS_TYPE_COUNTER:
num = PyNumber_Long(item); /* New reference. */
if (num != NULL) {
value[i].counter = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_GAUGE) {
+ break;
+ case DS_TYPE_GAUGE:
num = PyNumber_Float(item); /* New reference. */
if (num != NULL) {
value[i].gauge = PyFloat_AsDouble(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_DERIVE) {
+ break;
+ case DS_TYPE_DERIVE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].derive = PyLong_AsLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+ break;
+ case DS_TYPE_ABSOLUTE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].absolute = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else {
+ break;
+ default:
free(value);
- PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+ PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
return NULL;
}
if (PyErr_Occurred() != NULL) {
for (i = 0; i < size; ++i) {
PyObject *item, *num;
item = PySequence_Fast_GET_ITEM(values, i); /* Borrowed reference. */
- if (ds->ds->type == DS_TYPE_COUNTER) {
+ switch (ds->ds[i].type) {
+ case DS_TYPE_COUNTER:
num = PyNumber_Long(item); /* New reference. */
if (num != NULL) {
value[i].counter = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_GAUGE) {
+ break;
+ case DS_TYPE_GAUGE:
num = PyNumber_Float(item); /* New reference. */
if (num != NULL) {
value[i].gauge = PyFloat_AsDouble(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_DERIVE) {
+ break;
+ case DS_TYPE_DERIVE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].derive = PyLong_AsLongLong(num);
Py_XDECREF(num);
}
- } else if (ds->ds->type == DS_TYPE_ABSOLUTE) {
+ break;
+ case DS_TYPE_ABSOLUTE:
/* This might overflow without raising an exception.
* Not much we can do about it */
num = PyNumber_Long(item); /* New reference. */
value[i].absolute = PyLong_AsUnsignedLongLong(num);
Py_XDECREF(num);
}
- } else {
+ break;
+ default:
free(value);
- PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds->type, value_list.type);
+ PyErr_Format(PyExc_RuntimeError, "unknown data type %d for %s", ds->ds[i].type, value_list.type);
return NULL;
}
if (PyErr_Occurred() != NULL) {