[glom] Re-enable the import tests and partially deal with their race condition.



commit 4ca56232d86d8a9f7ed0bbeadbbf5d13235392c3
Author: Murray Cumming <murrayc murrayc com>
Date:   Sun Nov 14 20:56:54 2010 +0100

    Re-enable the import tests and partially deal with their race condition.
    
    * Makefile_tests.am: Re-enable the import tests.
    * glom/import_csv/csv_parser.[h|cc]: Add ensure_idle_handler_connection(),
    moving the idle signal handler connection there. Also call it from the
    beginning and end of on_file_read(), in case it has been disconnected
    too early.
    Use a priority less than PRIORITY_DEFAULT_IDLE, so that IO is likely to
    happen more often than the idle callback.

 ChangeLog                     |   12 ++++++++++++
 Makefile_tests.am             |   14 ++++++--------
 glom/import_csv/csv_parser.cc |   22 +++++++++++++++-------
 glom/import_csv/csv_parser.h  |   14 ++++++++------
 4 files changed, 41 insertions(+), 21 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index e77cdd6..befc189 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2010-11-14  Murray Cumming  <murrayc murrayc com>
+
+	Re-enable the import tests and partially deal with their race condition.
+
+	* Makefile_tests.am: Re-enable the import tests.
+	* glom/import_csv/csv_parser.[h|cc]: Add ensure_idle_handler_connection(), 
+	moving the idle signal handler connection there. Also call it from the 
+	beginning and end of on_file_read(), in case it has been disconnected 
+	too early.
+	Use a priority less than PRIORITY_DEFAULT_IDLE, so that IO is likely to 
+	happen more often than the idle callback.
+
 2010-11-12  Murray Cumming  <murrayc murrayc com>
 
 	Import tests: Slight code-style change.
diff --git a/Makefile_tests.am b/Makefile_tests.am
index f5ea6c8..8571f36 100644
--- a/Makefile_tests.am
+++ b/Makefile_tests.am
@@ -33,12 +33,12 @@ check_PROGRAMS =						\
 	tests/test_python_execute_func_date \
 	tests/test_python_execute_func_change_result_type \
 	tests/test_python_execute_script \
-	tests/import/test_parsing \
-	tests/import/test_signals \
 	tests/test_glade_derived_instantiation \
 	tests/glade_toplevels_instantiation \
 	tests/test_selfhosting_new_empty \
-	tests/test_selfhosting_new_from_example
+	tests/test_selfhosting_new_from_example \
+	tests/import/test_parsing \
+	tests/import/test_signals
 
 TESTS =	tests/test_document_load	\
   tests/test_document_autosave	\
@@ -56,11 +56,9 @@ TESTS =	tests/test_document_load	\
 	tests/test_python_execute_func_change_result_type \
 	tests/test_python_execute_script \
 	tests/test_selfhosting_new_empty \
-	tests/test_selfhosting_new_from_example
-
-# These hang most of the time, but not always:
-#	tests/import/test_parsing \
-#	tests/import/test_signals
+	tests/test_selfhosting_new_from_example \
+	tests/import/test_parsing \
+	tests/import/test_signals
 
 # We also set this in Makefile.am, with +=,
 # but this is the first use, where we must use =
diff --git a/glom/import_csv/csv_parser.cc b/glom/import_csv/csv_parser.cc
index eebce9d..4f59304 100644
--- a/glom/import_csv/csv_parser.cc
+++ b/glom/import_csv/csv_parser.cc
@@ -190,7 +190,7 @@ void CsvParser::set_encoding(const Glib::ustring& encoding_charset)
     return;
 
   m_encoding = encoding_charset;
-  
+
   //Stop parsing if the encoding changes.
   //The caller should restart the parsing when wanted.
   clear();
@@ -330,7 +330,7 @@ bool CsvParser::on_idle_parse()
   const char* prev = prev_line_end;
 
   // Identify the record rows in the .csv file.
-  // We can't just search for newlines because they may be inside quotes too. 
+  // We can't just search for newlines because they may be inside quotes too.
   // TODO: Use a regex instead, to more easily handle quotes?
   bool in_quotes = false;
   while(true)
