gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r37262 - in gnunet/src: include my


From: gnunet
Subject: [GNUnet-SVN] r37262 - in gnunet/src: include my
Date: Fri, 10 Jun 2016 14:32:40 +0200

Author: christophe.genevey
Date: 2016-06-10 14:32:40 +0200 (Fri, 10 Jun 2016)
New Revision: 37262

Modified:
   gnunet/src/include/gnunet_my_lib.h
   gnunet/src/my/my.c
   gnunet/src/my/my_query_helper.c
   gnunet/src/my/my_result_helper.c
   gnunet/src/my/test_my.c
Log:
finish to fix memory leak

Modified: gnunet/src/include/gnunet_my_lib.h
===================================================================
--- gnunet/src/include/gnunet_my_lib.h  2016-06-10 09:19:27 UTC (rev 37261)
+++ gnunet/src/include/gnunet_my_lib.h  2016-06-10 12:32:40 UTC (rev 37262)
@@ -19,6 +19,7 @@
 */
 /**
  * @author Christian Grothoff
+ * @author Christophe Genevey
  *
  * @file
  * Helper library to access a MySQL database
@@ -123,7 +124,6 @@
 #define GNUNET_MY_query_param_end { NULL, NULL, NULL, 0, NULL, 0 }
 
 
-
 /**
  * Generate query parameter for a buffer @a ptr of
  * @a ptr_size bytes.FG
@@ -135,6 +135,7 @@
 GNUNET_MY_query_param_fixed_size (const void *ptr,
                                  size_t ptr_size);
 
+
 /**
  * Run a prepared SELECT statement.
  *
@@ -304,7 +305,7 @@
 struct GNUNET_MY_QueryParam
 GNUNET_MY_query_param_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature 
*x);
 
-/**q
+/**
   * Generate query parameter for an absolute time value.
   * The database must store a 64-bit integer.
   *
@@ -314,6 +315,7 @@
 struct GNUNET_MY_QueryParam
 GNUNET_MY_query_param_absolute_time (const struct GNUNET_TIME_Absolute *x);
 
+
 /**
   * Generate query parameter for an absolute time value.
   * The database must store a 64-bit integer.
@@ -357,11 +359,6 @@
 #define GNUNET_MY_result_spec_auto_from_type(dst) 
GNUNET_MY_result_spec_fixed_size ((dst), sizeof (*(dst)))
 
 
-/**
- * FIXME.
- *
- */
-
  /**
   * Variable-size result expected
   *
@@ -468,6 +465,7 @@
  * #GNUNET_MY_exect_prepared().
  *
  * @param qp query specification to clean up
+ * @param qbind mysql query
  */
 void
 GNUNET_MY_cleanup_query (struct GNUNET_MY_QueryParam *qp,

Modified: gnunet/src/my/my.c
===================================================================
--- gnunet/src/my/my.c  2016-06-10 09:19:27 UTC (rev 37261)
+++ gnunet/src/my/my.c  2016-06-10 12:32:40 UTC (rev 37262)
@@ -107,6 +107,7 @@
  * #GNUNET_MY_exect_prepared().
  *
  * @param qp query specification to clean up
+ * @param qbind array of parameter to clean up
  */
 void
 GNUNET_MY_cleanup_query (struct GNUNET_MY_QueryParam *qp,
@@ -115,9 +116,9 @@
   unsigned int i;
 
   for (i=0; NULL != qp[i].conv ;i++)
-      if(NULL != qp[i].cleaner)
-        qp[i].cleaner (qp[i].conv_cls,
-                        &qbind[i]);
+    if(NULL != qp[i].cleaner)
+      qp[i].cleaner (qp[i].conv_cls,
+                    &qbind[i]);
 }
 
 
@@ -142,7 +143,7 @@
   int ret;
   MYSQL_STMT *stmt;
 
-  stmt = GNUNET_MYSQL_statement_get_stmt (NULL /* FIXME */, sh);
+  stmt = GNUNET_MYSQL_statement_get_stmt (NULL, sh);
   if (NULL == stmt)
   {
     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "mysql",
@@ -183,7 +184,6 @@
         GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                     "Pre-conversion for MySQL result failed at offset %u\n",
                     i);
-        GNUNET_MY_cleanup_result (rs);
         return GNUNET_SYSERR;
       }
       field_off += rp->num_fields;
