[collectd] [PATCH] perl plugin: Shut down an ithread if the embedding pthread terminates.
Sebastian Harl
sh at tokkee.org
Tue Nov 20 08:48:12 CET 2007
Each ithread object is registered as thread specific data along with a
destructor function. If the embedding pthread terminates the destructor is
called which takes care of cleanly shutting down the appropriate Perl
interpreter and freeing any related resources.
Signed-off-by: Sebastian Harl <sh at tokkee.org>
---
src/perl.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++----------
1 files changed, 76 insertions(+), 15 deletions(-)
diff --git a/src/perl.c b/src/perl.c
index 5cec1ed..b289fa0 100644
--- a/src/perl.c
+++ b/src/perl.c
@@ -112,6 +112,9 @@ typedef struct {
* point to the "base" thread */
static c_ithread_list_t *perl_threads = NULL;
+/* the key used to store each pthread's ithread */
+static pthread_key_t perl_thr_key;
+
static int perl_argc = 0;
static char **perl_argv = NULL;
@@ -776,6 +779,63 @@ static XS (Collectd_call_by_name)
*/
/* must be called with perl_threads->mutex locked */
+static void c_ithread_destroy (c_ithread_t *ithread)
+{
+ dTHXa (ithread->interp);
+
+ assert (NULL != perl_threads);
+
+ PERL_SET_CONTEXT (aTHX);
+ log_debug ("Shutting down Perl interpreter %p...", aTHX);
+
+#if COLLECT_DEBUG
+ sv_report_used ();
+
+ --perl_threads->number_of_threads;
+#endif /* COLLECT_DEBUG */
+
+ perl_destruct (aTHX);
+ perl_free (aTHX);
+
+ if (NULL == ithread->prev)
+ perl_threads->head = ithread->next;
+ else
+ ithread->prev->next = ithread->next;
+
+ if (NULL == ithread->next)
+ perl_threads->tail = ithread->prev;
+ else
+ ithread->next->prev = ithread->prev;
+
+ sfree (ithread);
+ return;
+} /* static void c_ithread_destroy (c_ithread_t *) */
+
+static void c_ithread_destructor (void *arg)
+{
+ c_ithread_t *ithread = (c_ithread_t *)arg;
+ c_ithread_t *t = NULL;
+
+ if (NULL == perl_threads)
+ return;
+
+ pthread_mutex_lock (&perl_threads->mutex);
+
+ for (t = perl_threads->head; NULL != t; t = t->next)
+ if (t == ithread)
+ break;
+
+ /* the ithread no longer exists */
+ if (NULL == t)
+ return;
+
+ c_ithread_destroy (ithread);
+
+ pthread_mutex_unlock (&perl_threads->mutex);
+ return;
+} /* static void c_ithread_destructor (void *) */
+
+/* must be called with perl_threads->mutex locked */
static c_ithread_t *c_ithread_create (PerlInterpreter *base)
{
c_ithread_t *t = NULL;
@@ -814,6 +874,8 @@ static c_ithread_t *c_ithread_create (PerlInterpreter *base)
}
perl_threads->tail = t;
+
+ pthread_setspecific (perl_thr_key, (const void *)t);
return t;
} /* static c_ithread_t *c_ithread_create (PerlInterpreter *) */
@@ -945,30 +1007,22 @@ static int perl_shutdown (void)
t = perl_threads->tail;
while (NULL != t) {
- c_ithread_t *last = NULL;
+ c_ithread_t *thr = t;
- aTHX = t->interp;
- PERL_SET_CONTEXT (aTHX);
-
- log_debug ("Shutting down Perl interpreter %p...", aTHX);
-
-#if COLLECT_DEBUG
- sv_report_used ();
-#endif /* COLLECT_DEBUG */
-
- perl_destruct (aTHX);
- perl_free (aTHX);
-
- last = t;
+ /* the pointer has to be advanced before destroying
+ * the thread as this will free the memory */
t = t->prev;
- sfree (last);
+ c_ithread_destroy (thr);
}
pthread_mutex_unlock (&perl_threads->mutex);
+ pthread_mutex_destroy (&perl_threads->mutex);
sfree (perl_threads);
+ pthread_key_delete (perl_thr_key);
+
PERL_SYS_TERM ();
plugin_unregister_shutdown ("perl");
@@ -1018,6 +1072,13 @@ static int init_pi (int argc, char **argv)
}
#endif /* COLLECT_DEBUG */
+ if (0 != pthread_key_create (&perl_thr_key, c_ithread_destructor)) {
+ log_err ("init_pi: pthread_key_create failed");
+
+ /* this must not happen - cowardly giving up if it does */
+ exit (1);
+ }
+
PERL_SYS_INIT3 (&argc, &argv, &environ);
perl_threads = (c_ithread_list_t *)smalloc (sizeof (c_ithread_list_t));
--
1.5.3.4
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mailman.verplant.org/pipermail/collectd/attachments/20071120/f951c298/attachment.pgp
More information about the collectd
mailing list