Index: /test/regfi-threadtest.c
===================================================================
--- /test/regfi-threadtest.c	(revision 184)
+++ /test/regfi-threadtest.c	(revision 185)
@@ -49,5 +49,5 @@
 void traverseValueList(REGFI_ITERATOR* iter)
 {
-  REGFI_VK_REC* value;
+  const REGFI_VK_REC* value;
 
   value = regfi_iterator_first_value(iter);
@@ -55,5 +55,5 @@
   {
     printMsgs(iter->f);
-    regfi_free_value(value);
+    regfi_free_record(value);
     value = regfi_iterator_next_value(iter);
   }
@@ -65,5 +65,5 @@
   const REGFI_NK_REC* root = NULL;
   const REGFI_NK_REC* cur = NULL;
-  REGFI_NK_REC* sub = NULL;
+  const REGFI_NK_REC* sub = NULL;
   const REGFI_SK_REC* sk;
   bool print_this = true;
@@ -116,5 +116,5 @@
       cur = regfi_iterator_cur_key(iter);
       printMsgs(iter->f);
-      regfi_free_key(sub);
+      regfi_free_record(sub);
 
       sub = regfi_iterator_first_subkey(iter);
@@ -131,9 +131,11 @@
 
 int num_iterations;
-void threadLoop(void* file)
+void* threadLoop(void* file)
 {
   REGFI_ITERATOR* iter;
   int i;
 
+  regfi_log_set_mask(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR);
+
   iter = regfi_iterator_new((REGFI_FILE*)f, REGFI_ENCODING_ASCII);
   if(iter == NULL)
@@ -150,4 +152,6 @@
 
   regfi_iterator_free(iter);
+
+  return NULL;
 }
 
@@ -185,5 +189,5 @@
   registry_file = argv[argi];
 
-  regfi_log_start(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR);
+  regfi_log_set_mask(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR);
 
   fd = openHive(registry_file);
@@ -211,5 +215,4 @@
 
   regfi_free(f);
-  regfi_log_stop();
   close(fd);
 
Index: /trunk/include/regfi.h
===================================================================
--- /trunk/include/regfi.h	(revision 184)
+++ /trunk/include/regfi.h	(revision 185)
@@ -48,5 +48,5 @@
  *
  * Most users will find that a combination of the Base Layer and the Iterator Layer 
- * will be sufficient for accessing registry hive files.  Those who are wiling
+ * will be sufficient for accessing registry hive files.  Those who are willing
  * to dive deep into registry data structures, for instance to recover deleted
  * data structures or to research Windows registry behavior in detail, will 
@@ -79,4 +79,6 @@
 
 
+
+
 /******************************************************************************/
 /* Constants for use while interacting with the library                       */
@@ -87,4 +89,5 @@
 #define REGFI_LOG_WARN  0x0004
 #define REGFI_LOG_ERROR 0x0010
+#define REGFI_DEFAULT_LOG_MASK REGFI_LOG_ERROR|REGFI_LOG_WARN
 
 typedef uint8_t REGFI_ENCODING;
@@ -146,5 +149,5 @@
 
 /* Global thread-local storage key */
-pthread_key_t REGFI_LOG_KEY;
+pthread_key_t regfi_log_key;
 
 /* Header sizes and magic number lengths for various records */
@@ -877,13 +880,4 @@
 
 
-/** Enables regfi library logging for the current thread.
- *
- * XXX: finish documenting
- *
- * @ingroup regfiBase
- */
-void regfi_log_start(uint16_t mask);
-
-
 /** Get errors, warnings, and/or verbose information relating to processing of
  *  the given registry file.
@@ -896,34 +890,31 @@
 
 
-/** Set the verbosity level of errors and warnings generated by the library
- *  (as accessible via regfi_get_messages).
- *
- * This may be called at any time and will take effect immediately.
- *
- * @param mask   an integer representing the types of messages desired.
+/** Set the verbosity level of messages generated by the library for the 
+ *  current thread.
+ *
+ * @param mask   An integer representing the types of messages desired.
  *               Acceptable values are created through bitwise ORs of 
- *               REGFI_MSG_* values.  For instance, if only errors and
+ *               REGFI_LOG_* values.  For instance, if only errors and
  *               informational messages were desired (but not warnings),
- *               then one would specify: REGFI_MSG_ERROR|REGFI_MSG_INFO
- *               New REGFI_FILE structures are created with:
- *                REGFI_MSG_ERROR|REGFI_MSG_WARN
- *               Note that error and warning messages will continue to
- *               accumulate in memory if they are not fetched using
- *               regfi_get_messages and then freed by the caller.
- *               To disable error messages entirely, supply 0, which
- *               will prevent message accumulation.  
+ *               then one would specify: REGFI_LOG_ERROR|REGFI_LOG_INFO
+ *               By default the message mask is: REGFI_LOG_ERROR|REGFI_LOG_WARN.
+ *
+ * @return       true on success and false on failure.  Failure occurs if 
+ *               underlying pthread functions fail.  errno is set in this case.
+ *
+ * Message masks are set in a thread-specific way.  If one were to set a message
+ * mask in one thread and then spawn a new thread, then the new thread will have
+ * it's message mask reset to the default.  This function may be called at any 
+ * time and will take effect immediately for the current thread.
+ *
+ * @note When a non-zero message mask is set, messages will
+ *       accumulate in memory without limit if they are not fetched using
+ *       @ref regfi_get_log_str and subsequently freed by the caller.  It is
+ *       recommended that messsages be fetched after each regfi API call in
+ *       order to provide the most context.
  *
  * @ingroup regfiBase
  */
-void regfi_log_set_mask(uint16_t mask);
-
-
-/** Disables regfi library logging for the current thread.
- *
- * XXX: finish documenting
- *
- * @ingroup regfiBase
- */
-void regfi_log_stop();
+bool regfi_log_set_mask(uint16_t mask);
 
 
@@ -1077,5 +1068,5 @@
  *         subkey, or NULL on failure.  Failure may be due to a lack of any
  *         subkeys or other errors.  Newly allocated keys must be freed with
- *         regfi_free_record.
+ *         @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
@@ -1090,5 +1081,5 @@
  * @return A newly allocated key structure for the currently referenced subkey,
  *         or NULL on failure.  Newly allocated keys must be freed with 
- *         regfi_free_record.
+ *         @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
@@ -1103,5 +1094,6 @@
  *
  * @return A newly allocated key structure for the next subkey or NULL on
- *         failure.  Newly allocated keys must be freed with regfi_free_record.
+ *         failure.  Newly allocated keys must be freed with 
+ *         @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
@@ -1132,5 +1124,5 @@
  *          value, or NULL on failure.  Failure may be due to a lack of any
  *          values or other errors.  Newly allocated keys must be freed with
- *          regfi_free_record.
+ *          @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
@@ -1145,5 +1137,5 @@
  * @return A newly allocated value structure for the currently referenced value,
  *         or NULL on failure.  Newly allocated values must be freed with 
- *         regfi_free_record.
+ *         @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
@@ -1158,5 +1150,6 @@
  *
  * @return  A newly allocated key structure for the next value or NULL on 
- *          failure.  Newly allocated keys must be freed with regfi_free_record.
+ *          failure.  Newly allocated keys must be freed with 
+ *          @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
@@ -1185,5 +1178,5 @@
  *
  * @return Returns a newly allocated classname structure, or NULL on failure.
- *         Classname structures must be freed with regfi_free_record.
+ *         Classname structures must be freed with @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
@@ -1199,5 +1192,5 @@
  *
  * @return Returns a newly allocated data structure, or NULL on failure.
- *         Data structures must be freed with regfi_free_record.
+ *         Data structures must be freed with @ref regfi_free_record.
  *
  * @ingroup regfiIteratorLayer
Index: /trunk/lib/regfi.c
===================================================================
--- /trunk/lib/regfi.c	(revision 184)
+++ /trunk/lib/regfi.c	(revision 185)
@@ -45,33 +45,59 @@
 
 
+/* Ensures regfi_init runs only once */
+static pthread_once_t regfi_init_once = PTHREAD_ONCE_INIT;
+
+
 
 /******************************************************************************
  ******************************************************************************/
-void regfi_log_start(uint16_t msg_mask)
-{
+void regfi_log_free(void* ptr)
+{
+  REGFI_LOG* log_info = (REGFI_LOG*)ptr;
+  
+  if(log_info->messages != NULL)
+    free(log_info->messages);
+
+  talloc_free(log_info);
+}
+
+
+/******************************************************************************
+ ******************************************************************************/
+void regfi_init()
+{
+  int err;
+  if((err = pthread_key_create(&regfi_log_key, regfi_log_free)) != 0)
+    fprintf(stderr, "ERROR: key_create: %s\n", strerror(err));
+  errno = err;
+}
+
+
+/******************************************************************************
+ ******************************************************************************/
+REGFI_LOG* regfi_log_new()
+{
+  int err;
   REGFI_LOG* log_info = talloc(NULL, REGFI_LOG);
   if(log_info == NULL)
-    return;
-
-  log_info->msg_mask = msg_mask;
+    return NULL;
+
+  log_info->msg_mask = REGFI_DEFAULT_LOG_MASK;
   log_info->messages = NULL;
 
-  /* XXX: Should we bother with a destructor here? */
-  if(pthread_key_create(&REGFI_LOG_KEY, NULL) != 0)
-  {
-    fprintf(stderr, "ERROR: key_create\n");
-    goto fail;
-  }
-
-  if(pthread_setspecific(REGFI_LOG_KEY, log_info) != 0)
-  {
-    fprintf(stderr, "ERROR: setspecific\n");
-    goto fail;
-  }
-
-  return;
+  pthread_once(&regfi_init_once, regfi_init);
+
+  if((err = pthread_setspecific(regfi_log_key, log_info)) != 0)
+  {
+    fprintf(stderr, "ERROR: setspecific: %s\n", strerror(err));
+    goto fail;
+  }
+
+  return log_info;
 
  fail:
   talloc_free(log_info);
+  errno = err;
+  return NULL;
 }
 
@@ -93,6 +119,9 @@
   va_list args;
 
-  log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
-  if(log_info == NULL || (log_info->msg_mask & msg_type) == 0)
+  log_info = (REGFI_LOG*)pthread_getspecific(regfi_log_key);
+  if(log_info == NULL && (log_info = regfi_log_new()) == NULL)
+    return;
+
+  if((log_info->msg_mask & msg_type) == 0)
     return;
 
@@ -138,8 +167,8 @@
 {
   char* ret_val;
-  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
-  if(log_info == NULL)
-    return NULL;
-
+  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(regfi_log_key);
+  if(log_info == NULL && (log_info = regfi_log_new()) == NULL)
+    return NULL;
+  
   ret_val = log_info->messages;
   log_info->messages = NULL;
@@ -151,27 +180,14 @@
 /******************************************************************************
  ******************************************************************************/
-void regfi_log_set_mask(uint16_t msg_mask)
-{
-  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
-  if(log_info == NULL)
-    return;
+bool regfi_log_set_mask(uint16_t msg_mask)
+{
+  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(regfi_log_key);
+  if(log_info == NULL && (log_info = regfi_log_new()) == NULL)
+  {
+      return false;
+  }
 
   log_info->msg_mask = msg_mask;
-}
-
-
-/******************************************************************************
- ******************************************************************************/
-void regfi_log_stop()
-{
-  REGFI_LOG* log_info = (REGFI_LOG*)pthread_getspecific(REGFI_LOG_KEY);
-  if(log_info == NULL)
-    return;
-  
-  if(log_info->messages != NULL)
-    free(log_info->messages);
-
-  pthread_key_delete(REGFI_LOG_KEY);
-  talloc_free(log_info);
+  return true;
 }
 
Index: /trunk/src/common.c
===================================================================
--- /trunk/src/common.c	(revision 184)
+++ /trunk/src/common.c	(revision 185)
@@ -49,5 +49,4 @@
 {
   fprintf(stderr, message);
-  regfi_log_stop();
   exit(code);
 }
Index: /trunk/src/reglookup-recover.c
===================================================================
--- /trunk/src/reglookup-recover.c	(revision 184)
+++ /trunk/src/reglookup-recover.c	(revision 185)
@@ -828,7 +828,7 @@
 
   if(print_verbose)
-    regfi_log_start(REGFI_LOG_ERROR|REGFI_LOG_WARN|REGFI_LOG_INFO);
+    regfi_log_set_mask(REGFI_LOG_ERROR|REGFI_LOG_WARN|REGFI_LOG_INFO);
   else
-    regfi_log_start(REGFI_LOG_ERROR);
+    regfi_log_set_mask(REGFI_LOG_ERROR);
 
   f = regfi_alloc(fd);
@@ -994,5 +994,4 @@
 
   regfi_free(f);
-  regfi_log_stop();
   close(fd);
 
Index: /trunk/src/reglookup.c
===================================================================
--- /trunk/src/reglookup.c	(revision 184)
+++ /trunk/src/reglookup.c	(revision 185)
@@ -624,7 +624,5 @@
 
   if(print_verbose)
-    regfi_log_start(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR);
-  else
-    regfi_log_start(REGFI_LOG_ERROR|REGFI_LOG_WARN);
+    regfi_log_set_mask(REGFI_LOG_INFO|REGFI_LOG_WARN|REGFI_LOG_ERROR);
 
   fd = openHive(registry_file);
@@ -685,5 +683,4 @@
   regfi_iterator_free(iter);
   regfi_free(f);
-  regfi_log_stop();
   close(fd);
 