@@ -209,6 +209,7 @@
                        _("mysql_stmt_fetch failed at %s:%d with error: %s\n"),
                        __FILE__, __LINE__,
                        mysql_stmt_error (stmt));
+      GNUNET_MY_cleanup_result (rs);
       return GNUNET_SYSERR;
     }
     field_off = 0;
@@ -241,7 +242,7 @@
  * Free all memory that was allocated in @a rs during
  * #GNUNET_MY_extract_result().
  *
- * @param rs reult specification to clean up
+ * @param rs result specification to clean up
  */
 void
 GNUNET_MY_cleanup_result (struct GNUNET_MY_ResultSpec *rs)

Modified: gnunet/src/my/my_query_helper.c
===================================================================
--- gnunet/src/my/my_query_helper.c     2016-06-10 09:19:27 UTC (rev 37261)
+++ gnunet/src/my/my_query_helper.c     2016-06-10 12:32:40 UTC (rev 37262)
@@ -21,6 +21,7 @@
  * @file my/my_query_helper.c
  * @brief library to help with access to a MySQL database
  * @author Christian Grothoff
+ * @author Christophe Genevey
  */
 #include "platform.h"
 #include <mysql/mysql.h>
@@ -32,7 +33,7 @@
  * by a #GNUNET_MY_QueryConverter.
  *
  * @param cls closure
- * @param rd result data to clean up
+ * @param qbind array of parameter to clean up
  */
 static void
 my_clean_query (void *cls,
@@ -119,7 +120,6 @@
 
   GNUNET_assert (1 == qp->num_params);
 
-
   u_nbo = GNUNET_new (uint16_t);
   if (NULL == u_nbo)
     return -1;
@@ -143,13 +143,13 @@
 GNUNET_MY_query_param_uint16 (const uint16_t *x)
 {
   struct GNUNET_MY_QueryParam res = {
-      .conv = &my_conv_uint16,
-      .cleaner = &my_clean_query,
-      .conv_cls = NULL,
-      .num_params = 1,
-      .data = x,
-      .data_len = sizeof (*x)
-    };
+    .conv = &my_conv_uint16,
+    .cleaner = &my_clean_query,
+    .conv_cls = NULL,
+    .num_params = 1,
+    .data = x,
+    .data_len = sizeof (*x)
+  };
 
   return res;
 }
@@ -275,7 +275,7 @@
   size_t buf_size;
 
   GNUNET_assert(1 == qp->num_params);
-  // FIXME: this leaks memory right now...
+
   buf_size = GNUNET_CRYPTO_rsa_public_key_encode (rsa, &buf);
 
   qbind->buffer = (void *) buf;

Modified: gnunet/src/my/my_result_helper.c
===================================================================
--- gnunet/src/my/my_result_helper.c    2016-06-10 09:19:27 UTC (rev 37261)
+++ gnunet/src/my/my_result_helper.c    2016-06-10 12:32:40 UTC (rev 37262)
@@ -23,12 +23,15 @@
 #include "gnunet_util_lib.h"
 #include "gnunet_my_lib.h"
 
+
 /**
  * extract data from a Mysql database @a result at row @a row
  *
  * @param cls closure
- * @param qp data about the query
- * @param result mysql result
+ * @param[in,out] rs
+ * @param stmt the mysql statement that is being run
+ * @param column the column that is being processed
+ * @param[out] result mysql result
  * @return
  *   #GNUNET_OK if all results could be extracted
  *   #GNUNET_SYSERR if a result was invalid
@@ -117,11 +120,12 @@
   }
 }
 
+
 /**
  * Variable-size result expected
  *
  * @param[out] dst where to store the result, allocated
- * @param[out] sptr where to store the size of @a dst
+ * @param[out] ptr_size where to store the size of @a dst
  * @return array entru for the result specification to use
  */
 struct GNUNET_MY_ResultSpec
@@ -146,11 +150,10 @@
  * Extract data from a Mysql database @a result at row @a row
  *
  * @param cls closure
