no longer deliberately leak the first context object
authorTony Cook <tony@develop-help.com>
Wed, 9 Mar 2016 10:02:15 +0000 (21:02 +1100)
committerTony Cook <tony@develop-help.com>
Wed, 9 Mar 2016 10:02:15 +0000 (21:02 +1100)
Previously Imager would deliberately leak the context object from
the start thread to ensure there was always at least one context
object available.

Modified the log code to handle there being no context object.

Imager.xs
log.c

index 85f6224..5919d11 100644 (file)
--- a/Imager.xs
+++ b/Imager.xs
@@ -52,22 +52,11 @@ typedef struct {
 
 START_MY_CXT
 
-im_context_t fallback_context;
-
 static void
 start_context(pTHX) {
   dMY_CXT;
   MY_CXT.ctx = im_context_new();
   sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", MY_CXT.ctx);
-
-  /* Ideally we'd free this reference, but the error message memory
-     was never released on exit, so the associated memory here is reasonable
-     to keep.
-     With logging enabled we always need at least one context, since
-     objects may be released fairly late and attempt to get the log file.
-  */
-  im_context_refinc(MY_CXT.ctx, "start_context");
-  fallback_context = MY_CXT.ctx;
 }
 
 static im_context_t
@@ -75,7 +64,7 @@ perl_get_context(void) {
   dTHX;
   dMY_CXT;
   
-  return MY_CXT.ctx ? MY_CXT.ctx : fallback_context;
+  return MY_CXT.ctx;
 }
 
 #else
@@ -85,7 +74,9 @@ static im_context_t perl_context;
 static void
 start_context(pTHX) {
   perl_context = im_context_new();
-  im_context_refinc(perl_context, "start_context");
+
+  /* just so it gets destroyed */
+  sv_setref_pv(get_sv("Imager::_context", GV_ADD), "Imager::Context", perl_context);
 }
 
 static im_context_t
diff --git a/log.c b/log.c
index 62b8eab..efc604c 100644 (file)
--- a/log.c
+++ b/log.c
@@ -99,7 +99,7 @@ im_vloog(pIMCTX, int level, const char *fmt, va_list ap) {
   struct tm *str_tm;
   char date_buffer[DTBUFF];
 
-  if (!aIMCTX->lg_file || level > aIMCTX->log_level)
+  if (!aIMCTX || !aIMCTX->lg_file || level > aIMCTX->log_level)
     return;
 
   i_mutex_lock(log_mutex);
@@ -120,7 +120,7 @@ i_loog(int level,const char *fmt, ... ) {
   dIMCTX;
   va_list ap;
 
-  if (!aIMCTX->lg_file || level > aIMCTX->log_level)
+  if (!aIMCTX || !aIMCTX->lg_file || level > aIMCTX->log_level)
     return;
 
   va_start(ap,fmt);
@@ -132,7 +132,7 @@ void
 im_loog(pIMCTX, int level,const char *fmt, ... ) {
   va_list ap;
 
-  if (!aIMCTX->lg_file || level > aIMCTX->log_level)
+  if (!aIMCTX || !aIMCTX->lg_file || level > aIMCTX->log_level)
     return;
 
   va_start(ap,fmt);
@@ -151,7 +151,7 @@ This is an internal function called by the mm_log() macro.
 
 void
 im_lhead(pIMCTX, const char *file, int line) {
-  if (aIMCTX->lg_file != NULL) {
+  if (aIMCTX && aIMCTX->lg_file != NULL) {
     aIMCTX->filename = file;
     aIMCTX->line = line;
   }