@@ -363,7 +363,7 @@ bool CsvParser::on_idle_parse()
     {
       // There is a null byte in the conversion. Because normal text files don't
       // contain null bytes this only occurs when converting, for example, a UTF-16
-      // file from ISO-8859-1 to UTF-8 (note that the UTF-16 file is valid ISO-8859-1 - 
+      // file from ISO-8859-1 to UTF-8 (note that the UTF-16 file is valid ISO-8859-1 -
       // it just contains lots of nullbytes). We therefore produce an error here.
       //std::cerr << G_STRFUNC << ": on_idle_parse(): Encoding error" << std::endl;
       set_state(STATE_ENCODING_ERROR);
@@ -419,7 +419,7 @@ bool CsvParser::on_idle_parse()
       prev = pos + 1;
 
       // Skip DOS-style linebreak (\r\n)
-      if(ch == '\r' 
+      if(ch == '\r'
          && prev != outbuf && *prev == '\n')
       {
          ++prev;
@@ -490,14 +490,19 @@ void CsvParser::do_line_scanned(const Glib::ustring& line, guint line_number)
   signal_line_scanned().emit(row, line_number);
 }
 
-void CsvParser::on_file_read(const Glib::RefPtr<Gio::AsyncResult>& result, const Glib::RefPtr<Gio::File>& source)
+void CsvParser::ensure_idle_handler_connection()
 {
-  // TODO: Introduce CsvParser::is_idle_handler_connected() instead?
   if(!m_idle_connection.connected())
   {
     m_idle_connection = Glib::signal_idle().connect(
-      sigc::mem_fun(*this, &CsvParser::on_idle_parse));
+      sigc::mem_fun(*this, &CsvParser::on_idle_parse),
+      Glib::PRIORITY_DEFAULT_IDLE - 20);
   }
+}
+
+void CsvParser::on_file_read(const Glib::RefPtr<Gio::AsyncResult>& result, const Glib::RefPtr<Gio::File>& source)
+{
+  ensure_idle_handler_connection();
 
   try
   {
@@ -528,6 +533,9 @@ void CsvParser::copy_buffer_and_continue_reading(gssize size)
     m_buffer.reset(0);
     m_stream.reset();
   }
+
+  //In case it has been disconnected too early due to timing problems:
+  ensure_idle_handler_connection();
 }
 
 void CsvParser::on_buffer_read(const Glib::RefPtr<Gio::AsyncResult>& result)
diff --git a/glom/import_csv/csv_parser.h b/glom/import_csv/csv_parser.h
index 6d206d6..ef904e9 100644
--- a/glom/import_csv/csv_parser.h
+++ b/glom/import_csv/csv_parser.h
@@ -48,7 +48,7 @@ namespace Glom
  *
  * set_file_and_start_parsing() to start parsing.
  * The data can then be read via get_date(), with get_rows_count() and get_cols_count().
- * 
+ *
  * The signals offer feedback while the parsing is happening.
  */
 class CsvParser
@@ -64,7 +64,7 @@ public:
   ~CsvParser();
 
   enum State {
-    STATE_NONE, 
+    STATE_NONE,
     STATE_PARSING,  /**< Parsing is in progress. */
     STATE_ENCODING_ERROR, /**< An error happened while parsing. */
     STATE_PARSED /**< Finished parsing. */
@@ -99,8 +99,8 @@ public:
 
   typedef sigc::signal<void, const Glib::ustring&> type_signal_have_display_name;
 
-  /** This signal will be emitted when the parser has discovered the 
-   * display name for the file. This does not require any parsing of the contents, 
+  /** This signal will be emitted when the parser has discovered the
+   * display name for the file. This does not require any parsing of the contents,
    * but it is asynchronous, so CsvParser signals this as a convenience.
    */
   type_signal_have_display_name signal_have_display_name() const;
@@ -139,8 +139,8 @@ public:
   void clear();
 
   /** Change the encoding used when reading the file.
-   * This stop parsing. Call set_file_and_start_parsing() to restart the parser  
-   * with the specified encoding. 
+   * This stop parsing. Call set_file_and_start_parsing() to restart the parser
+   * with the specified encoding.
    * See the FileEncoding namespace.
    */
   void set_encoding(const Glib::ustring& encoding_charset);
@@ -164,6 +164,8 @@ private:
   //TODO: Document this:
   static Glib::ustring::const_iterator advance_field(const Glib::ustring::const_iterator& iter, const Glib::ustring::const_iterator& end, Glib::ustring& field);
 
+  void ensure_idle_handler_connection();
+
   void on_file_read(const Glib::RefPtr<Gio::AsyncResult>& result, const Glib::RefPtr<Gio::File>& source);
   void copy_buffer_and_continue_reading(gssize size);
   void on_buffer_read(const Glib::RefPtr<Gio::AsyncResult>& result);



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