- * @param result where to extract data from
- * @param int row to extract data from
- * @param fname name (or prefix) of the fields to extract from
- * @param[in] dst_size desired size, never NULL
- * @param[out] dst where to store the result
+ * @param[in,out] rs
+ * @param stmt the mysql statement that is being run
+ * @param column the column that is being processed
+ * @param[out] results
  * @return
  *  #GNUNET_OK if all results could be extracted
  *  #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
@@ -176,11 +179,10 @@
  * result at row @a row
  *
  * @param cls closure
- * @param result where to extract data from
- * @param int row to extract data from
- * @param fname name (or prefix) of the fields to extract from
- * @param[in] dst_size desired size, never NULL
- * @param[out] dst where to store the result
+ * @param[in,out] rs
+ * @param stmt the mysql statement that is being run
+ * @param column the column that is being processed
+ * @param[out] results
  * @return
  *  #GNUNET_OK if all results could be extracted
  *  #GNUNET_SYSERR if a result was invalid(non-existing field or NULL)
@@ -203,7 +205,7 @@
  *
  * @param name name of the field in the table
  * @param[out] dst where to store the result
- * @param dst_size number of bytes in @a dst
+ * @param ptr_size number of bytes in @a dst
  * @return array entry for the result specification to use
  */
 struct GNUNET_MY_ResultSpec
@@ -228,11 +230,10 @@
   * Extract data from a Mysql database @a result at row @a row
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *   #GNUNET_OK if all results could be extracted
   *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -258,11 +259,10 @@
   * result at row @a row
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *   #GNUNET_OK if all results could be extracted
   *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -297,6 +297,7 @@
     GNUNET_free (buf);
     return GNUNET_SYSERR;
   }
+  
   *pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
                                              size);
   GNUNET_free (buf);
@@ -316,7 +317,7 @@
  * by a #GNUNET_MY_ResultConverter.
  *
  * @param cls closure
- * @param rd result data to clean up
+ * @param rs result data to clean up
  */
 static void
 clean_rsa_public_key (void *cls,
@@ -354,15 +355,15 @@
   return res;
 }
 
+
 /**
   * Extract data from a Mysql database @a result at row @a row.
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in,out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *    #GNUNET_OK if all results could be extracted
   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -387,11 +388,10 @@
   * Extract data from a Mysql database @a result at row @a row.
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in,out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *    #GNUNET_OK if all results could be extracted
   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -481,15 +481,15 @@
   return res;
 }
 
+
 /**
   * Extract data from a Mysql database @a result at row @a row
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *    #GNUNET_OK if all results could be extracted
   *    #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
@@ -513,11 +513,10 @@
   * Check size of extracted fixed size data from a Mysql database @a
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *    #GNUNET_OK if all results could be extracted
   *    #GNUNET_SYSERR if a result was invalid (non existing field or NULL)
@@ -589,11 +588,10 @@
  * Extract data from a Postgres database @a result at row @a row.
  *
  * @param cls closure
- * @param result where to extract data from
- * @param int row to extract data from
- * @param fname name (or prefix) of the fields to extract from
- * @param[in,out] dst_size where to store size of result, may be NULL
- * @param[out] dst where to store the result
+ * @param[in,out] rs
+ * @param stmt the mysql statement that is being run
+ * @param column the column that is being processed
+ * @param[out] results
  * @return
  *   #GNUNET_YES if all results could be extracted
  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -618,11 +616,10 @@
  * Check size of extracted fixed size data from a Mysql datbase.
  *
  * @param cls closure
- * @param result where to extract data from
- * @param int row to extract data from
- * @param fname name (or prefix) of the fields to extract from
- * @param[in,out] dst_size where to store size of result, may be NULL
- * @param[out] dst where to store the result
+ * @param[in,out] rs
+ * @param stmt the mysql statement that is being run
+ * @param column the column that is being processed
+ * @param[out] results
  * @return
  *   #GNUNET_YES if all results could be extracted
  *   #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -660,15 +657,16 @@
   return res;
 }
 
+
 /**
   * Extrac data from a  MYSQL database @a result at row @a row
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param cls closure
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *      #GNUNET_OK if all results could be extracted
   *      #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -693,11 +691,11 @@
   * Extrac data from a  MYSQL database @a result at row @a row
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be NULL
-  * @param[out] dst where to store the result
+  * @param cls closure
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *      #GNUNET_OK if all results could be extracted
   *      #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -740,11 +738,10 @@
   * Extract data from a MYSQL database @a result at row @a row
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be null
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *    #GNUNET_OK if all results could be extracted
   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -765,16 +762,14 @@
 }
 
 
-
 /**
   * Check size of extracted fixe size data from a Mysql database
   *
   * @param cls closure
-  * @param result where to extract data from
-  * @param int row to extract data from
-  * @param fname name (or prefix) of the fields to extract from
-  * @param[in, out] dst_size where to store size of result, may be null
-  * @param[out] dst where to store the result
+  * @param[in,out] rs
+  * @param stmt the mysql statement that is being run
+  * @param column the column that is being processed
+  * @param[out] results
   * @return
   *    #GNUNET_OK if all results could be extracted
   *    #GNUNET_SYSERR if a result was invalid (non-existing field or NULL)
@@ -812,4 +807,5 @@
   return res;
 }
 
+
 /* end of pq_result_helper.c */

Modified: gnunet/src/my/test_my.c
===================================================================
--- gnunet/src/my/test_my.c     2016-06-10 09:19:27 UTC (rev 37261)
+++ gnunet/src/my/test_my.c     2016-06-10 12:32:40 UTC (rev 37262)
@@ -28,6 +28,7 @@
 #include "gnunet_mysql_lib.h"
 #include "gnunet_util_lib.h"
 
+
 /**
   * Run actual test queries.
   *
@@ -77,7 +78,7 @@
 
   memset (&hc, 0, sizeof(hc));
   memset (&hc2, 0, sizeof(hc2));
-  
+
   statements_handle_insert = GNUNET_MYSQL_statement_prepare (context,
                                         "INSERT INTO test_my2 ("
                                         " pub"
@@ -139,7 +140,7 @@
   }
 
   struct GNUNET_MY_QueryParam params_select[] = {
-        GNUNET_MY_query_param_end
+    GNUNET_MY_query_param_end
   };
 
   if (GNUNET_OK != GNUNET_MY_exec_prepared (context,
@@ -146,21 +147,21 @@
                                             statements_handle_select,
                                             params_select))
   {
-          fprintf (stderr, "Failed to execute prepared statement SELECT\n");
-          return 1;
+    fprintf (stderr, "Failed to execute prepared statement SELECT\n");
+    return 1;
   }
 
   struct GNUNET_MY_ResultSpec results_select[] = {
-        GNUNET_MY_result_spec_rsa_public_key (&pub2),
-        GNUNET_MY_result_spec_rsa_signature (&sig2),
-        GNUNET_MY_result_spec_absolute_time (&abs_time2),
-        GNUNET_MY_result_spec_absolute_time (&forever2),
-        GNUNET_MY_result_spec_auto_from_type (&hc2),
-        GNUNET_MY_result_spec_variable_size (&msg2, &msg2_len),
-        GNUNET_MY_result_spec_uint16 (&u162),
-        GNUNET_MY_result_spec_uint32 (&u322),
-        GNUNET_MY_result_spec_uint64 (&u642),
-        GNUNET_MY_result_spec_end
+    GNUNET_MY_result_spec_rsa_public_key (&pub2),
+    GNUNET_MY_result_spec_rsa_signature (&sig2),
+    GNUNET_MY_result_spec_absolute_time (&abs_time2),
+    GNUNET_MY_result_spec_absolute_time (&forever2),
+    GNUNET_MY_result_spec_auto_from_type (&hc2),
+    GNUNET_MY_result_spec_variable_size (&msg2, &msg2_len),
+    GNUNET_MY_result_spec_uint16 (&u162),
+    GNUNET_MY_result_spec_uint32 (&u322),
+    GNUNET_MY_result_spec_uint64 (&u642),
+    GNUNET_MY_result_spec_end
   };
 
   ret = GNUNET_MY_extract_result (statements_handle_select,
@@ -177,17 +178,18 @@
   GNUNET_assert (NULL != sig2);
   GNUNET_assert (NULL != pub2);
   GNUNET_break (0 ==
-            GNUNET_CRYPTO_rsa_signature_cmp (sig,
-                                 sig2));
+                GNUNET_CRYPTO_rsa_signature_cmp (sig,
+                                                 sig2));
   GNUNET_break (0 ==
-            GNUNET_CRYPTO_rsa_public_key_cmp (pub,
-                                  pub2));
+                GNUNET_CRYPTO_rsa_public_key_cmp (pub,
+                                                  pub2));
 
   GNUNET_break (strlen (msg) == msg2_len);
   GNUNET_break (0 ==
-            strncmp (msg,
-                  msg2,
-                  msg2_len));
+                strncmp (msg,
+                         msg2,
+                         msg2_len));
+
   GNUNET_break (16 == u162);
   GNUNET_break (32 == u322);
   GNUNET_break (64 == u642);
@@ -199,7 +201,7 @@
   GNUNET_CRYPTO_rsa_public_key_free (pub);     
   
   if (GNUNET_OK != ret)
-      return 1;
+    return 1;
 
   return 0;
 }
@@ -212,46 +214,47 @@
   struct GNUNET_MYSQL_Context *context = NULL;
   int ret;
 
-  GNUNET_log_setup (  "test-my",
-                         "WARNING",
-                         NULL);
+  GNUNET_log_setup ("test-my",
+                    "WARNING",
+                    NULL);
 
   config = GNUNET_CONFIGURATION_create ();
   if (GNUNET_OK != GNUNET_CONFIGURATION_parse (config, "test_my.conf"))
   {
-      fprintf (stderr, "Failed to parse configuaration\n");
-      return 1;
+    fprintf (stderr, "Failed to parse configuaration\n");
+    return 1;
   }
 
   context = GNUNET_MYSQL_context_create (config,
-                                             "datastore-mysql");
+                                        "datastore-mysql");
   if (NULL == context)
   {
-      fprintf(stderr, "Failed to connect to database\n");
-      return 77;
+    fprintf(stderr, "Failed to connect to database\n");
+    return 77;
   }
 
   (void) GNUNET_MYSQL_statement_run (context,
-                                        "DROP TABLE test_my2;");
+                                    "DROP TABLE test_my2;");
+
   if (GNUNET_OK != GNUNET_MYSQL_statement_run (context,
-                                                  "CREATE TABLE IF NOT EXISTS 
test_my2("
-                                                  " pub BLOB NOT NULL"
-                                                  ",sig BLOB NOT NULL"
-                                                  ",abs_time BIGINT NOT NULL"
-                                                  ",forever BIGINT NOT NULL"
-                                                  ",hash BLOB NOT NULL 
CHECK(LENGTH(hash)=64)"
-                                                  ",vsize BLOB NOT NULL"
-                                                  ",u16 SMALLINT NOT NULL"
-                                                  ",u32 INT NOT NULL"
-                                                  ",u64 BIGINT NOT NULL"
-                                                  ")"))
+                                              "CREATE TABLE IF NOT EXISTS 
test_my2("
+                                              " pub BLOB NOT NULL"
+                                              ",sig BLOB NOT NULL"
+                                              ",abs_time BIGINT NOT NULL"
+                                              ",forever BIGINT NOT NULL"
+                                              ",hash BLOB NOT NULL 
CHECK(LENGTH(hash)=64)"
+                                              ",vsize BLOB NOT NULL"
+                                              ",u16 SMALLINT NOT NULL"
+                                              ",u32 INT NOT NULL"
+                                              ",u64 BIGINT NOT NULL"
+                                              ")"))
   {
-      fprintf (stderr,
-                "Failed to create table \n");
-      GNUNET_MYSQL_statements_invalidate (context);
-      GNUNET_MYSQL_context_destroy (context);
+    fprintf (stderr,
+            "Failed to create table \n");
+    GNUNET_MYSQL_statements_invalidate (context);
+    GNUNET_MYSQL_context_destroy (context);
 
-      return 1;
+    return 1;
   }
 
   ret = run_queries (context);




reply via email to

[Prev in Thread] Current Thread [Next in Thread]